Skip to content

Commit f4d60fc

Browse files
author
HusneShabbir
committed
feat: update scorecard e2e tests with Jira integration
1 parent ea67e7e commit f4d60fc

8 files changed

Lines changed: 111 additions & 379 deletions

File tree

.ibm/pipelines/auth/secrets-rhdh-secrets.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,5 @@ data:
4242
GITHUB_OAUTH_APP_ID: $GITHUB_OAUTH_APP_ID_ENCODED
4343
GITHUB_OAUTH_APP_SECRET: $GITHUB_OAUTH_APP_SECRET_ENCODED
4444
BACKEND_SECRET: $BACKEND_SECRET
45+
JIRA_TOKEN: $JIRA_TOKEN
4546
type: Opaque

.ibm/pipelines/env_variables.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ QE_USER8_ID=$(cat /tmp/secrets/QE_USER8_ID)
9090
QE_USER8_PASS=$(cat /tmp/secrets/QE_USER8_PASS)
9191
QE_USER9_ID=$(cat /tmp/secrets/QE_USER9_ID)
9292
QE_USER9_PASS=$(cat /tmp/secrets/QE_USER9_PASS)
93+
JIRA_TOKEN=$(cat /tmp/secrets/jira_token)
9394

9495
K8S_CLUSTER_TOKEN_TEMPORARY=$(cat /tmp/secrets/K8S_CLUSTER_TOKEN_TEMPORARY)
9596

.ibm/pipelines/value_files/values_showcase-rbac.yaml

Lines changed: 12 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -257,90 +257,36 @@ global:
257257
- package: ./dynamic-plugins/dist/backstage-community-plugin-analytics-provider-segment
258258
disabled: true
259259
#Enable Scorecard plugin.
260-
- disabled: false
261-
package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard
260+
- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard:bs_1.42.5__1.0.0!red-hat-developer-hub-backstage-plugin-scorecard
261+
disabled: false
262262
pluginConfig:
263263
dynamicPlugins:
264264
frontend:
265265
red-hat-developer-hub.backstage-plugin-scorecard:
266266
entityTabs:
267267
- path: "/scorecard"
268268
title: Scorecard
269-
titleKey: catalog.entityPage.scorecard.title
270269
mountPoint: entity.page.scorecard
271270
mountPoints:
272271
- mountPoint: entity.page.scorecard/cards
273272
importName: EntityScorecardContent
274273
config:
275274
layout:
276275
gridColumn: 1 / -1
277-
- disabled: false
278-
package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard-backend
279-
- disabled: false
280-
package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github
281-
pluginConfig:
282-
integrations:
283-
github:
284-
- host: github.com
285-
token: "{gh-token}"
286-
- disabled: false
287-
package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira
288-
pluginConfig:
289-
jira:
290-
baseUrl: "{jira-base-url}"
291-
token: "{jira-api-token}"
292-
product: datacenter
293-
# Enable orchestrator plugins - Official release (Backstage 1.45.3)
294-
- package: "oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-orchestrator:bs_1.45.3__5.1.0!red-hat-developer-hub-backstage-plugin-orchestrator"
295-
disabled: false
296-
pluginConfig:
297-
dynamicPlugins:
298-
frontend:
299-
red-hat-developer-hub.backstage-plugin-orchestrator:
300-
appIcons:
301-
- importName: OrchestratorIcon
302-
name: orchestratorIcon
303-
dynamicRoutes:
304-
- importName: OrchestratorPage
305-
menuItem:
306-
icon: orchestratorIcon
307-
text: Orchestrator
308-
textKey: menuItem.orchestrator
309-
path: /orchestrator
310-
entityTabs:
311-
- path: /workflows
312-
title: Workflows
313-
titleKey: catalog.entityPage.workflows.title
314-
mountPoint: entity.page.workflows
315-
mountPoints:
316-
- mountPoint: entity.page.workflows/cards
317-
importName: OrchestratorCatalogTab
318-
config:
319-
layout:
320-
gridColumn: "1 / -1"
321-
if:
322-
anyOf:
323-
- IsOrchestratorCatalogTabAvailable
324-
- package: "oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-orchestrator-backend:bs_1.45.3__8.3.0!red-hat-developer-hub-backstage-plugin-orchestrator-backend"
276+
if:
277+
allOf:
278+
- isKind: component
279+
- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend:bs_1.42.5__1.0.0!red-hat-developer-hub-backstage-plugin-scorecard-backend
325280
disabled: false
326-
pluginConfig:
327-
orchestrator:
328-
dataIndexService:
329-
url: http://sonataflow-platform-data-index-service
330-
331-
- package: "oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator:bs_1.45.3__1.3.1!red-hat-developer-hub-backstage-plugin-scaffolder-backend-module-orchestrator"
281+
- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github:bs_1.42.5__1.0.0!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-github
332282
disabled: false
283+
- package: oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira:pr_1499__0.1.0!red-hat-developer-hub-backstage-plugin-scorecard-backend-module-jira
333284
pluginConfig:
334-
orchestrator:
335-
dataIndexService:
336-
url: http://sonataflow-platform-data-index-service
337-
338-
- package: "oci://ghcr.io/redhat-developer/rhdh-plugin-export-overlays/red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets:bs_1.45.3__1.2.0!red-hat-developer-hub-backstage-plugin-orchestrator-form-widgets"
285+
jira:
286+
baseUrl: https://redhat-team-f703ynt3.atlassian.net
287+
token: ${JIRA_TOKEN}
288+
product: cloud
339289
disabled: false
340-
pluginConfig:
341-
dynamicPlugins:
342-
frontend:
343-
red-hat-developer-hub.backstage-plugin-orchestrator-form-widgets: {}
344290

345291
- package: ./dynamic-plugins/dist/red-hat-developer-hub-backstage-plugin-dynamic-home-page
346292
disabled: false

e2e-tests/playwright/e2e/plugins/scorecard/scorecard.spec.ts

Lines changed: 72 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,9 @@
1616

1717
import { test, expect } from "@playwright/test";
1818
import { Common } from "../../../utils/common";
19-
import { mockScorecardResponse } from "../../../utils/scorecard-utils";
2019
import { ComponentImportPage } from "../../../support/page-objects/scorecard/component-import-page";
2120
import { Catalog } from "../../../support/pages/catalog";
2221
import { ScorecardPage } from "../../../support/page-objects/scorecard/scorecard-page";
23-
import {
24-
CUSTOM_SCORECARD_RESPONSE,
25-
EMPTY_SCORECARD_RESPONSE,
26-
UNAVAILABLE_METRIC_RESPONSE,
27-
INVALID_THRESHOLD_RESPONSE,
28-
} from "../../../utils/scorecard-response-utils";
2922

3023
test.describe.serial("Scorecard Plugin Tests", () => {
3124
let context;
@@ -62,38 +55,33 @@ test.describe.serial("Scorecard Plugin Tests", () => {
6255
});
6356

6457
test("Import component and validate scorecard tabs for GitHub PRs and Jira tickets", async () => {
65-
await mockScorecardResponse(page, CUSTOM_SCORECARD_RESPONSE);
66-
67-
await catalog.go();
68-
await catalog.goToByName("rhdh-app");
69-
await scorecardPage.openTab();
70-
71-
await scorecardPage.verifyScorecardValues({
72-
"GitHub open PRs": "9",
73-
"Jira open blocking tickets": "8",
74-
});
58+
await importPage.importAndOpenScorecard(
59+
"https://github.com/rhdh-pai-qe/RHDH-scorecard-plugin-test/blob/main/all-scorecards.yaml",
60+
catalog,
61+
scorecardPage,
62+
);
7563

7664
for (const metric of scorecardPage.scorecardMetrics) {
7765
await scorecardPage.validateScorecardAriaFor(metric);
7866
}
7967
});
8068

81-
test("Display empty state when scorecard API returns no metrics", async () => {
82-
await mockScorecardResponse(page, EMPTY_SCORECARD_RESPONSE);
83-
84-
await catalog.go();
85-
await catalog.goToByName("rhdh-app");
86-
await scorecardPage.openTab();
69+
test("Validate empty scorecard state", async () => {
70+
await importPage.importAndOpenScorecard(
71+
"https://github.com/rhdh-pai-qe/RHDH-scorecard-plugin-test/blob/main/no-scorecards.yaml",
72+
catalog,
73+
scorecardPage,
74+
);
8775

8876
await scorecardPage.expectEmptyState();
8977
});
9078

9179
test("Displays error state for unavailable data while rendering metrics", async () => {
92-
await mockScorecardResponse(page, UNAVAILABLE_METRIC_RESPONSE);
93-
94-
await catalog.go();
95-
await catalog.goToByName("rhdh-app");
96-
await scorecardPage.openTab();
80+
await importPage.importAndOpenScorecard(
81+
"https://github.com/rhdh-pai-qe/RHDH-scorecard-plugin-test/blob/main/metrics-unavailable.yaml",
82+
catalog,
83+
scorecardPage,
84+
);
9785

9886
const jiraMetric = scorecardPage.scorecardMetrics[1];
9987
const githubMetric = scorecardPage.scorecardMetrics[0];
@@ -114,22 +102,19 @@ test.describe.serial("Scorecard Plugin Tests", () => {
114102
await expect(errorLocator).toBeVisible();
115103

116104
await errorLocator.hover();
117-
const errorTooltip = UNAVAILABLE_METRIC_RESPONSE.find(
118-
(metric) => metric.id === "github.open-prs",
119-
)?.error;
120-
121-
expect(errorTooltip).toBeTruthy();
122-
await expect(page.getByText(errorTooltip!)).toBeVisible();
105+
const errorTooltip =
106+
"GraphqlResponseError: Request failed due to following response errors: - Could not resolve to a Repository with the name 'dzemanov/react-app-t1'.";
107+
await expect(page.getByText(errorTooltip)).toBeVisible();
123108

124109
await scorecardPage.validateScorecardAriaFor(jiraMetric);
125110
});
126111

127112
test("Display error state for invalid threshold config while rendering metrics", async () => {
128-
await mockScorecardResponse(page, INVALID_THRESHOLD_RESPONSE);
129-
130-
await catalog.go();
131-
await catalog.goToByName("rhdh-app");
132-
await scorecardPage.openTab();
113+
await importPage.importAndOpenScorecard(
114+
"https://github.com/rhdh-pai-qe/RHDH-scorecard-plugin-test/blob/main/invalid-threshold.yaml",
115+
catalog,
116+
scorecardPage,
117+
);
133118

134119
const githubMetric = scorecardPage.scorecardMetrics[0];
135120
const jiraMetric = scorecardPage.scorecardMetrics[1];
@@ -150,12 +135,55 @@ test.describe.serial("Scorecard Plugin Tests", () => {
150135
await expect(errorLocator).toBeVisible();
151136

152137
await errorLocator.hover();
153-
const errorTooltip = INVALID_THRESHOLD_RESPONSE.find(
154-
(metric) => metric.id === "github.open-prs",
155-
)?.result?.thresholdResult?.error;
138+
const errorTooltip =
139+
"ThresholdConfigFormatError: Invalid threshold annotation 'scorecard.io/github.open_prs.thresholds.rules.error: >50d' in entity 'component:default/invalid-threshold': Cannot parse \"50d\" as number from expression: \">50d\"";
140+
await expect(page.getByText(errorTooltip)).toBeVisible();
141+
142+
await scorecardPage.validateScorecardAriaFor(jiraMetric);
143+
});
156144

157-
expect(errorTooltip).toBeTruthy();
158-
await expect(page.getByText(errorTooltip!)).toBeVisible();
145+
test("Validate only GitHub scorecard is displayed", async () => {
146+
await importPage.importAndOpenScorecard(
147+
"https://github.com/rhdh-pai-qe/RHDH-scorecard-plugin-test/blob/main/github-scorecard-only.yaml",
148+
catalog,
149+
scorecardPage,
150+
);
151+
152+
const githubMetric = scorecardPage.scorecardMetrics[0];
153+
const jiraMetric = scorecardPage.scorecardMetrics[1];
154+
155+
const isGithubVisible = await scorecardPage.isScorecardVisible(
156+
githubMetric.title,
157+
);
158+
expect(isGithubVisible).toBe(true);
159+
160+
const isJiraVisible = await scorecardPage.isScorecardVisible(
161+
jiraMetric.title,
162+
);
163+
expect(isJiraVisible).toBe(false);
164+
165+
await scorecardPage.validateScorecardAriaFor(githubMetric);
166+
});
167+
168+
test("Validate only Jira scorecard is displayed", async () => {
169+
await importPage.importAndOpenScorecard(
170+
"https://github.com/rhdh-pai-qe/RHDH-scorecard-plugin-test/blob/main/jira-scorecard-only.yaml",
171+
catalog,
172+
scorecardPage,
173+
);
174+
175+
const githubMetric = scorecardPage.scorecardMetrics[0];
176+
const jiraMetric = scorecardPage.scorecardMetrics[1];
177+
178+
const isGithubVisible = await scorecardPage.isScorecardVisible(
179+
githubMetric.title,
180+
);
181+
expect(isGithubVisible).toBe(false);
182+
183+
const isJiraVisible = await scorecardPage.isScorecardVisible(
184+
jiraMetric.title,
185+
);
186+
expect(isJiraVisible).toBe(true);
159187

160188
await scorecardPage.validateScorecardAriaFor(jiraMetric);
161189
});

e2e-tests/playwright/support/page-objects/scorecard/component-import-page.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
*/
1616
import { Page } from "@playwright/test";
1717
import { UIhelper } from "../../../utils/ui-helper";
18+
import { Catalog } from "../../../support/pages/catalog";
19+
import { ScorecardPage } from "./scorecard-page";
1820

1921
export class ComponentImportPage {
2022
readonly page: Page;
@@ -34,16 +36,33 @@ export class ComponentImportPage {
3436
await this.uiHelper.fillTextInputByLabel("URL", url);
3537
await this.uiHelper.clickButton("Analyze");
3638
await this.uiHelper.clickButton("Import");
37-
//wait for few seconds
3839
await this.page.waitForTimeout(5000);
3940
}
4041

4142
async viewImportedComponent() {
4243
await this.uiHelper.clickButton("View Component");
44+
const entityNotFoundLocator = this.page.getByRole("button", {
45+
name: "Warning: Entity not found",
46+
});
47+
if (await entityNotFoundLocator.isVisible({ timeout: 10000 })) {
48+
await this.page.reload();
49+
}
4350
// After a component is imported, wait for the Overview tab to be visible
4451
// This could take sometime more time depending on the environment performance.
4552
// We saw API calls taking round about 10 seconds in some cases on our CI.
4653
const tabLocator = this.page.getByRole("tab", { name: "Overview" });
4754
await tabLocator.waitFor({ state: "visible", timeout: 20000 });
4855
}
56+
57+
async importAndOpenScorecard(
58+
url: string,
59+
catalog: Catalog,
60+
scorecardPage: ScorecardPage,
61+
) {
62+
await catalog.go();
63+
await this.startComponentImport();
64+
await this.analyzeComponent(url);
65+
await this.viewImportedComponent();
66+
await scorecardPage.openTab();
67+
}
4968
}

e2e-tests/playwright/support/page-objects/scorecard/scorecard-page.ts

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
*/
1616

1717
import { Page, expect } from "@playwright/test";
18-
import { waitUntilApiCallSucceeds } from "../../../utils/scorecard-utils";
1918

2019
export class ScorecardPage {
2120
readonly page: Page;
@@ -34,25 +33,15 @@ export class ScorecardPage {
3433
{
3534
title: "Jira open blocking tickets",
3635
description:
37-
"Highlights the number of critical, blocking issues that are currently open in Jira.",
36+
"Highlights the number of issues that are currently open in Jira.",
3837
},
3938
];
4039
}
4140

4241
async openTab() {
43-
const scorecardTab = this.page.getByText("Scorecard");
42+
const scorecardTab = this.page.getByText("Scorecard", { exact: true });
4443
await expect(scorecardTab).toBeVisible();
45-
await Promise.all([
46-
waitUntilApiCallSucceeds(this.page),
47-
scorecardTab.click(),
48-
]);
49-
}
50-
51-
async verifyScorecardValues(expectedValues: { [key: string]: string }) {
52-
for (const [metric, value] of Object.entries(expectedValues)) {
53-
await expect(this.page.getByText(metric)).toBeVisible();
54-
await expect(this.page.getByText(value)).toBeVisible();
55-
}
44+
await scorecardTab.click();
5645
}
5746

5847
async expectEmptyState() {
@@ -79,9 +68,9 @@ export class ScorecardPage {
7968
- article:
8069
- text: ${title}
8170
- paragraph: ${description}
82-
- paragraph: /Error/
83-
- paragraph: /Warning/
8471
- paragraph: /Success/
72+
- paragraph: /Warning/
73+
- paragraph: /Error/
8574
`);
8675
}
8776

0 commit comments

Comments
 (0)