From 161bbd11f4c492edb06d71af99321053008699c9 Mon Sep 17 00:00:00 2001 From: Subhash Khileri Date: Fri, 28 Jun 2024 21:32:57 +0530 Subject: [PATCH] [e2e] Link Scaffolded Templates to Catalog Items --- .../e2e/catalog-scaffoldedfromLink.spec.ts | 116 ++++++++++++++++++ .../playwright/support/pages/CatalogImport.ts | 21 ++++ e2e-tests/playwright/utils/APIEndpoints.ts | 2 + e2e-tests/playwright/utils/UIhelper.ts | 4 + 4 files changed, 143 insertions(+) create mode 100644 e2e-tests/playwright/e2e/catalog-scaffoldedfromLink.spec.ts diff --git a/e2e-tests/playwright/e2e/catalog-scaffoldedfromLink.spec.ts b/e2e-tests/playwright/e2e/catalog-scaffoldedfromLink.spec.ts new file mode 100644 index 0000000000..1ab9859773 --- /dev/null +++ b/e2e-tests/playwright/e2e/catalog-scaffoldedfromLink.spec.ts @@ -0,0 +1,116 @@ +import { Page, test } from '@playwright/test'; +import { UIhelper } from '../utils/UIhelper'; +import { Common, setupBrowser } from '../utils/Common'; +import { CatalogImport } from '../support/pages/CatalogImport'; +import { APIHelper } from '../utils/APIHelper'; +import { githubAPIEndpoints } from '../utils/APIEndpoints'; + +let page: Page; +test.describe.serial('Link Scaffolded Templates to Catalog Items', () => { + let uiHelper: UIhelper; + let common: Common; + let catalogImport: CatalogImport; + + const template = + 'https://github.com/janus-idp/backstage-plugins/blob/main/plugins/scaffolder-annotator-action/examples/templates/01-scaffolder-template.yaml'; + + const reactAppDetails = { + owner: 'janus-qe/maintainers', + componentName: `test-scaffoldedfromlink-${Date.now()}`, + description: 'react app using template', + repo: `test-scaffolded-${Date.now()}`, + repoOwner: process.env.GITHUB_ORG || 'janus-qe', + }; + + test.beforeAll(async ({ browser }, testInfo) => { + page = (await setupBrowser(browser, testInfo)).page; + + common = new Common(page); + uiHelper = new UIhelper(page); + catalogImport = new CatalogImport(page); + + await common.loginAsGithubUser(); + }); + test('Register an Template', async () => { + await uiHelper.openSidebar('Catalog'); + await uiHelper.clickButton('Create'); + await uiHelper.clickButton('Register Existing Component'); + await catalogImport.registerExistingTemplate(template); + }); + + test('Create a React App using the newly registered Template', async () => { + await uiHelper.openSidebar('Catalog'); + await uiHelper.clickButton('Create'); + await uiHelper.searchInputPlaceholder('Create React'); + + await uiHelper.verifyText('Create React App Template'); + await uiHelper.clickButton('Choose'); + + await uiHelper.fillTextInputByLabel('Name', reactAppDetails.componentName); + await uiHelper.fillTextInputByLabel( + 'Description', + reactAppDetails.description, + ); + await uiHelper.fillTextInputByLabel('Owner', reactAppDetails.owner); + await uiHelper.clickButton('Next'); + + await uiHelper.fillTextInputByLabel('Owner', reactAppDetails.repoOwner); + await uiHelper.fillTextInputByLabel('Repository', reactAppDetails.repo); + await uiHelper.clickButton('Review'); + + await uiHelper.verifyRowInTableByUniqueText('Owner', [ + `group:${reactAppDetails.owner}`, + ]); + await uiHelper.verifyRowInTableByUniqueText('Component Id', [ + reactAppDetails.componentName, + ]); + await uiHelper.verifyRowInTableByUniqueText('Description', [ + reactAppDetails.description, + ]); + await uiHelper.verifyRowInTableByUniqueText('Repo Url', [ + `github.com?owner=${reactAppDetails.repoOwner}&repo=${reactAppDetails.repo}`, + ]); + + await uiHelper.clickButton('Create'); + await uiHelper.clickLink('Open in catalog'); + }); + + test('Verify Scaffolded link in components Dependencies and scaffoldedFrom relation in entity Raw Yaml ', async () => { + await common.clickOnGHloginPopup(); + await uiHelper.clickTab('Dependencies'); + await uiHelper.verifyText( + `ownerOf / ownedByscaffoldedFromcomponent:${reactAppDetails.componentName}group:${reactAppDetails.owner}Create React App Template`, + ); + await catalogImport.inspectEntityAndVerifyYaml( + `- type: scaffoldedFrom\n targetRef: template:default/create-react-app-template-with-timestamp-entityref\n target:\n kind: template\n namespace: default\n name: create-react-app-template-with-timestamp-entityref`, + ); + }); + + test('Verify Registered Template and scaffolderOf relation in entity Raw Yaml', async () => { + await uiHelper.openSidebar('Catalog'); + await uiHelper.selectMuiBox('Kind', 'Template'); + await uiHelper.searchInputPlaceholder('Create React App Template'); + await uiHelper.verifyRowInTableByUniqueText('Create React App Template', [ + 'website', + ]); + await uiHelper.clickLink('Create React App Template'); + + await catalogImport.inspectEntityAndVerifyYaml( + `- type: scaffolderOf\n targetRef: component:default/${reactAppDetails.componentName}\n target:\n kind: component\n namespace: default\n name: ${reactAppDetails.componentName}\n`, + ); + + await uiHelper.clickLink('Launch Template'); + await uiHelper.verifyText('Provide some simple information'); + }); + + test.afterAll(async () => { + await APIHelper.githubRequest( + 'DELETE', + githubAPIEndpoints.deleteRepo( + reactAppDetails.repoOwner, + reactAppDetails.repo, + ), + ); + await page.close(); + }); +}); diff --git a/e2e-tests/playwright/support/pages/CatalogImport.ts b/e2e-tests/playwright/support/pages/CatalogImport.ts index e3cab03742..6211bd8ebd 100644 --- a/e2e-tests/playwright/support/pages/CatalogImport.ts +++ b/e2e-tests/playwright/support/pages/CatalogImport.ts @@ -25,6 +25,27 @@ export class CatalogImport { expect(await this.uiHelper.isBtnVisible('Register another')).toBeTruthy(); } } + + async registerExistingTemplate(url: string) { + await this.page.fill(CatalogImportPO.componentURL, url); + await this.uiHelper.clickButton('Analyze'); + + // Wait for the visibility of either 'Refresh' or 'Import' button + if (await this.uiHelper.isBtnVisible('Import')) { + await this.uiHelper.clickButton('Import'); + } else { + await this.uiHelper.clickButton('Refresh'); + expect(await this.uiHelper.isBtnVisible('Register another')).toBeTruthy(); + } + } + + async inspectEntityAndVerifyYaml(text: string) { + await this.page.getByTitle('More').click(); + await this.page.getByRole('menuitem').getByText('Inspect entity').click(); + await this.uiHelper.clickTab('Raw YAML'); + await expect(this.page.getByTestId('code-snippet')).toContainText(text); + await this.uiHelper.clickButton('Close'); + } } export class BackstageShowcase { diff --git a/e2e-tests/playwright/utils/APIEndpoints.ts b/e2e-tests/playwright/utils/APIEndpoints.ts index 0368fc4c9c..19e4fec9c7 100644 --- a/e2e-tests/playwright/utils/APIEndpoints.ts +++ b/e2e-tests/playwright/utils/APIEndpoints.ts @@ -7,4 +7,6 @@ export const githubAPIEndpoints = { issues: (state: string) => `${backstageShowcaseAPI}/issues?per_page=100&sort=updated&state=${state}`, workflowRuns: `${backstageShowcaseAPI}/actions/runs?per_page=100`, + deleteRepo: (owner: string, repo: string) => + `https://api.github.com/repos/${owner}/${repo}`, }; diff --git a/e2e-tests/playwright/utils/UIhelper.ts b/e2e-tests/playwright/utils/UIhelper.ts index 11699fe7bb..9f5ad3fab1 100644 --- a/e2e-tests/playwright/utils/UIhelper.ts +++ b/e2e-tests/playwright/utils/UIhelper.ts @@ -15,6 +15,10 @@ export class UIhelper { await this.verifyRowsInTable(expectedRows); } + async fillTextInputByLabel(label: string, text: string) { + await this.page.getByLabel(label).fill(text); + } + async searchInputPlaceholder(searchText: string) { await this.page.fill('input[placeholder="Search"]', searchText); }