Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
198 changes: 198 additions & 0 deletions comprehensive-demo-react16/e2e/checkApp1.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import { test, expect } from '@playwright/test';
import type { Page } from '@playwright/test';

const base = 'http://localhost:3001';

const demoPages = [
{ name: 'Main', hash: '#/' },
{ name: 'UI Library', hash: '#/ui-library' },
{ name: 'Dialog', hash: '#/dialog' },
{ name: 'Svelte Page', hash: '#/svelte' },
{ name: 'Routing', hash: '#/routing/foo' },
];

const appLinks = [
{ name: 'App #1', href: 'http://localhost:3001' },
{ name: 'App #2', href: 'http://localhost:3002' },
{ name: 'App #3', href: 'http://localhost:3003' },
{ name: 'App #4', href: 'http://localhost:3004' },
{ name: 'App #5', href: 'http://localhost:3005' },
];

const mainPageParagraphs = [
'Welcome to the Module Federation Demo!',
'Click any of the items on the left to get started.',
'Feel free to leave me feedback',
];

const uiLibraryParagraphs = [
'Simple example showing host app and external component using separate CSS solutions.',
'This Button component can be found in App #3.',
'This button is also used in the routing demo.',
];

const routingParagraphs = [
'The following tab components are being imported remotely from "bravo-app".',
"Notice that your browser's route is /routing/<foo|bar> depending on which tab is active.",
'If you open http://localhost:3002 you will see the same tab components at the root level',
'The "Bar" tab also lazily renders the styled-component Button from the UI Library demo only when rendered.',
];

const escapeRegExp = (value: string) => value.replace(/[-/\^$*+?.()|[\]{}]/g, '\$&');

const expectAppBar = async (page: Page, title: string) => {
const appBar = page.locator('header').first();
await expect(appBar).toBeVisible();
await expect(appBar).toHaveCSS('background-color', 'rgb(63, 81, 181)');
await expect(page.getByRole('heading', { name: title })).toBeVisible();
};

test.describe('Comprehensive Demo App1', () => {
test('main page displays sidebar links and elements', async ({ page }) => {
await page.goto(base);

await expect(page.getByRole('heading', { name: 'SideNav' })).toBeVisible();
await expect(page.getByText('Demo Pages')).toBeVisible();
await expect(page.getByText('Apps')).toBeVisible();

for (const { name, hash } of demoPages) {
const link = page.locator('a', { hasText: name }).first();
await expect(link).toBeVisible();
await expect(link).toHaveAttribute('href', hash);
}

for (const { name, href } of appLinks) {
const link = page.locator(`a[href="${href}"]`).first();
await expect(link).toBeVisible();
await expect(link).toHaveAttribute('href', href);
await expect(link).toContainText(name);
await expect(link).toContainText(href);
}

await expectAppBar(page, 'Module Federation Demo');

const alert = page.locator('.alert');
await expect(alert).toBeVisible();
await expect(alert).toHaveText(/Alert from LitElement/);
await expect(page.locator('.closebtn')).toBeVisible();

for (const paragraph of mainPageParagraphs) {
await expect(page.locator('p', { hasText: paragraph })).toBeVisible();
}

await expect(
page.getByRole('link', { name: 'https://github.com/module-federation/mfe-webpack-demo' }),
).toHaveAttribute('href', 'https://github.com/module-federation/mfe-webpack-demo');

const actionButton = page.locator('action-button button');
await expect(actionButton).toHaveText('Lit Element Action');
await expect(actionButton).toHaveCSS('background-color', 'rgb(219, 112, 147)');
});

test('main tab functionality', async ({ page }) => {
await page.goto(base);

page.once('dialog', async dialog => {
expect(dialog.message()).toBe('You have pressed a button.');
await dialog.accept();
});

await page.locator('action-button button').click();
await page.locator('.closebtn').click();
await expect(page.locator('.alert')).toBeHidden();

for (const { name, hash } of demoPages) {
await page.locator('a', { hasText: name }).first().click();
await expect(page).toHaveURL(`${base}/${hash}`);
}

await page.locator('a', { hasText: 'Main' }).first().click();
await expect(page).toHaveURL(`${base}/#/`);

for (const { href } of appLinks) {
await Promise.all([
page.waitForNavigation({ waitUntil: 'load' }),
page.locator(`a[href="${href}"]`).first().click(),
]);
await expect(page).toHaveURL(new RegExp(`^${escapeRegExp(href)}`));
await page.goBack();
await expect(page).toHaveURL(new RegExp(`^${escapeRegExp(base)}`));
await expect(page.getByRole('heading', { name: 'Module Federation Demo' })).toBeVisible();
}
});

test('UI library page renders remote button', async ({ page }) => {
await page.goto(`${base}/#/ui-library`);

await expectAppBar(page, 'UI Library Demo');

for (const paragraph of uiLibraryParagraphs) {
await expect(page.locator('p', { hasText: paragraph })).toBeVisible();
}

await expect(page.locator('a[href="http://localhost:3003/"]').first()).toHaveAttribute(
'href',
'http://localhost:3003/',
);
await expect(page.locator('a[href="http://localhost:3001/#/routing/foo"]').first()).toHaveAttribute(
'href',
'http://localhost:3001/#/routing/foo',
);

const styledButton = page.getByRole('button', { name: '💅 Button' });
await expect(styledButton).toBeVisible();
await expect(styledButton).toHaveCSS('background-color', 'rgb(219, 112, 147)');
});

test('dialog page loads and dialog opens', async ({ page }) => {
await page.goto(`${base}/#/dialog`);

await expectAppBar(page, 'Dialog Demo');
await expect(
page.locator('p', {
hasText:
'Clicking the button below will render a Dialog using React Portal. This dialog component is being lazy loaded from the app #2.',
}),
).toBeVisible();

await page.getByRole('button', { name: 'Open Dialog' }).click();
const dialog = page.locator('[role="dialog"]');
await expect(dialog.getByRole('heading', { name: 'Dialog Example' })).toBeVisible();
await expect(
dialog.getByText('This is a dialog from the Material UI app rendered in a React Portal.'),
).toBeVisible();
await dialog.getByRole('button', { name: 'Nice' }).click();
await expect(dialog).not.toBeVisible();
});

test('svelte page updates greeting', async ({ page }) => {
await page.goto(`${base}/#/svelte`);

await expectAppBar(page, 'Svelte Demo');

const input = page.locator('input');
await expect(input).toBeVisible();
await input.fill('May The Force Be With You');
await expect(page.locator('h1')).toHaveText('Hello From Svelte May The Force Be With You!');
});

test('routing page renders tabs', async ({ page }) => {
await page.goto(`${base}/#/routing/foo`);

await expectAppBar(page, 'Routing Demo');

for (const paragraph of routingParagraphs) {
await expect(page.locator('p', { hasText: paragraph })).toBeVisible();
}

await expect(page.getByRole('tab', { name: 'Foo' })).toBeVisible();
await expect(page.getByText('Foo Content')).toBeVisible();

await page.getByRole('tab', { name: 'Bar' }).click();
await expect(page.getByText('Bar Content')).toBeVisible();

const barButton = page.getByRole('button', { name: 'Bar Button' });
await expect(barButton).toBeVisible();
await expect(barButton).toHaveCSS('background-color', 'rgb(219, 112, 147)');
});
});
40 changes: 40 additions & 0 deletions comprehensive-demo-react16/e2e/checkApp2.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { test, expect } from '@playwright/test';

const base = 'http://localhost:3002';

test.describe('Comprehensive Demo App2', () => {
test('renders blocks, dialog and tabs', async ({ page }) => {
await page.goto(base);
await expect(page.locator('.jss1')).toBeVisible();
const appBar = page.locator('header').first();
await expect(appBar).toHaveCSS('background-color', 'rgb(63, 81, 181)');
await expect(page.locator('.jss2')).toHaveCSS('background-color', 'rgb(250, 250, 250)');
await expect(page.locator('.jss3')).toHaveCSS('background-color', 'rgb(255, 255, 255)');

await expect(page.getByRole('heading', { name: 'Material UI App' })).toBeVisible();
await expect(page.getByRole('heading', { name: 'Dialog Component' })).toBeVisible();
const openDialogButton = page.getByRole('button', { name: 'Open Dialog' });
await expect(openDialogButton).toBeVisible();
await openDialogButton.click();
const dialog = page.locator('[role="dialog"]');
await expect(dialog.getByRole('heading', { name: 'Dialog Example' })).toBeVisible();
await expect(
dialog.getByText('This is a dialog from the Material UI app rendered in a React Portal.'),
).toBeVisible();
await dialog.getByRole('button', { name: 'Nice' }).click();
await expect(dialog).not.toBeVisible();

await expect(page.getByRole('heading', { name: 'Tabs Component' })).toBeVisible();
const fooTab = page.getByRole('tab', { name: 'Foo' });
const barTab = page.getByRole('tab', { name: 'Bar' });
await expect(fooTab).toBeVisible();
await expect(barTab).toBeVisible();
await expect(page.getByText('Foo Content')).toBeVisible();
await barTab.click();
await expect(page.getByText('Bar Content')).toBeVisible();
await expect(page.getByRole('button', { name: 'Bar Button' })).toHaveCSS(
'background-color',
'rgb(219, 112, 147)',
);
});
});
17 changes: 17 additions & 0 deletions comprehensive-demo-react16/e2e/checkApp3.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { test, expect } from '@playwright/test';

const base = 'http://localhost:3003';

test.describe('Comprehensive Demo App3', () => {
test('shows styled button', async ({ page }) => {
await page.goto(base);
await expect(page.locator('.jss1')).toBeVisible();
const appBar = page.locator('header').first();
await expect(appBar).toHaveCSS('background-color', 'rgb(63, 81, 181)');
await expect(page.locator('.jss2')).toHaveCSS('background-color', 'rgb(250, 250, 250)');
await expect(page.getByRole('heading', { name: 'Styled Components App' })).toBeVisible();
const button = page.getByRole('button', { name: '💅 Test Button' });
await expect(button).toBeVisible();
await expect(button).toHaveCSS('background-color', 'rgb(219, 112, 147)');
});
});
8 changes: 8 additions & 0 deletions comprehensive-demo-react16/e2e/checkApp4.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { test, expect } from '@playwright/test';

test.describe('Comprehensive Demo App4', () => {
test('shows svelte greeting', async ({ page }) => {
await page.goto('http://localhost:3004');
await expect(page.locator('h1')).toHaveText('Hello From Svelte world!');
});
});
24 changes: 24 additions & 0 deletions comprehensive-demo-react16/e2e/checkApp5.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { test, expect } from '@playwright/test';

const base = 'http://localhost:3005';

test.describe('Comprehensive Demo App5', () => {
test('shows button and alert', async ({ page }) => {
await page.goto(base);
const button = page.locator('action-button').locator('button');
await expect(button).toHaveText('bar');
await expect(page.locator('.alert')).toHaveText(/Hello/);
await expect(page.locator('.closebtn')).toBeVisible();
});

test('button triggers alert and close hides it', async ({ page }) => {
await page.goto(base);
page.once('dialog', async dialog => {
expect(dialog.message()).toBe('You have pressed a button.');
await dialog.accept();
});
await page.locator('action-button').locator('button').click();
await page.locator('.closebtn').click();
await expect(page.locator('.alert')).toBeHidden();
});
});
18 changes: 18 additions & 0 deletions comprehensive-demo-react16/e2e/checkApplications.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { test, expect } from '@playwright/test';

const apps = [
{ port: 3001, name: 'App 1', selector: 'h6', text: 'Module Federation Demo' },
{ port: 3002, name: 'App 2', selector: 'h6', text: 'Material UI App' },
{ port: 3003, name: 'App 3', selector: 'h6', text: 'Styled Components App' },
{ port: 3004, name: 'App 4', selector: 'h1', text: 'Hello From Svelte world!' },
{ port: 3005, name: 'App 5', selector: 'action-button button', text: 'bar' },
];

apps.forEach(({ port, name, selector, text }) => {
test.describe(name, () => {
test(`build and run ${name}`, async ({ page }) => {
await page.goto(`http://localhost:${port}`);
await expect(page.locator(selector, { hasText: text })).toBeVisible();
});
});
});
Loading
Loading