Skip to content

Commit 4f5ebd1

Browse files
committed
add playwright tests for 1.10 with NFS
1 parent ea8ac3a commit 4f5ebd1

11 files changed

Lines changed: 179 additions & 7 deletions

File tree

helm/rhdh-110-nfs/values.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,14 @@ redhat-developer-hub:
122122
appConfig:
123123
app:
124124
title: RHDH 1.10 NFS loadtest
125+
packages: all
126+
extensions:
127+
- page:home:
128+
config:
129+
path: /
130+
- page:catalog:
131+
config:
132+
path: /catalog
125133

126134
auth:
127135
providers:

load-generator/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"install-browser": "playwright install chromium",
1717
"playwright": "playwright",
1818
"analyse": "node scripts/analyse.mts",
19-
"test": "playwright test && npm run analyse"
19+
"test": "playwright test && npm run analyse",
20+
"test:ofs:ui": "playwright test --ui && npm run analyse",
21+
"test:nfs": "RHDH_FRONTEND=nfs playwright test && npm run analyse",
22+
"test:nfs:ui": "RHDH_FRONTEND=nfs playwright test --ui && npm run analyse"
2023
}
2124
}

load-generator/playwright.config.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,25 @@ import { defineConfig, devices } from '@playwright/test';
88
// import path from 'path';
99
// dotenv.config({ path: path.resolve(__dirname, '.env') });
1010

11+
const frontend = (process.env.RHDH_FRONTEND ?? 'ofs').toLowerCase();
12+
const testMatch =
13+
frontend === 'nfs'
14+
? 'guest-login-home-catalog-nfs.spec.ts'
15+
: 'guest-login-home-catalog.spec.ts';
16+
const nfsNavigationTimeout = Number(process.env.NFS_NAVIGATION_TIMEOUT ?? 200_000);
17+
const testTimeout = Number(
18+
process.env.PLAYWRIGHT_TEST_TIMEOUT ??
19+
(frontend === 'nfs' ? Math.max(600_000, nfsNavigationTimeout * 3) : 60_000),
20+
);
21+
1122
/**
1223
* See https://playwright.dev/docs/test-configuration.
1324
*/
1425
export default defineConfig({
26+
testMatch,
27+
timeout: testTimeout,
1528
expect: {
16-
timeout: 20_000, // default 5_000
29+
timeout: frontend === 'nfs' ? nfsNavigationTimeout : 20_000,
1730
},
1831

1932
testDir: './scenarios',
@@ -36,6 +49,9 @@ export default defineConfig({
3649
/* Base URL to use in actions like `await page.goto('')`. */
3750
baseURL: process.env.RHDH_URL || process.env.PLAYWRIGHT_BASEURL,
3851

52+
navigationTimeout: frontend === 'nfs' ? nfsNavigationTimeout : 30_000,
53+
actionTimeout: frontend === 'nfs' ? nfsNavigationTimeout : undefined,
54+
3955
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
4056
trace: 'on-first-retry',
4157
},

load-generator/scenarios/Backstage.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,10 @@ export class Backstage {
2828
sidebarItem(name: string) {
2929
return this.sidebar.getByRole('link', { name, exact: true });
3030
}
31+
32+
sidebarNavItem(name: string) {
33+
return this.sidebar
34+
.locator('span.MuiTypography-subtitle2')
35+
.filter({ hasText: new RegExp(`^${name}$`) });
36+
}
3137
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import { test as base, expect, type Page } from '@playwright/test';
2+
3+
import { Backstage } from './Backstage';
4+
5+
const test = base.extend<{ backstage: Backstage }>({
6+
backstage: ({ page }, use) => use(new Backstage(page)),
7+
});
8+
9+
const loops = Number(process.env.LOOPS ?? 100);
10+
const nfsNavigationTimeout = Number(process.env.NFS_NAVIGATION_TIMEOUT ?? 500_000);
11+
12+
async function isNfsHomeVisible(page: Page): Promise<boolean> {
13+
const noWidgets = page.getByText(/no widgets added/i);
14+
const addWidget = page.getByRole('button', { name: 'Add widget' });
15+
const edit = page.getByRole('button', { name: 'Edit' });
16+
17+
return (
18+
(await noWidgets.isVisible()) ||
19+
(await addWidget.isVisible()) ||
20+
(await edit.isVisible())
21+
);
22+
}
23+
24+
async function expectNfsHomeVisible(page: Page) {
25+
await expect
26+
.poll(() => isNfsHomeVisible(page), { timeout: nfsNavigationTimeout })
27+
.toBe(true);
28+
}
29+
30+
for (let i = 1; i <= loops; i++) {
31+
test(`run ${i} of ${loops}`, async ({ backstage, page }) => {
32+
await test.step('login', async () => {
33+
await page.goto('/', { timeout: nfsNavigationTimeout });
34+
// NFS + many dynamic plugins can take well over 20s on cold load.
35+
await expect(page.getByRole('button', { name: 'Enter' })).toBeVisible({
36+
timeout: nfsNavigationTimeout,
37+
});
38+
});
39+
40+
await test.step('home', async () => {
41+
await page.getByRole('button', { name: 'Enter' }).click();
42+
await page.waitForURL('/', { timeout: nfsNavigationTimeout });
43+
44+
if (!(await isNfsHomeVisible(page))) {
45+
await backstage.sidebarNavItem('Home').click();
46+
}
47+
48+
await expectNfsHomeVisible(page);
49+
});
50+
51+
await test.step('catalog', async () => {
52+
await backstage.sidebarItem('Catalog').click();
53+
await expect(page.getByText('Catalog', { exact: true }).first()).toBeVisible();
54+
// await expect(backstage.content.getByText('All Components (1001)')).toBeVisible();
55+
await expect(backstage.content.getByText('All Components (1000)')).toBeVisible();
56+
await expect(backstage.content.getByText('Component 1', { exact: true })).toBeVisible();
57+
});
58+
59+
await test.step('component', async () => {
60+
await backstage.content.getByText('Component 1', { exact: true }).click();
61+
await expect(page.getByText('Component 1', { exact: true }).first()).toBeVisible();
62+
await expect(backstage.content.getByText('About')).toBeVisible();
63+
await expect(backstage.content.getByText('Group 1')).toBeVisible();
64+
await expect(backstage.content.getByText('System 1')).toBeVisible();
65+
await expect(page.getByTestId('header-tab-catalog-tab-1')).toBeVisible();
66+
});
67+
68+
await test.step('catalog-tab-n', async () => {
69+
await page.getByTestId('header-tab-catalog-tab-1').click();
70+
await expect(page.getByText('Component 1', { exact: true }).first()).toBeVisible();
71+
await expect(page.getByText('Example User List')).toBeVisible({ timeout: 30_000 });
72+
});
73+
74+
await test.step('page-n', async () => {
75+
await backstage.sidebar
76+
.getByRole('link', { name: /^(Page 1|page-1)$/ })
77+
.click();
78+
await expect(page.getByText(/welcome to page-?1!/i)).toBeVisible({ timeout: 30_000 });
79+
await expect(page.getByText('Information card')).toBeVisible();
80+
await expect(page.getByText('Example User List')).toBeVisible();
81+
});
82+
});
83+
}

plugins/backstage-1.49/yarn.lock

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17698,7 +17698,7 @@ __metadata:
1769817698
languageName: node
1769917699
linkType: hard
1770017700

17701-
"clsx@npm:^1.0.2, clsx@npm:^1.0.4, clsx@npm:^1.1.0, clsx@npm:^1.2.1":
17701+
"clsx@npm:^1.0.2, clsx@npm:^1.0.4, clsx@npm:^1.1.0, clsx@npm:^1.1.1, clsx@npm:^1.2.1":
1770217702
version: 1.2.1
1770317703
resolution: "clsx@npm:1.2.1"
1770417704
checksum: 10c0/34dead8bee24f5e96f6e7937d711978380647e936a22e76380290e35486afd8634966ce300fc4b74a32f3762c7d4c0303f442c3e259f4ce02374eb0c82834f27
@@ -25213,6 +25213,13 @@ __metadata:
2521325213
languageName: node
2521425214
linkType: hard
2521525215

25216+
"lodash.isequal@npm:^4.0.0":
25217+
version: 4.5.0
25218+
resolution: "lodash.isequal@npm:4.5.0"
25219+
checksum: 10c0/dfdb2356db19631a4b445d5f37868a095e2402292d59539a987f134a8778c62a2810c2452d11ae9e6dcac71fc9de40a6fedcb20e2952a15b431ad8b29e50e28f
25220+
languageName: node
25221+
linkType: hard
25222+
2521625223
"lodash.isinteger@npm:^4.0.4":
2521725224
version: 4.0.4
2521825225
resolution: "lodash.isinteger@npm:4.0.4"
@@ -25429,7 +25436,7 @@ __metadata:
2542925436
languageName: node
2543025437
linkType: hard
2543125438

25432-
"luxon@npm:^3.0.0, luxon@npm:^3.2.1":
25439+
"luxon@npm:^3.0.0, luxon@npm:^3.2.1, luxon@npm:^3.4.3":
2543325440
version: 3.7.2
2543425441
resolution: "luxon@npm:3.7.2"
2543525442
checksum: 10c0/ed8f0f637826c08c343a29dd478b00628be93bba6f068417b1d8896b61cb61c6deacbe1df1e057dbd9298334044afa150f9aaabbeb3181418ac8520acfdc2ae2
@@ -29801,6 +29808,19 @@ __metadata:
2980129808
languageName: node
2980229809
linkType: hard
2980329810

29811+
"react-draggable@npm:^4.0.0":
29812+
version: 4.7.0
29813+
resolution: "react-draggable@npm:4.7.0"
29814+
dependencies:
29815+
clsx: "npm:^2.1.1"
29816+
prop-types: "npm:^15.8.1"
29817+
peerDependencies:
29818+
react: ">= 16.3.0"
29819+
react-dom: ">= 16.3.0"
29820+
checksum: 10c0/4bfd46025b6009585a644d17721cafcd7976c058c250086c06c1a952724230c83caa548c54f9b5849c3a148144e3ed6610a1745b2afc6db685c85c56a0b4f775
29821+
languageName: node
29822+
linkType: hard
29823+
2980429824
"react-draggable@npm:^4.5.0":
2980529825
version: 4.5.0
2980629826
resolution: "react-draggable@npm:4.5.0"
@@ -29850,6 +29870,22 @@ __metadata:
2985029870
languageName: node
2985129871
linkType: hard
2985229872

29873+
"react-grid-layout@npm:1.3.4":
29874+
version: 1.3.4
29875+
resolution: "react-grid-layout@npm:1.3.4"
29876+
dependencies:
29877+
clsx: "npm:^1.1.1"
29878+
lodash.isequal: "npm:^4.0.0"
29879+
prop-types: "npm:^15.8.1"
29880+
react-draggable: "npm:^4.0.0"
29881+
react-resizable: "npm:^3.0.4"
29882+
peerDependencies:
29883+
react: ">= 16.3.0"
29884+
react-dom: ">= 16.3.0"
29885+
checksum: 10c0/2c4a9ca1284cf6a618070aeccf8ffb8d2d91798452f7606395a4524bda27fad82ba9c818cb3e420d617fec8aed93c0caaae060c714d21a929c6f5c75727697b7
29886+
languageName: node
29887+
linkType: hard
29888+
2985329889
"react-helmet@npm:6.1.0":
2985429890
version: 6.1.0
2985529891
resolution: "react-helmet@npm:6.1.0"
@@ -30069,6 +30105,19 @@ __metadata:
3006930105
languageName: node
3007030106
linkType: hard
3007130107

30108+
"react-resizable@npm:^3.0.4":
30109+
version: 3.2.0
30110+
resolution: "react-resizable@npm:3.2.0"
30111+
dependencies:
30112+
prop-types: "npm:15.x"
30113+
react-draggable: "npm:^4.5.0"
30114+
peerDependencies:
30115+
react: ">= 16.3"
30116+
react-dom: ">= 16.3"
30117+
checksum: 10c0/b589bca0b1135dc4bf875f09dd677821bfe4b468e5c9ec7e37d91a06ca49281f3dec289d5aa41a7cc0f4603872610b0c5d1d077287c3fef73a5c9339d3216598
30118+
languageName: node
30119+
linkType: hard
30120+
3007230121
"react-resizable@npm:^3.0.5":
3007330122
version: 3.1.3
3007430123
resolution: "react-resizable@npm:3.1.3"

plugins/backstage-1.52/app-config.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@ app:
33
baseUrl: http://localhost:3000
44
packages: all
55
extensions:
6-
- page:catalog:
6+
- page:home:
77
config:
88
path: /
9+
- page:catalog:
10+
config:
11+
path: /catalog
912
- api:app/app-language:
1013
config:
1114
availableLanguages: ['en', 'de', 'es', 'fr', 'it', 'ja']
1215
defaultLanguage: 'en'
1316
- nav-item:user-settings: false
14-
- nav-item:search: false
17+
- nav-item:search: false
1518
# - nav-item:catalog:
1619
# config:
1720
# title: 'Home'

plugins/backstage-1.52/packages/app-nfs/e2e-tests/app.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ test('App should render the welcome page', async ({ page }) => {
2323
await expect(enterButton).toBeVisible();
2424
await enterButton.click();
2525

26+
await page.goto('/catalog');
2627
await expect(page.getByText('My Company Catalog')).toBeVisible();
2728
});

plugins/backstage-1.52/packages/app-nfs/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { createApp } from '@backstage/frontend-defaults';
22
import catalogPlugin from '@backstage/plugin-catalog/alpha';
3+
import homePlugin from '@backstage/plugin-home/alpha';
34
import notificationsPlugin from '@backstage/plugin-notifications/alpha';
45
import scaffolderPlugin from '@backstage/plugin-scaffolder/alpha';
56
import searchPlugin from '@backstage/plugin-search/alpha';
@@ -10,6 +11,7 @@ import { navModule } from './modules/nav';
1011

1112
export default createApp({
1213
features: [
14+
homePlugin,
1315
catalogPlugin,
1416
scaffolderPlugin,
1517
searchPlugin,

plugins/backstage-1.52/packages/app-nfs/src/modules/nav/Sidebar.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export const SidebarContent = NavContentBlueprint.make({
3333
</SidebarGroup>
3434
<SidebarDivider />
3535
<SidebarGroup label="Menu" icon={<MenuIcon />}>
36+
{nav.take('page:home')}
3637
{nav.take('page:catalog')}
3738
{nav.take('page:scaffolder')}
3839
<SidebarDivider />

0 commit comments

Comments
 (0)