Skip to content

Commit 04241c0

Browse files
test: expand comprehensive demo playwright coverage
1 parent f8d550d commit 04241c0

File tree

3 files changed

+160
-39
lines changed

3 files changed

+160
-39
lines changed
Lines changed: 142 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,160 @@
11
import { test, expect } from '@playwright/test';
2+
import type { Page } from '@playwright/test';
23

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

6+
const demoPages = [
7+
{ name: 'Main', hash: '#/' },
8+
{ name: 'UI Library', hash: '#/ui-library' },
9+
{ name: 'Dialog', hash: '#/dialog' },
10+
{ name: 'Svelte Page', hash: '#/svelte' },
11+
{ name: 'Routing', hash: '#/routing/foo' },
12+
];
13+
14+
const appLinks = [
15+
{ name: 'App #1', href: 'http://localhost:3001' },
16+
{ name: 'App #2', href: 'http://localhost:3002' },
17+
{ name: 'App #3', href: 'http://localhost:3003' },
18+
{ name: 'App #4', href: 'http://localhost:3004' },
19+
{ name: 'App #5', href: 'http://localhost:3005' },
20+
];
21+
22+
const mainPageParagraphs = [
23+
'Welcome to the Module Federation Demo!',
24+
'Click any of the items on the left to get started.',
25+
'Feel free to leave me feedback',
26+
];
27+
28+
const uiLibraryParagraphs = [
29+
'Simple example showing host app and external component using separate CSS solutions.',
30+
'This Button component can be found in App #3.',
31+
'This button is also used in the routing demo.',
32+
];
33+
34+
const routingParagraphs = [
35+
'The following tab components are being imported remotely from "bravo-app".',
36+
"Notice that your browser's route is /routing/<foo|bar> depending on which tab is active.",
37+
'If you open http://localhost:3002 you will see the same tab components at the root level',
38+
'The "Bar" tab also lazily renders the styled-component Button from the UI Library demo only when rendered.',
39+
];
40+
41+
const escapeRegExp = (value: string) => value.replace(/[-/\^$*+?.()|[\]{}]/g, '\$&');
42+
43+
const expectAppBar = async (page: Page, title: string) => {
44+
const appBar = page.locator('header').first();
45+
await expect(appBar).toBeVisible();
46+
await expect(appBar).toHaveCSS('background-color', 'rgb(63, 81, 181)');
47+
await expect(page.getByRole('heading', { name: title })).toBeVisible();
48+
};
49+
550
test.describe('Comprehensive Demo App1', () => {
651
test('main page displays sidebar links and elements', async ({ page }) => {
752
await page.goto(base);
53+
854
await expect(page.getByRole('heading', { name: 'SideNav' })).toBeVisible();
55+
await expect(page.getByText('Demo Pages')).toBeVisible();
56+
await expect(page.getByText('Apps')).toBeVisible();
957

10-
const demoLinks = ['Main', 'UI Library', 'Dialog', 'Svelte Page', 'Routing'];
11-
for (const name of demoLinks) {
12-
await expect(page.getByRole('button', { name })).toBeVisible();
58+
for (const { name, hash } of demoPages) {
59+
const link = page.locator('a', { hasText: name }).first();
60+
await expect(link).toBeVisible();
61+
await expect(link).toHaveAttribute('href', hash);
1362
}
1463

15-
const appLinks = [
16-
{ name: 'App #1', href: 'http://localhost:3001' },
17-
{ name: 'App #2', href: 'http://localhost:3002' },
18-
{ name: 'App #3', href: 'http://localhost:3003' },
19-
{ name: 'App #4', href: 'http://localhost:3004' },
20-
{ name: 'App #5', href: 'http://localhost:3005' },
21-
];
2264
for (const { name, href } of appLinks) {
23-
await expect(page.locator('a', { hasText: name })).toHaveAttribute('href', href);
65+
const link = page.locator(`a[href="${href}"]`).first();
66+
await expect(link).toBeVisible();
67+
await expect(link).toHaveAttribute('href', href);
68+
await expect(link).toContainText(name);
69+
await expect(link).toContainText(href);
2470
}
2571

26-
await expect(page.getByRole('heading', { name: 'Module Federation Demo' })).toBeVisible();
27-
await expect(page.getByText('Alert from LitElement')).toBeVisible();
28-
const actionButton = page.getByRole('button', { name: 'Lit Element Action' });
29-
await expect(actionButton).toBeVisible();
72+
await expectAppBar(page, 'Module Federation Demo');
73+
74+
const alert = page.locator('.alert');
75+
await expect(alert).toBeVisible();
76+
await expect(alert).toHaveText(/Alert from LitElement/);
77+
await expect(page.locator('.closebtn')).toBeVisible();
78+
79+
for (const paragraph of mainPageParagraphs) {
80+
await expect(page.locator('p', { hasText: paragraph })).toBeVisible();
81+
}
82+
83+
await expect(
84+
page.getByRole('link', { name: 'https://github.com/module-federation/mfe-webpack-demo' }),
85+
).toHaveAttribute('href', 'https://github.com/module-federation/mfe-webpack-demo');
86+
87+
const actionButton = page.locator('action-button button');
88+
await expect(actionButton).toHaveText('Lit Element Action');
89+
await expect(actionButton).toHaveCSS('background-color', 'rgb(219, 112, 147)');
3090
});
3191

3292
test('main tab functionality', async ({ page }) => {
3393
await page.goto(base);
94+
3495
page.once('dialog', async dialog => {
3596
expect(dialog.message()).toBe('You have pressed a button.');
3697
await dialog.accept();
3798
});
38-
await page.getByRole('button', { name: 'Lit Element Action' }).click();
99+
100+
await page.locator('action-button button').click();
39101
await page.locator('.closebtn').click();
40102
await expect(page.locator('.alert')).toBeHidden();
103+
104+
for (const { name, hash } of demoPages) {
105+
await page.locator('a', { hasText: name }).first().click();
106+
await expect(page).toHaveURL(`${base}/${hash}`);
107+
}
108+
109+
await page.locator('a', { hasText: 'Main' }).first().click();
110+
await expect(page).toHaveURL(`${base}/#/`);
111+
112+
for (const { href } of appLinks) {
113+
await Promise.all([
114+
page.waitForNavigation({ waitUntil: 'load' }),
115+
page.locator(`a[href="${href}"]`).first().click(),
116+
]);
117+
await expect(page).toHaveURL(new RegExp(`^${escapeRegExp(href)}`));
118+
await page.goBack();
119+
await expect(page).toHaveURL(new RegExp(`^${escapeRegExp(base)}`));
120+
await expect(page.getByRole('heading', { name: 'Module Federation Demo' })).toBeVisible();
121+
}
41122
});
42123

43124
test('UI library page renders remote button', async ({ page }) => {
44125
await page.goto(`${base}/#/ui-library`);
45-
await expect(page.getByRole('heading', { name: 'UI Library Demo' })).toBeVisible();
46-
await expect(
47-
page.getByText('Simple example showing host app and external component using separate CSS solutions.'),
48-
).toBeVisible();
49-
await expect(page.getByRole('button', { name: /Button/ })).toBeVisible();
126+
127+
await expectAppBar(page, 'UI Library Demo');
128+
129+
for (const paragraph of uiLibraryParagraphs) {
130+
await expect(page.locator('p', { hasText: paragraph })).toBeVisible();
131+
}
132+
133+
await expect(page.locator('a[href="http://localhost:3003/"]').first()).toHaveAttribute(
134+
'href',
135+
'http://localhost:3003/',
136+
);
137+
await expect(page.locator('a[href="http://localhost:3001/#/routing/foo"]').first()).toHaveAttribute(
138+
'href',
139+
'http://localhost:3001/#/routing/foo',
140+
);
141+
142+
const styledButton = page.getByRole('button', { name: '💅 Button' });
143+
await expect(styledButton).toBeVisible();
144+
await expect(styledButton).toHaveCSS('background-color', 'rgb(219, 112, 147)');
50145
});
51146

52147
test('dialog page loads and dialog opens', async ({ page }) => {
53148
await page.goto(`${base}/#/dialog`);
54-
await expect(page.getByRole('heading', { name: 'Dialog Demo' })).toBeVisible();
149+
150+
await expectAppBar(page, 'Dialog Demo');
55151
await expect(
56-
page.getByText(
57-
'Clicking the button below will render a Dialog using React Portal. This dialog component is being lazy loaded from the app #2.',
58-
),
152+
page.locator('p', {
153+
hasText:
154+
'Clicking the button below will render a Dialog using React Portal. This dialog component is being lazy loaded from the app #2.',
155+
}),
59156
).toBeVisible();
157+
60158
await page.getByRole('button', { name: 'Open Dialog' }).click();
61159
const dialog = page.locator('[role="dialog"]');
62160
await expect(dialog.getByRole('heading', { name: 'Dialog Example' })).toBeVisible();
@@ -69,21 +167,32 @@ test.describe('Comprehensive Demo App1', () => {
69167

70168
test('svelte page updates greeting', async ({ page }) => {
71169
await page.goto(`${base}/#/svelte`);
72-
await expect(page.getByRole('heading', { name: 'Svelte Demo' })).toBeVisible();
170+
171+
await expectAppBar(page, 'Svelte Demo');
172+
73173
const input = page.locator('input');
74-
await input.fill('test');
75-
await expect(page.locator('h1')).toHaveText('Hello From Svelte test!');
174+
await expect(input).toBeVisible();
175+
await input.fill('May The Force Be With You');
176+
await expect(page.locator('h1')).toHaveText('Hello From Svelte May The Force Be With You!');
76177
});
77178

78179
test('routing page renders tabs', async ({ page }) => {
79180
await page.goto(`${base}/#/routing/foo`);
80-
await expect(page.getByRole('heading', { name: 'Routing Demo' })).toBeVisible();
181+
182+
await expectAppBar(page, 'Routing Demo');
183+
184+
for (const paragraph of routingParagraphs) {
185+
await expect(page.locator('p', { hasText: paragraph })).toBeVisible();
186+
}
187+
188+
await expect(page.getByRole('tab', { name: 'Foo' })).toBeVisible();
81189
await expect(page.getByText('Foo Content')).toBeVisible();
190+
82191
await page.getByRole('tab', { name: 'Bar' }).click();
83192
await expect(page.getByText('Bar Content')).toBeVisible();
84-
await expect(page.getByRole('button', { name: 'Bar Button' })).toHaveCSS(
85-
'background-color',
86-
'rgb(219, 112, 147)',
87-
);
193+
194+
const barButton = page.getByRole('button', { name: 'Bar Button' });
195+
await expect(barButton).toBeVisible();
196+
await expect(barButton).toHaveCSS('background-color', 'rgb(219, 112, 147)');
88197
});
89198
});

comprehensive-demo-react16/e2e/checkApp2.spec.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,17 @@ const base = 'http://localhost:3002';
55
test.describe('Comprehensive Demo App2', () => {
66
test('renders blocks, dialog and tabs', async ({ page }) => {
77
await page.goto(base);
8-
await expect(page.locator('header').first()).toHaveCSS('background-color', 'rgb(63, 81, 181)');
8+
await expect(page.locator('.jss1')).toBeVisible();
9+
const appBar = page.locator('header').first();
10+
await expect(appBar).toHaveCSS('background-color', 'rgb(63, 81, 181)');
911
await expect(page.locator('.jss2')).toHaveCSS('background-color', 'rgb(250, 250, 250)');
1012
await expect(page.locator('.jss3')).toHaveCSS('background-color', 'rgb(255, 255, 255)');
1113

1214
await expect(page.getByRole('heading', { name: 'Material UI App' })).toBeVisible();
13-
await expect(page.getByText('Dialog Component')).toBeVisible();
14-
await page.getByRole('button', { name: 'Open Dialog' }).click();
15+
await expect(page.getByRole('heading', { name: 'Dialog Component' })).toBeVisible();
16+
const openDialogButton = page.getByRole('button', { name: 'Open Dialog' });
17+
await expect(openDialogButton).toBeVisible();
18+
await openDialogButton.click();
1519
const dialog = page.locator('[role="dialog"]');
1620
await expect(dialog.getByRole('heading', { name: 'Dialog Example' })).toBeVisible();
1721
await expect(
@@ -20,9 +24,13 @@ test.describe('Comprehensive Demo App2', () => {
2024
await dialog.getByRole('button', { name: 'Nice' }).click();
2125
await expect(dialog).not.toBeVisible();
2226

23-
await expect(page.getByText('Tabs Component')).toBeVisible();
27+
await expect(page.getByRole('heading', { name: 'Tabs Component' })).toBeVisible();
28+
const fooTab = page.getByRole('tab', { name: 'Foo' });
29+
const barTab = page.getByRole('tab', { name: 'Bar' });
30+
await expect(fooTab).toBeVisible();
31+
await expect(barTab).toBeVisible();
2432
await expect(page.getByText('Foo Content')).toBeVisible();
25-
await page.getByRole('tab', { name: 'Bar' }).click();
33+
await barTab.click();
2634
await expect(page.getByText('Bar Content')).toBeVisible();
2735
await expect(page.getByRole('button', { name: 'Bar Button' })).toHaveCSS(
2836
'background-color',

comprehensive-demo-react16/e2e/checkApp3.spec.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,12 @@ const base = 'http://localhost:3003';
55
test.describe('Comprehensive Demo App3', () => {
66
test('shows styled button', async ({ page }) => {
77
await page.goto(base);
8+
await expect(page.locator('.jss1')).toBeVisible();
9+
const appBar = page.locator('header').first();
10+
await expect(appBar).toHaveCSS('background-color', 'rgb(63, 81, 181)');
11+
await expect(page.locator('.jss2')).toHaveCSS('background-color', 'rgb(250, 250, 250)');
812
await expect(page.getByRole('heading', { name: 'Styled Components App' })).toBeVisible();
9-
const button = page.getByRole('button', { name: /Test Button/ });
13+
const button = page.getByRole('button', { name: '💅 Test Button' });
1014
await expect(button).toBeVisible();
1115
await expect(button).toHaveCSS('background-color', 'rgb(219, 112, 147)');
1216
});

0 commit comments

Comments
 (0)