# Instructions - Following Playwright test failed. - Explain why, be concise, respect Playwright best practices. - Provide a snippet of code with the fix, if possible. # Test info - Name: ui/component.test.ts >> Component UI Test Suite >> Test Image Registry >> test image registry - Location: tests/ui/component.test.ts:206:5 # Error details ``` TimeoutError: Step timeout of 20000ms exceeded. ``` ``` Error: expect(locator).toBeVisible() failed Locator: getByRole('heading', { name: 'Quay repository: rhtap_qe/backend-tests-go-wijgfgsg' }) Expected: visible Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 60000ms - waiting for getByRole('heading', { name: 'Quay repository: rhtap_qe/backend-tests-go-wijgfgsg' }) ``` # Page snapshot ```yaml - generic [ref=e3]: - navigation [ref=e5]: - generic [ref=e6]: - link "Home" [ref=e8] [cursor=pointer]: - /url: / - img [ref=e9] - generic [ref=e18]: - img [ref=e20] - combobox "Search..." [ref=e22] - generic "Self-service" [ref=e25]: - link "Self-service" [ref=e26] [cursor=pointer]: - /url: /create - img [ref=e28] - button "Your starred items" [ref=e31] [cursor=pointer]: - img [ref=e32] - button "Application launcher" [ref=e35] [cursor=pointer]: - img [ref=e36] - button "Help" [ref=e39] [cursor=pointer]: - img [ref=e40] - separator [ref=e42] - button "Admin" [ref=e44] [cursor=pointer]: - generic [ref=e45]: - img [ref=e46] - paragraph [ref=e49]: Admin - img [ref=e50] - generic [ref=e53]: - navigation "sidebar nav": - generic [ref=e55]: - generic [ref=e58]: - link "Home" [ref=e60] [cursor=pointer]: - /url: / - img [ref=e64] - generic [ref=e66]: Home - link "Catalog" [ref=e68] [cursor=pointer]: - /url: /catalog - img [ref=e72] - generic [ref=e74]: Catalog - link "APIs" [ref=e76] [cursor=pointer]: - /url: /api-docs - img [ref=e80] - generic [ref=e82]: APIs - link "Learning Paths" [ref=e84] [cursor=pointer]: - /url: /learning-paths - img [ref=e88] - generic [ref=e90]: Learning Paths - separator [ref=e91] - link "Docs" [ref=e94] [cursor=pointer]: - /url: /docs - img [ref=e98] - generic [ref=e100]: Docs - generic [ref=e101]: - separator [ref=e102] - button "Administration" [ref=e103] [cursor=pointer]: - generic [ref=e104]: - img [ref=e108] - generic [ref=e111]: Administration - img [ref=e113] - main [ref=e115]: - generic [ref=e117]: - paragraph [ref=e118]: component - heading "backend-tests-go-wijgfgsg" [level=1] [ref=e119]: - generic [ref=e121]: backend-tests-go-wijgfgsg - article [ref=e122]: - alert [ref=e123]: - 'button "Warning: Entity not found" [ref=e124] [cursor=pointer]': - generic [ref=e125]: - img [ref=e126] - 'heading "Warning: Entity not found" [level=6] [ref=e128]' - img [ref=e131] ``` # Test source ```ts 1 | import { expect, Page } from '@playwright/test'; 2 | import { ImageRegistry } from '../../../rhtap/core/integration/registry/imageRegistry'; 3 | import { BaseRegistryPlugin } from "./baseRegistryPlugin"; 4 | import { RegistryPO } from "../../page-objects/registryPo"; 5 | 6 | export class QuayUiPlugin extends BaseRegistryPlugin { 7 | 8 | constructor(registry: ImageRegistry) { 9 | super(registry); 10 | } 11 | 12 | async checkRepositoryHeading(page: Page): Promise { > 13 | await expect(page.getByRole('heading', { name: `${RegistryPO.quayRepositoryPrefix} ${this.registry.getOrganization()}/${this.registry.getImageName()}` })).toBeVisible(); | ^ Error: expect(locator).toBeVisible() failed 14 | } 15 | 16 | async checkRepositoryLink(page: Page): Promise { 17 | const repositoryLink = `${this.registry.getOrganization()}/${this.registry.getImageName()}`; 18 | 19 | await expect(page.getByRole('link', { name: repositoryLink })).toBeVisible(); 20 | } 21 | 22 | async checkTableColumns(page: Page): Promise { 23 | await this.checkTableColumnHeaders(page, [ 24 | RegistryPO.tagColumnHeader, 25 | RegistryPO.lastModifiedColumnHeader, 26 | RegistryPO.securityScanColumnHeader, 27 | RegistryPO.sizeColumnHeader, 28 | RegistryPO.expiresColumnHeader, 29 | RegistryPO.manifestColumnHeader, 30 | ]); 31 | } 32 | 33 | async checkVulnerabilities(page: Page): Promise { 34 | const searchInput = page.getByRole('textbox', { name: RegistryPO.searchPlaceholder }); 35 | await searchInput.fill('build-container'); 36 | 37 | // Click on the vulnerabilities scan link (any vulnerability counts) 38 | const vulnerabilitiesLink = page.getByRole('link', { name: /(Critical|High|Medium|Low):\s*\d+/ }).first(); 39 | await expect(vulnerabilitiesLink).toBeVisible(); 40 | await vulnerabilitiesLink.click(); 41 | 42 | // Check that the vulnerabilities heading is visible 43 | const vulnerabilitiesHeading = page.getByRole('heading', { name: /Vulnerabilities for .+/ }); 44 | await expect(vulnerabilitiesHeading).toBeVisible(); 45 | 46 | // Check that the vulnerabilities table headers are visible 47 | await expect(page.getByRole('columnheader', { name: RegistryPO.advisoryColumnHeader })).toBeVisible(); 48 | await expect(page.getByRole('columnheader', { name: RegistryPO.severityColumnHeader })).toBeVisible(); 49 | await expect(page.getByRole('columnheader', { name: RegistryPO.packageNameColumnHeader })).toBeVisible(); 50 | await expect(page.getByRole('columnheader', { name: RegistryPO.currentVersionColumnHeader })).toBeVisible(); 51 | await expect(page.getByRole('columnheader', { name: RegistryPO.fixedByColumnHeader })).toBeVisible(); 52 | 53 | // Close the vulnerabilities popup 54 | const goBackButton = page.getByRole('link', { name: RegistryPO.backToRepositoryLinkLabel }); 55 | await expect(goBackButton).toBeVisible(); 56 | await goBackButton.click(); 57 | 58 | // Check that the repository link is visible 59 | const repositoryLink = `${this.registry.getOrganization()}/${this.registry.getImageName()}`; 60 | await expect(page.getByRole('link', { name: repositoryLink })).toBeVisible(); 61 | } 62 | } 63 | ```