Skip to content

Commit bee2458

Browse files
author
HusneShabbir
committed
test(homepage): add Playwright e2e for dynamic home page
Add workspace e2e-tests with Keycloak auth, dynamic-plugins config aligned with the overlay image, and serial tests for cards, resize, delete, and clear-all flows. Skip restore-defaults until the control is fixed upstream. Made-with: Cursor
1 parent 01ac7ea commit bee2458

12 files changed

Lines changed: 2877 additions & 0 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
playwright-report/
2+
test-results/
3+
node_modules/.cache/
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
playwright-report/
2+
test-results/
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
nodeLinker: node-modules
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { createEslintConfig } from "@red-hat-developer-hub/e2e-test-utils/eslint";
2+
3+
export default createEslintConfig(import.meta.dirname);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "homepage-e2e-tests",
3+
"version": "1.0.0",
4+
"private": true,
5+
"type": "module",
6+
"engines": {
7+
"node": ">=22",
8+
"yarn": ">=3"
9+
},
10+
"packageManager": "yarn@3.8.7",
11+
"description": "E2E tests for Dynamic Home Page plugin",
12+
"scripts": {
13+
"test": "playwright test",
14+
"report": "playwright show-report",
15+
"test:ui": "playwright test --ui",
16+
"test:headed": "playwright test --headed",
17+
"lint:check": "eslint .",
18+
"lint:fix": "eslint . --fix",
19+
"prettier:check": "prettier --check .",
20+
"prettier:fix": "prettier --write .",
21+
"tsc:check": "tsc --noEmit",
22+
"check": "yarn tsc:check && yarn lint:check && yarn prettier:check"
23+
},
24+
"devDependencies": {
25+
"@eslint/js": "^9.39.2",
26+
"@playwright/test": "1.57.0",
27+
"@red-hat-developer-hub/e2e-test-utils": "1.1.14",
28+
"@types/node": "^24.10.1",
29+
"dotenv": "^16.4.7",
30+
"eslint": "^9.39.2",
31+
"eslint-plugin-check-file": "^3.3.1",
32+
"eslint-plugin-playwright": "^2.4.0",
33+
"prettier": "^3.7.4",
34+
"typescript": "^5.9.3",
35+
"typescript-eslint": "^8.50.0"
36+
}
37+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { defineConfig } from "@red-hat-developer-hub/e2e-test-utils/playwright-config";
2+
import dotenv from "dotenv";
3+
4+
dotenv.config({ path: `${import.meta.dirname}/.env` });
5+
6+
export default defineConfig({
7+
projects: [
8+
{
9+
name: "homepage",
10+
},
11+
],
12+
});
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
auth:
2+
environment: development
3+
providers:
4+
guest:
5+
dangerouslyAllowOutsideDevelopment: true
6+
oidc:
7+
development:
8+
metadataUrl: ${KEYCLOAK_METADATA_URL}
9+
clientId: ${KEYCLOAK_CLIENT_ID}
10+
clientSecret: ${KEYCLOAK_CLIENT_SECRET}
11+
prompt: auto
12+
callbackUrl: ${RHDH_BASE_URL}/api/auth/oidc/handler/frame
13+
signIn:
14+
resolvers:
15+
- resolver: emailLocalPartMatchingUserEntityName
16+
17+
permission:
18+
enabled: true
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# RHDH ships this plugin from dynamic-plugins.default.yaml as
2+
# ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page with default
3+
# dynamicRoutes. Enabling the same frontend plugin again via GHCR with different dynamicRoutes
4+
# makes install-dynamic-plugins.py fail merging pluginConfig. Disable the dist entry first
5+
# (same pattern as workspaces/scorecard/e2e-tests/tests/config/dynamic-plugins.yaml).
6+
plugins:
7+
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page
8+
disabled: true
9+
- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-dynamic-home-page:bs_1.45.3__1.10.4!red-hat-developer-hub-backstage-plugin-dynamic-home-page
10+
disabled: false
11+
pluginConfig:
12+
dynamicPlugins:
13+
frontend:
14+
red-hat-developer-hub.backstage-plugin-dynamic-home-page:
15+
dynamicRoutes:
16+
- path: /
17+
importName: DynamicCustomizableHomePage
18+
mountPoints:
19+
- mountPoint: home.page/cards
20+
importName: OnboardingSection
21+
config:
22+
id: onboarding-section
23+
title: Onboarding section
24+
- mountPoint: home.page/cards
25+
importName: EntitySection
26+
config:
27+
id: entity-section
28+
title: Entity section
29+
- mountPoint: home.page/cards
30+
importName: RecentlyVisitedCard
31+
config:
32+
id: recently-visited-card
33+
title: Recently visited
34+
- mountPoint: home.page/cards
35+
importName: TopVisitedCard
36+
config:
37+
id: top-visited-card
38+
title: Top visited
39+
- mountPoint: home.page/cards
40+
importName: JokeCard
41+
config:
42+
id: joke-card
43+
title: Random joke
44+
translationResources:
45+
- importName: homepageTranslations
46+
ref: homepageTranslationRef
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import { test } from "@red-hat-developer-hub/e2e-test-utils/test";
2+
import { DynamicHomePagePo } from "../support/dynamic-home-page.po";
3+
4+
/* Assertions live in DynamicHomePagePo (expect/verify*), matching RHDH core structure. */
5+
/* eslint-disable playwright/expect-expect -- see DynamicHomePagePo */
6+
test.describe.serial("Dynamic home page customization", () => {
7+
test.beforeAll(async ({ rhdh }) => {
8+
await rhdh.configure({
9+
auth: "keycloak",
10+
// Default chart tag in registry (avoid "next", which is not always published).
11+
version: process.env.RHDH_VERSION ?? "1.10",
12+
});
13+
await rhdh.deploy();
14+
});
15+
16+
test.beforeEach(async ({ loginHelper, uiHelper }) => {
17+
await loginHelper.loginAsKeycloakUser();
18+
await uiHelper.goToPageUrl("/", "Welcome back!");
19+
});
20+
21+
test("Verify cards display after login", async ({ page, uiHelper }) => {
22+
const home = new DynamicHomePagePo(page, uiHelper);
23+
await home.seedHomePageWidgets();
24+
await home.verifyHomePageLoaded();
25+
await home.verifyAllCardsDisplayed();
26+
await home.verifyEditButtonVisible();
27+
});
28+
29+
test("Verify all cards can be resized in edit mode", async ({
30+
page,
31+
uiHelper,
32+
}) => {
33+
const home = new DynamicHomePagePo(page, uiHelper);
34+
await home.enterEditMode();
35+
await home.resizeAllCards();
36+
await home.exitEditMode();
37+
});
38+
39+
test("Verify cards can be individually deleted in edit mode", async ({
40+
page,
41+
uiHelper,
42+
}) => {
43+
const home = new DynamicHomePagePo(page, uiHelper);
44+
await home.enterEditMode();
45+
await home.deleteAllCards();
46+
await home.verifyCardsDeleted();
47+
});
48+
49+
// restore defaults button is not working as expected in talks with devs
50+
// eslint-disable-next-line playwright/no-skipped-test -- re-enable when restore-defaults is fixed
51+
test.skip("Verify restore default cards", async ({ page, uiHelper }) => {
52+
const home = new DynamicHomePagePo(page, uiHelper);
53+
await home.restoreDefaultCards();
54+
await home.verifyCardsRestored();
55+
});
56+
57+
test("Verify all cards can be deleted with Clear all button", async ({
58+
page,
59+
uiHelper,
60+
}) => {
61+
const home = new DynamicHomePagePo(page, uiHelper);
62+
// Until restore-defaults works, rebuild the grid the same way as the first test.
63+
await home.seedHomePageWidgets();
64+
await home.enterEditMode();
65+
await home.clearAllCardsWithButton();
66+
await home.verifyCardsDeleted();
67+
});
68+
});

0 commit comments

Comments
 (0)