Skip to content

Commit 5dd743c

Browse files
authored
chore(e2e-test): [Test automation] Verify global floating action button , application provider and listener (#2405)
* chore(e2e-test): [Test automation] Verify global floating action button * e2e tests to verify application provider and listener
1 parent 9c3c4ab commit 5dd743c

12 files changed

+304
-7
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
dynamicPlugins:
2+
rootDirectory: dynamic-plugins-root
3+
frontend:
4+
red-hat-developer-hub.backstage-plugin-global-floating-action-button:
5+
mountPoints:
6+
- mountPoint: application/listener
7+
importName: DynamicGlobalFloatingActionButton
8+
- mountPoint: global.floatingactionbutton/config
9+
importName: NullComponent
10+
config:
11+
icon: github
12+
label: 'Git'
13+
showLabel: true
14+
toolTip: 'Github'
15+
to: https://github.com/redhat-developer/rhdh
16+
- mountPoint: global.floatingactionbutton/config
17+
importName: NullComponent
18+
config:
19+
icon: '<svg viewBox="0 0 250 300" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M200.134 0l55.555 117.514-55.555 117.518h-47.295l55.555-117.518L152.84 0h47.295zM110.08 99.836l20.056-38.092-2.29-8.868L102.847 0H55.552l48.647 102.898 5.881-3.062zm17.766 74.433l-17.333-39.034-6.314-3.101-48.647 102.898h47.295l25-52.88v-7.883z" fill="#40B4E5"/><path d="M152.842 235.032L97.287 117.514 152.842 0h47.295l-55.555 117.514 55.555 117.518h-47.295zm-97.287 0L0 117.514 55.555 0h47.296L47.295 117.514l55.556 117.518H55.555z" fill="#003764"/></svg>'
20+
label: 'Quay'
21+
showLabel: true
22+
toolTip: 'Quay'
23+
to: 'https://quay.io'
24+
visibleOnPaths: ['/catalog']
25+
red-hat-developer-hub.backstage-plugin-bulk-import:
26+
mountPoints:
27+
- mountPoint: global.floatingactionbutton/config
28+
importName: BulkImportPage
29+
config:
30+
slot: 'bottom-left'
31+
icon: bulkImportIcon
32+
label: 'Bulk import'
33+
toolTip: 'Register multiple repositories in bulk'
34+
to: /bulk-import/repositories
35+
excludeOnPaths: ['/catalog']
36+
appIcons:
37+
- name: bulkImportIcon
38+
importName: BulkImportIcon
39+
dynamicRoutes:
40+
- path: /bulk-import/repositories
41+
importName: BulkImportPage
42+
menuItem:
43+
icon: bulkImportIcon
44+
text: Bulk import

.ibm/pipelines/resources/config_map/dynamic-homepage-and-sidebar-config.yaml

+23
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ dynamicPlugins:
33
frontend:
44
red-hat-developer-hub.backstage-plugin-dynamic-home-page:
55
mountPoints:
6+
- mountPoint: application/listener
7+
importName: VisitListener
68
- mountPoint: home.page/cards
79
importName: SearchBar
810
config:
@@ -143,6 +145,27 @@ dynamicPlugins:
143145
importName: FeaturedDocsCard
144146
- mountPoint: home.page/cards
145147
importName: JokeCard
148+
- mountPoint: home.page/cards
149+
importName: RecentlyVisitedCard
150+
config:
151+
layouts:
152+
xl: { w: 6, h: 4, x: 6 }
153+
lg: { w: 6, h: 4, x: 6 }
154+
md: { w: 6, h: 4, x: 6 }
155+
sm: { w: 6, h: 4, x: 6 }
156+
xs: { w: 6, h: 4, x: 6 }
157+
xxs: { w: 6, h: 4, x: 6 }
158+
- mountPoint: home.page/cards
159+
importName: TopVisitedCard
160+
config:
161+
layouts:
162+
xl: { w: 6, h: 4 }
163+
lg: { w: 6, h: 4 }
164+
md: { w: 6, h: 4 }
165+
sm: { w: 6, h: 4 }
166+
xs: { w: 6, h: 4 }
167+
xxs: { w: 6, h: 4 }
168+
146169
default.main-menu-items:
147170
menuItems:
148171
default.list:

.ibm/pipelines/utils.sh

+6
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,12 @@ apply_yaml_files() {
526526

527527
oc apply -f "$dir/auth/secrets-rhdh-secrets.yaml" --namespace="${project}"
528528

529+
# configuration for testing global floating action button.
530+
oc create configmap dynamic-global-floating-action-button-config \
531+
--from-file="dynamic-global-floating-action-button-config.yaml"="$dir/resources/config_map/dynamic-global-floating-action-button-config.yaml" \
532+
--namespace="${project}" \
533+
--dry-run=client -o yaml | oc apply -f -
534+
529535
# Create Pipeline run for tekton test case.
530536
oc apply -f "$dir/resources/pipeline-run/hello-world-pipeline.yaml"
531537
oc apply -f "$dir/resources/pipeline-run/hello-world-pipeline-run.yaml"

.ibm/pipelines/value_files/values_showcase.yaml

+27
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,29 @@ global:
3030
minutes: 1
3131
initialDelay:
3232
seconds: 15
33+
- package: '@red-hat-developer-hub/[email protected]'
34+
integrity: 'sha512-N3HxvTNe/CxTDtXIsvfre3ZoFLWYfPxz/IJiKY3nzA5C0wcH4lZn+fI+mDFoTUXogt7fZWyl3mCrdwQWrOEM8A=='
35+
pluginConfig:
36+
dynamicPlugins:
37+
frontend:
38+
red-hat-developer-hub.backstage-plugin-application-provider-test:
39+
dynamicRoutes:
40+
- path: /application-provider-test-page
41+
importName: TestPage
42+
mountPoints:
43+
- mountPoint: application/provider
44+
importName: TestProviderOne
45+
- mountPoint: application/provider
46+
importName: TestProviderTwo
47+
- package: '@red-hat-developer-hub/[email protected]'
48+
integrity: 'sha512-GRLbpjXE9ZyfRJr/iyp+1L2sUQL97aPc+FV/IORH63eGT32Uc0xCFBu51fGPYJFmXY49BlSh+CnVnbKNsyiOAQ=='
49+
pluginConfig:
50+
dynamicPlugins:
51+
frontend:
52+
red-hat-developer-hub.backstage-plugin-application-listener-test:
53+
mountPoints:
54+
- mountPoint: application/listener
55+
importName: LocationListener
3356
- package: ./dynamic-plugins/dist/backstage-plugin-catalog-backend-module-github-org-dynamic
3457
disabled: false
3558
- package: ./dynamic-plugins/dist/backstage-community-plugin-github-issues
@@ -136,6 +159,8 @@ global:
136159
disabled: false
137160
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-marketplace
138161
disabled: false
162+
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-global-floating-action-button
163+
disabled: false
139164

140165
# -- Upstream Backstage [chart configuration](https://github.com/backstage/charts/blob/main/charts/backstage/values.yaml)
141166
upstream:
@@ -169,6 +194,8 @@ upstream:
169194
filename: app-config-rhdh.yaml
170195
- configMapRef: dynamic-homepage-and-sidebar-config
171196
filename: dynamic-homepage-and-sidebar-config.yaml
197+
- configMapRef: dynamic-global-floating-action-button-config
198+
filename: dynamic-global-floating-action-button-config.yaml
172199
startupProbe:
173200
# This gives enough time upon container startup before the liveness and readiness probes are triggered.
174201
# Giving (120s = initialDelaySeconds + failureThreshold * periodSeconds) to account for the worst case scenario.

dynamic-plugins/_utils/src/wrappers.test.ts

+19-7
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,10 @@ function validateDynamicPluginsConfig(
116116
): void {
117117
const dynamicPluginsPackageNames = config.plugins.reduce(
118118
(packageNames, plugin) => {
119-
const isExternalPlugin = externalDynamicPlugins?.some((externalDynamicPlugin) => externalDynamicPlugin.package === plugin.package)
119+
const isExternalPlugin = externalDynamicPlugins?.some(
120+
(externalDynamicPlugin) =>
121+
externalDynamicPlugin.package === plugin.package,
122+
);
120123
if (!isExternalPlugin) {
121124
// We want the third index ['.', 'dynamic-plugins', 'dist', 'backstage-plugin-scaffolder-backend-module-github-dynamic']
122125
packageNames.push(plugin.package.split("/")[3]);
@@ -241,13 +244,22 @@ describe("Dynamic Plugin Wrappers", () => {
241244
IBM_VALUES_SHOWCASE_CONFIG_FILE,
242245
);
243246

244-
const externalDynamicPluginsConfig: DynamicPluginConfig[] = [{
245-
package: "@pataknight/[email protected]",
246-
disabled: false,
247-
},
247+
const externalDynamicPluginsConfig: DynamicPluginConfig[] = [
248248
{
249-
package: "@backstage-community/[email protected]"
250-
}
249+
package: "@pataknight/[email protected]",
250+
disabled: false,
251+
},
252+
{
253+
package: "@backstage-community/[email protected]",
254+
},
255+
{
256+
package:
257+
"@red-hat-developer-hub/[email protected]",
258+
},
259+
{
260+
package:
261+
"@red-hat-developer-hub/[email protected]",
262+
},
251263
];
252264

253265
it("should have a corresponding package", () => {

e2e-tests/playwright/e2e/home-page-customization.spec.ts

+13
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import { test } from "@playwright/test";
22
import { UIhelper } from "../utils/ui-helper";
33
import { Common } from "../utils/common";
4+
import { HomePage } from "../support/pages/home-page";
45

56
test.describe("Home page customization", () => {
67
let common: Common;
78
let uiHelper: UIhelper;
9+
let homePage: HomePage;
810

911
test.beforeEach(async ({ page }) => {
1012
uiHelper = new UIhelper(page);
1113
common = new Common(page);
14+
homePage = new HomePage(page);
1215
await common.loginAsGuest();
1316
});
1417

@@ -30,4 +33,14 @@ test.describe("Home page customization", () => {
3033
await uiHelper.verifyTextinCard("Random Joke", "Random Joke");
3134
await uiHelper.clickButton("Reroll");
3235
});
36+
37+
test("Verify that the Top Visited card in the Home page renders without an error", async () => {
38+
await uiHelper.verifyTextinCard("Top Visited", "Top Visited");
39+
await homePage.verifyVisitedCardContent("Top Visited");
40+
});
41+
42+
test("Verify that the Recently Visited card in the Home page renders without an error", async () => {
43+
await uiHelper.verifyTextinCard("Recently Visited", "Recently Visited");
44+
await homePage.verifyVisitedCardContent("Recently Visited");
45+
});
3346
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { expect, test } from "@playwright/test";
2+
import { UIhelper } from "../../utils/ui-helper";
3+
import { Common } from "../../utils/common";
4+
5+
test.describe("Test ApplicationListener", () => {
6+
let uiHelper: UIhelper;
7+
8+
test.beforeEach(async ({ page }) => {
9+
const common = new Common(page);
10+
uiHelper = new UIhelper(page);
11+
await common.loginAsGuest();
12+
});
13+
14+
test("Verify that the LocationListener logs the current location", async ({
15+
page,
16+
}) => {
17+
const logs: string[] = [];
18+
19+
page.on("console", (msg) => {
20+
if (msg.type() === "log") {
21+
logs.push(msg.text());
22+
}
23+
});
24+
25+
await uiHelper.openSidebar("Catalog");
26+
27+
expect(logs.some((l) => l.includes("pathname: /catalog"))).toBeTruthy();
28+
});
29+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { expect, test } from "@playwright/test";
2+
import { UIhelper } from "../../utils/ui-helper";
3+
import { Common } from "../../utils/common";
4+
import { UI_HELPER_ELEMENTS } from "../../support/pageObjects/global-obj";
5+
6+
test.describe("Test ApplicationProvider", () => {
7+
let uiHelper: UIhelper;
8+
9+
test.beforeEach(async ({ page }) => {
10+
const common = new Common(page);
11+
uiHelper = new UIhelper(page);
12+
await common.loginAsGuest();
13+
});
14+
15+
test("Verify that the TestPage is rendered", async ({ page }) => {
16+
await page.goto("/application-provider-test-page");
17+
await uiHelper.verifyText("application/provider TestPage");
18+
await uiHelper.verifyText(
19+
"This card will work only if you register the TestProviderOne and TestProviderTwo correctly.",
20+
);
21+
await uiHelper.verifyTextinCard("Context one", "Context one");
22+
23+
const contextOneFirstLocator = page
24+
.locator(UI_HELPER_ELEMENTS.MuiCard("Context one"))
25+
.first();
26+
const contextOneSecondLocator = page
27+
.locator(UI_HELPER_ELEMENTS.MuiCard("Context one"))
28+
.last();
29+
const contextOneIncrementButton = contextOneFirstLocator
30+
.locator("button")
31+
.filter({ hasText: "+" });
32+
await contextOneIncrementButton.click();
33+
expect(contextOneFirstLocator.getByText("1")).toBeVisible();
34+
expect(contextOneSecondLocator.getByText("1")).toBeVisible();
35+
36+
await uiHelper.verifyTextinCard("Context two", "Context two");
37+
const contextTwoFirstLocator = page
38+
.locator(UI_HELPER_ELEMENTS.MuiCard("Context two"))
39+
.first();
40+
const contextTwoSecondLocator = page
41+
.locator(UI_HELPER_ELEMENTS.MuiCard("Context two"))
42+
.last();
43+
const contextTwoIncrementButton = contextTwoFirstLocator
44+
.locator("button")
45+
.filter({ hasText: "+" });
46+
await contextTwoIncrementButton.click();
47+
expect(contextTwoFirstLocator.getByText("1")).toBeVisible();
48+
expect(contextTwoSecondLocator.getByText("1")).toBeVisible();
49+
});
50+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { test } from "@playwright/test";
2+
import { Common } from "../../utils/common";
3+
import { FabPo } from "../../support/pageObjects/global-fab-po";
4+
import { UIhelper } from "../../utils/ui-helper";
5+
import { PagesUrl } from "../../support/pageObjects/page";
6+
7+
test.describe("Test global floating action button plugin", () => {
8+
let uiHelper: UIhelper;
9+
let fabHelper: FabPo;
10+
11+
test.beforeEach(async ({ page }) => {
12+
const common = new Common(page);
13+
await common.loginAsGuest();
14+
15+
uiHelper = new UIhelper(page);
16+
fabHelper = new FabPo(page, "/" as PagesUrl);
17+
});
18+
19+
test("Check if Git and Bulk import floating buttons are visible on the Home page", async () => {
20+
await uiHelper.openSidebar("Home");
21+
await fabHelper.verifyFabButtonByLabel("Git");
22+
await fabHelper.verifyFabButtonByDataTestId("bulk-import");
23+
await fabHelper.clickFabMenu();
24+
await uiHelper.verifyText("Added repositories");
25+
});
26+
27+
test("Check if floating button is shown with two sub-menu actions on the Catalog Page", async () => {
28+
await uiHelper.openSidebar("Catalog");
29+
await fabHelper.verifyFabButtonByDataTestId("floating-button");
30+
await fabHelper.clickFabMenu();
31+
await fabHelper.verifyFabButtonByLabel("Git");
32+
await fabHelper.clickFabMenu();
33+
await fabHelper.verifyPopup(
34+
"GitHub - redhat-developer/rhdh: The repo formerly known as janus-idp/backstage-showcase",
35+
);
36+
await fabHelper.switchTab();
37+
await fabHelper.verifyFabButtonByLabel("Quay");
38+
await fabHelper.clickFabMenu();
39+
await fabHelper.verifyPopup("Quay Container Registry · Quay");
40+
});
41+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { expect, Locator, Page } from "@playwright/test";
2+
import { PageObject, PagesUrl } from "./page";
3+
4+
export class FabPo extends PageObject {
5+
private fabMenu: Locator;
6+
7+
constructor(page: Page, url: PagesUrl) {
8+
super(page, url);
9+
}
10+
11+
private generateDataTestId(label: string) {
12+
return label.split(" ").join("-").toLocaleLowerCase();
13+
}
14+
15+
public async verifyPopup(str: string) {
16+
const popupPromise = this.page.waitForEvent("popup");
17+
const popup = await popupPromise;
18+
await expect(popup).toHaveTitle(str);
19+
}
20+
21+
public async clickFabMenu() {
22+
await this.fabMenu.click();
23+
}
24+
25+
public async switchTab() {
26+
await this.page.bringToFront();
27+
}
28+
29+
public async verifyFabButtonByLabel(label: string) {
30+
this.fabMenu = this.page.getByTestId(this.generateDataTestId(label));
31+
await expect(this.fabMenu).toContainText(label);
32+
}
33+
34+
public async verifyFabButtonByDataTestId(id: string) {
35+
this.fabMenu = this.page.getByTestId(id);
36+
await expect(this.fabMenu).toBeVisible();
37+
}
38+
}

e2e-tests/playwright/support/pageObjects/page-obj.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export const HOME_PAGE_COMPONENTS = {
22
MuiAccordion: 'div[class*="MuiAccordion-root-"]',
3+
MuiCard: 'div[class*="MuiCard-root-"]',
34
};
45

56
export const SEARCH_OBJECTS_COMPONENTS = {

0 commit comments

Comments
 (0)