Skip to content

Commit f13f583

Browse files
feat(scorecard):Added extension for scorecard homepage and metric page (#2637)
* feat(scorecard):Added extension for scorecard homepage and metric page Signed-off-by: rohitratannagar <rohitratannagar2003@gmail.com> * Supporting e2e tests for nfs Signed-off-by: rohitratannagar <rohitratannagar2003@gmail.com> * adding changeset Signed-off-by: rohitratannagar <rohitratannagar2003@gmail.com> * removing the double border Signed-off-by: rohitratannagar <rohitratannagar2003@gmail.com> * using published home-page Signed-off-by: rohitratannagar <rohitratannagar2003@gmail.com> * updating translation import in app-legacy Signed-off-by: rohitratannagar <rohitratannagar2003@gmail.com> --------- Signed-off-by: rohitratannagar <rohitratannagar2003@gmail.com>
1 parent d37946f commit f13f583

27 files changed

Lines changed: 740 additions & 333 deletions
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@red-hat-developer-hub/backstage-plugin-scorecard': minor
3+
---
4+
5+
Adding scorecardHomepage and metric page extension, also added e2e support in nfs

workspaces/scorecard/.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,4 @@ site
5151
*.session.sql
5252

5353
# E2E test reports
54-
e2e-test-report/
54+
e2e-test-report*/

workspaces/scorecard/app-config.yaml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ app:
55
extensions:
66
- api:app/app-language:
77
config:
8-
availableLanguages: ['en', 'de', 'fr']
8+
availableLanguages: ['en', 'de', 'fr', 'it', 'es', 'ja']
99
defaultLanguage: 'en'
10+
- api:home/visits: true
11+
- app-root-element:home/visit-listener: true
12+
- page:home:
13+
config:
14+
path: /
1015

1116
# Scorecard tab: entity shows tab if it matches any filter below.
1217
- entity-content:catalog/entity-content-scorecard:
@@ -16,6 +21,28 @@ app:
1621
type: website
1722
- kind: api # e.g. any API entity
1823
- type: service # e.g. Component or System with spec.type: service
24+
- home-page-layout:home/dynamic-homepage-layout:
25+
config:
26+
customizable: true
27+
widgetLayout:
28+
ScorecardJiraHomepage:
29+
priority: 240
30+
breakpoints:
31+
xl: { w: 4, h: 6 }
32+
lg: { w: 4, h: 6 }
33+
md: { w: 4, h: 6 }
34+
sm: { w: 4, h: 6 }
35+
xs: { w: 4, h: 6 }
36+
xxs: { w: 4, h: 6 }
37+
ScorecardGithubHomepage:
38+
priority: 250
39+
breakpoints:
40+
xl: { w: 4, h: 6, x: 4 }
41+
lg: { w: 4, h: 6, x: 4 }
42+
md: { w: 4, h: 6, x: 4 }
43+
sm: { w: 4, h: 6, x: 4 }
44+
xs: { w: 4, h: 6, x: 4 }
45+
xxs: { w: 4, h: 6, x: 4 }
1946
organization:
2047
name: My Company
2148

workspaces/scorecard/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@
2121
"test": "NODE_OPTIONS='--experimental-vm-modules' backstage-cli repo test",
2222
"test:all": "NODE_OPTIONS='--experimental-vm-modules' backstage-cli repo test --coverage",
2323
"test:e2e": "playwright test",
24+
"test:e2e:legacy": "APP_MODE=legacy playwright test",
25+
"test:e2e:nfs": "APP_MODE=nfs playwright test",
26+
"test:e2e:all": "yarn test:e2e:legacy && yarn test:e2e:nfs",
27+
"playwright": "bash -c 'if [[ \"$*\" == \"test\" ]]; then yarn test:e2e:all; else npx playwright \"$@\"; fi' _",
2428
"fix": "backstage-cli repo fix",
2529
"lint": "backstage-cli repo lint --since origin/main",
2630
"lint:all": "backstage-cli repo lint",

workspaces/scorecard/packages/app-legacy/e2e-tests/pages/HomePage.ts

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ import {
2222
} from '../utils/translationUtils';
2323

2424
type ThresholdState = 'success' | 'warning' | 'error';
25+
const escapeRegex = (value: string) =>
26+
value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
2527

2628
export class HomePage {
2729
readonly page: Page;
@@ -48,7 +50,22 @@ export class HomePage {
4850

4951
async addCard(cardName: string) {
5052
await this.page.getByRole('button', { name: 'Add widget' }).click();
51-
await this.page.getByRole('button', { name: cardName }).click();
53+
await expect(
54+
this.page.getByRole('heading', { name: 'Add new widget to dashboard' }),
55+
).toBeVisible();
56+
57+
let cardPattern: RegExp;
58+
if (cardName === 'Onboarding section') {
59+
cardPattern = /Onboarding section|RhdhOnboardingSection/i;
60+
} else if (cardName === 'Scorecard: GitHub open PRs') {
61+
cardPattern = /Scorecard:\s*GitHub open PRs|ScorecardGithubHomepage/i;
62+
} else if (cardName === 'Scorecard: Jira open blocking') {
63+
cardPattern = /Scorecard:\s*Jira open blocking|ScorecardJiraHomepage/i;
64+
} else {
65+
cardPattern = new RegExp(escapeRegex(cardName), 'i');
66+
}
67+
68+
await this.page.getByRole('button', { name: cardPattern }).first().click();
5269
}
5370

5471
async saveChanges() {
@@ -69,8 +86,9 @@ export class HomePage {
6986

7087
getCard(metricId: 'github.open_prs' | 'jira.open_issues'): Locator {
7188
return this.page
72-
.locator('article')
73-
.filter({ hasText: this.translations.metric[metricId].title });
89+
.getByText(this.translations.metric[metricId].title, { exact: true })
90+
.last()
91+
.locator('xpath=ancestor::article[1]');
7492
}
7593

7694
async verifyThresholdTooltip(

workspaces/scorecard/packages/app-legacy/e2e-tests/scorecard.test.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,17 @@ test.describe('Scorecard Plugin Tests', () => {
7070

7171
test.describe('Entity Scorecards', () => {
7272
test('Verify permission required state', async ({ browser }, testInfo) => {
73+
await mockScorecardResponse(
74+
page,
75+
{
76+
error: {
77+
name: 'NotAllowedError',
78+
message: 'Permission denied',
79+
},
80+
},
81+
403,
82+
);
83+
7384
await catalogPage.openCatalog();
7485
await catalogPage.openComponent('Red Hat Developer Hub');
7586
await page.getByText('Scorecard', { exact: true }).click();
@@ -184,7 +195,30 @@ test.describe('Scorecard Plugin Tests', () => {
184195

185196
test.describe('Aggregated Scorecards', () => {
186197
test('Verify missing permission state', async () => {
198+
await mockAggregatedScorecardResponse(
199+
page,
200+
{
201+
error: {
202+
name: 'NotAllowedError',
203+
message: 'Permission denied',
204+
},
205+
},
206+
{
207+
error: {
208+
name: 'NotAllowedError',
209+
message: 'Permission denied',
210+
},
211+
},
212+
403,
213+
);
214+
187215
await homePage.navigateToHome();
216+
await page.reload();
217+
await homePage.enterEditMode();
218+
await homePage.clearAllCards();
219+
await homePage.addCard('Scorecard: GitHub open PRs');
220+
await homePage.addCard('Scorecard: Jira open blocking');
221+
await homePage.saveChanges();
188222

189223
const entityCount = getEntityCount(translations, currentLocale, '0');
190224

@@ -268,7 +302,9 @@ test.describe('Scorecard Plugin Tests', () => {
268302
),
269303
);
270304

271-
await runAccessibilityTests(page, testInfo);
305+
await runAccessibilityTests(page, testInfo, undefined, {
306+
includeSelectors: ['[data-chart-container]'],
307+
});
272308
});
273309

274310
test('Verify cards aggregation data is not found when API returns empty aggregated response', async () => {

workspaces/scorecard/packages/app-legacy/e2e-tests/utils/accessibility.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,20 @@ export async function runAccessibilityTests(
2121
page: Page,
2222
testInfo: TestInfo,
2323
attachName = 'accessibility-scan-results.json',
24+
options?: {
25+
includeSelectors?: string[];
26+
},
2427
) {
25-
const accessibilityScanResults = await new AxeBuilder({ page })
26-
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
27-
.analyze();
28+
let axeBuilder = new AxeBuilder({ page }).withTags([
29+
'wcag2a',
30+
'wcag2aa',
31+
'wcag21a',
32+
'wcag21aa',
33+
]);
34+
for (const selector of options?.includeSelectors ?? []) {
35+
axeBuilder = axeBuilder.include(selector);
36+
}
37+
const accessibilityScanResults = await axeBuilder.analyze();
2838

2939
await testInfo.attach(attachName, {
3040
body: JSON.stringify(accessibilityScanResults, null, 2),

workspaces/scorecard/packages/app-legacy/src/App.test.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@
1616
import { render, waitFor } from '@testing-library/react';
1717
import App from './App';
1818

19+
jest.mock(
20+
'@red-hat-developer-hub/backstage-plugin-dynamic-home-page/alpha',
21+
() => ({
22+
homepageTranslations: {},
23+
}),
24+
{ virtual: true },
25+
);
26+
1927
describe('App', () => {
2028
it('should render', async () => {
2129
process.env = {

workspaces/scorecard/packages/app-legacy/src/App.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ import {
6868
DynamicCustomizableHomePage,
6969
OnboardingSection,
7070
HomePageCardMountPoint,
71-
homepageTranslations,
7271
} from '@red-hat-developer-hub/backstage-plugin-dynamic-home-page';
72+
import { homepageTranslations } from '@red-hat-developer-hub/backstage-plugin-dynamic-home-page/alpha';
7373
import { ComponentType } from 'react';
7474

7575
const mountPoints: HomePageCardMountPoint[] = [

workspaces/scorecard/packages/app/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"@backstage/plugin-api-docs": "^0.13.1",
2727
"@backstage/plugin-app-react": "^0.1.0",
2828
"@backstage/plugin-catalog": "^1.32.0",
29+
"@backstage/plugin-home": "^0.9.2",
2930
"@backstage/plugin-org": "^0.6.46",
3031
"@backstage/plugin-scaffolder": "^1.34.3",
3132
"@backstage/plugin-search": "^1.5.0",
@@ -34,6 +35,7 @@
3435
"@backstage/ui": "^0.9.1",
3536
"@material-ui/core": "^4.12.2",
3637
"@mui/icons-material": "^5.18.0",
38+
"@red-hat-developer-hub/backstage-plugin-dynamic-home-page": "1.11.0",
3739
"@red-hat-developer-hub/backstage-plugin-scorecard": "workspace:^",
3840
"@red-hat-developer-hub/backstage-plugin-theme": "^0.13.0",
3941
"react": "^18.0.2",

0 commit comments

Comments
 (0)