# 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/e2e-tests-python-vsxrpqdl' }) Expected: visible Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 60000ms - waiting for getByRole('heading', { name: 'Quay repository: rhtap_qe/e2e-tests-python-vsxrpqdl' }) ``` # 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=e116]: - generic [ref=e117]: - paragraph [ref=e118]: component — service - heading "e2e-tests-python-vsxrpqdl Add to favorites" [level=1] [ref=e119]: - generic [ref=e120]: - generic "component:default/e2e-tests-python-vsxrpqdl | service | Secure Supply Chain Example for Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. This sample demonstrates software supply chain security functionalty using an advanced continuous integration pipeline covering building, CVE scanning, security scanning, signatures, attestations, SLSA provenance and SBOM along with Gitops-based continuous deployment." [ref=e122]: e2e-tests-python-vsxrpqdl - button "Add to favorites" [ref=e123] [cursor=pointer]: - img [ref=e126] - generic [ref=e128]: - generic [ref=e130]: - paragraph [ref=e131]: Owner - paragraph [ref=e132]: - link "user:guest" [ref=e133] [cursor=pointer]: - /url: /catalog/default/user/guest - generic "user:default/guest" [ref=e134]: - img [ref=e136] - text: user:guest - generic [ref=e139]: - paragraph [ref=e140]: Lifecycle - paragraph [ref=e141]: experimental - button "more" [ref=e142] [cursor=pointer]: - img [ref=e144] - tablist "tabs" [ref=e150]: - tab "Overview" [selected] [ref=e151] [cursor=pointer] - tab "Topology" [ref=e152] [cursor=pointer] - tab "CI" [ref=e153] [cursor=pointer] - tab "CD" [ref=e154] [cursor=pointer] - tab "Kubernetes" [ref=e155] [cursor=pointer] - tab "API" [ref=e156] [cursor=pointer] - tab "Dependencies" [ref=e157] [cursor=pointer] - tab "Docs" [ref=e158] [cursor=pointer] - article [ref=e160]: - generic [ref=e161]: - alert [ref=e163]: - img [ref=e165] - generic [ref=e167]: "This entity has relations to other entities, which can't be found in the catalog. Entities not found are: user:default/guest" - generic [ref=e169]: - generic [ref=e171]: - generic [ref=e174]: Links - separator [ref=e175] - list [ref=e177]: - listitem [ref=e178]: - generic [ref=e180]: - img [ref=e183] - link "Trusted Secure Supply Chain , Opens in a new window" [ref=e186] [cursor=pointer]: - /url: https://www.redhat.com/en/solutions/trusted-software-supply-chain - text: Trusted Secure Supply Chain - generic [ref=e187]: ", Opens in a new window" - generic [ref=e189]: - generic [ref=e190]: - generic [ref=e191]: - generic [ref=e192]: About - navigation [ref=e194]: - link "View Source , Opens in a new window" [ref=e195] [cursor=pointer]: - /url: https://github.com/rhtap-rhdh-qe/e2e-tests-python-vsxrpqdl/tree/main/ - img [ref=e196] - generic [ref=e198]: View Source - generic [ref=e199]: ", Opens in a new window" - link "View TechDocs" [ref=e200] [cursor=pointer]: - /url: /docs/default/Component/e2e-tests-python-vsxrpqdl - img [ref=e201] - generic [ref=e203]: View TechDocs - generic [ref=e204]: - button "Refresh" [ref=e205] [cursor=pointer]: - img [ref=e207] - button "Edit, Opens in a new window" [ref=e209] [cursor=pointer]: - img [ref=e211] - generic [ref=e213]: ", Opens in a new window" - separator [ref=e214] - generic [ref=e216]: - generic [ref=e217]: - heading "Description" [level=2] [ref=e218] - paragraph [ref=e220]: Secure Supply Chain Example for Python is an interpreted, object-oriented, high-level programming language with dynamic semantics. This sample demonstrates software supply chain security functionalty using an advanced continuous integration pipeline covering building, CVE scanning, security scanning, signatures, attestations, SLSA provenance and SBOM along with Gitops-based continuous deployment. - generic [ref=e221]: - heading "Owner" [level=2] [ref=e222] - link "user:guest" [ref=e223] [cursor=pointer]: - /url: /catalog/default/user/guest - generic "user:default/guest" [ref=e224]: - img [ref=e226] - text: user:guest - generic [ref=e228]: - heading "System" [level=2] [ref=e229] - paragraph [ref=e230]: No System - generic [ref=e231]: - heading "Type" [level=2] [ref=e232] - paragraph [ref=e233]: service - generic [ref=e234]: - heading "Lifecycle" [level=2] [ref=e235] - paragraph [ref=e236]: experimental - generic [ref=e237]: - heading "Tags" [level=2] [ref=e238] - generic [ref=e240]: python - generic [ref=e242]: pip - generic [ref=e244]: flask - generic [ref=e246]: sscs - generic [ref=e248]: sbom - generic [ref=e250]: acs - generic [ref=e253]: - heading "Deployment Summary" [level=2] [ref=e256] - table [ref=e261]: - rowgroup [ref=e262]: - row "ArgoCD App Namespace Instance Server Revision Last deployed Sync status Health status" [ref=e263]: - columnheader "ArgoCD App" [ref=e264]: - button "ArgoCD App" [ref=e265] [cursor=pointer]: - text: ArgoCD App - img [ref=e266] - columnheader "Namespace" [ref=e268]: - button "Namespace" [ref=e269] [cursor=pointer]: - text: Namespace - img [ref=e270] - columnheader "Instance" [ref=e272]: - button "Instance" [ref=e273] [cursor=pointer]: - text: Instance - img [ref=e274] - columnheader "Server" [ref=e276]: - button "Server" [ref=e277] [cursor=pointer]: - text: Server - img [ref=e278] - columnheader "Revision" [ref=e280]: - button "Revision" [ref=e281] [cursor=pointer]: - text: Revision - img [ref=e282] - columnheader "Last deployed" [ref=e284]: - button "Last deployed" [ref=e285] [cursor=pointer]: - text: Last deployed - img [ref=e286] - columnheader "Sync status" [ref=e288]: - button "Sync status" [ref=e289] [cursor=pointer]: - text: Sync status - img [ref=e290] - columnheader "Health status" [ref=e292]: - button "Health status" [ref=e293] [cursor=pointer]: - text: Health status - img [ref=e294] - rowgroup [ref=e296]: - row "e2e-tests-python-vsxrpqdl-ci tssc-app-ci default https://kubernetes.default.svc dbf9d80 11/05/2026, 7:41:52 Synced Healthy" [ref=e297]: - cell "e2e-tests-python-vsxrpqdl-ci" [ref=e298]: - link "e2e-tests-python-vsxrpqdl-ci" [ref=e299] [cursor=pointer]: - /url: https://tssc-gitops-server-tssc-gitops.apps.rosa.kx-9eb103329d.rtum.p3.openshiftapps.com/applications/tssc-gitops/e2e-tests-python-vsxrpqdl-ci - text: e2e-tests-python-vsxrpqdl-ci - button [ref=e300]: - img [ref=e302] - cell "tssc-app-ci" [ref=e304] - cell "default" [ref=e305] - cell "https://kubernetes.default.svc" [ref=e306] - cell "dbf9d80" [ref=e307]: - link "dbf9d80" [ref=e308] [cursor=pointer]: - /url: https://github.com/rhtap-rhdh-qe/e2e-tests-python-vsxrpqdl-gitops/commit/dbf9d80dec8ca8146f6d8720f9acc84486b92898 - cell "11/05/2026, 7:41:52" [ref=e309] - cell "Synced" [ref=e310]: - img [ref=e311] - text: Synced - cell "Healthy" [ref=e313]: - img [ref=e314] - text: Healthy - row "e2e-tests-python-vsxrpqdl-development tssc-app-development default https://kubernetes.default.svc 115b475 11/05/2026, 7:51:31 Synced Healthy" [ref=e316]: - cell "e2e-tests-python-vsxrpqdl-development" [ref=e317]: - link "e2e-tests-python-vsxrpqdl-development" [ref=e318] [cursor=pointer]: - /url: https://tssc-gitops-server-tssc-gitops.apps.rosa.kx-9eb103329d.rtum.p3.openshiftapps.com/applications/tssc-gitops/e2e-tests-python-vsxrpqdl-development - text: e2e-tests-python-vsxrpqdl-development - button [ref=e319]: - img [ref=e321] - cell "tssc-app-development" [ref=e323] - cell "default" [ref=e324] - cell "https://kubernetes.default.svc" [ref=e325] - cell "115b475" [ref=e326]: - link "115b475" [ref=e327] [cursor=pointer]: - /url: https://github.com/rhtap-rhdh-qe/e2e-tests-python-vsxrpqdl-gitops/commit/115b475fa8873af26731ec303c0bdb34eb5835b7 - cell "11/05/2026, 7:51:31" [ref=e328] - cell "Synced" [ref=e329]: - img [ref=e330] - text: Synced - cell "Healthy" [ref=e332]: - img [ref=e333] - text: Healthy - row "e2e-tests-python-vsxrpqdl-prod tssc-app-prod default https://kubernetes.default.svc ec349a7 11/05/2026, 7:55:02 Synced Healthy" [ref=e335]: - cell "e2e-tests-python-vsxrpqdl-prod" [ref=e336]: - link "e2e-tests-python-vsxrpqdl-prod" [ref=e337] [cursor=pointer]: - /url: https://tssc-gitops-server-tssc-gitops.apps.rosa.kx-9eb103329d.rtum.p3.openshiftapps.com/applications/tssc-gitops/e2e-tests-python-vsxrpqdl-prod - text: e2e-tests-python-vsxrpqdl-prod - button [ref=e338]: - img [ref=e340] - cell "tssc-app-prod" [ref=e342] - cell "default" [ref=e343] - cell "https://kubernetes.default.svc" [ref=e344] - cell "ec349a7" [ref=e345]: - link "ec349a7" [ref=e346] [cursor=pointer]: - /url: https://github.com/rhtap-rhdh-qe/e2e-tests-python-vsxrpqdl-gitops/commit/ec349a7f1cfe64bfbfd13009030cb76c3ed16d29 - cell "11/05/2026, 7:55:02" [ref=e347] - cell "Synced" [ref=e348]: - img [ref=e349] - text: Synced - cell "Healthy" [ref=e351]: - img [ref=e352] - text: Healthy - row "e2e-tests-python-vsxrpqdl-stage tssc-app-stage default https://kubernetes.default.svc a0be39d 11/05/2026, 7:53:21 Synced Healthy" [ref=e354]: - cell "e2e-tests-python-vsxrpqdl-stage" [ref=e355]: - link "e2e-tests-python-vsxrpqdl-stage" [ref=e356] [cursor=pointer]: - /url: https://tssc-gitops-server-tssc-gitops.apps.rosa.kx-9eb103329d.rtum.p3.openshiftapps.com/applications/tssc-gitops/e2e-tests-python-vsxrpqdl-stage - text: e2e-tests-python-vsxrpqdl-stage - button [ref=e357]: - img [ref=e359] - cell "tssc-app-stage" [ref=e361] - cell "default" [ref=e362] - cell "https://kubernetes.default.svc" [ref=e363] - cell "a0be39d" [ref=e364]: - link "a0be39d" [ref=e365] [cursor=pointer]: - /url: https://github.com/rhtap-rhdh-qe/e2e-tests-python-vsxrpqdl-gitops/commit/a0be39dac3624002b3455206b49fb816471d1b3a - cell "11/05/2026, 7:53:21" [ref=e366] - cell "Synced" [ref=e367]: - img [ref=e368] - text: Synced - cell "Healthy" [ref=e370]: - img [ref=e371] - text: Healthy - row [ref=e373] - row [ref=e374] - table [ref=e375]: - rowgroup [ref=e376]: - row "5 rows First Page Previous Page 1-4 of 4 Next Page Last Page" [ref=e377]: - cell "5 rows First Page Previous Page 1-4 of 4 Next Page Last Page" [ref=e378]: - generic [ref=e379]: - generic [ref=e380]: - 'button "Rows per page: 5 rows" [ref=e381] [cursor=pointer]': - generic [ref=e382]: 5 rows - textbox: "5" - img - generic [ref=e383]: - generic "First Page" [ref=e384]: - button "First Page" [disabled]: - generic: - img - generic "Previous Page" [ref=e385]: - button "Previous Page" [disabled]: - generic: - img - generic [ref=e386]: 1-4 of 4 - generic "Next Page" [ref=e387]: - button "Next Page" [disabled]: - generic: - img - generic "Last Page" [ref=e388]: - button "Last Page" [disabled]: - generic: - img ``` # 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 | ```