# 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 >> Verify CD >> verify ArgoCD deployment lifecycle - Location: tests/ui/component.test.ts:130:5 # Error details ``` TimeoutError: Step timeout of 30000ms exceeded. ``` ``` Error: expect(locator).toBeVisible() failed Locator: getByRole('heading', { name: 'Deployment Summary' }) Expected: visible Error: element(s) not found Call log: - Expect "toBeVisible" with timeout 60000ms - waiting for getByRole('heading', { name: 'Deployment Summary' }) ``` # 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-dbafwepq" [level=1] [ref=e119]: - generic [ref=e121]: backend-tests-go-dbafwepq - 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, Locator } from '@playwright/test'; 2 | import { ArgocdPO, getArgocdCardTestId, getArgocdLinkTestId } from '../../page-objects/argocdPo'; 3 | 4 | /** 5 | * ArgoCD Plugin for verifying Deployment Lifecycle UI 6 | */ 7 | export class ArgoCDPlugin { 8 | private componentName: string; 9 | 10 | constructor(componentName: string) { 11 | this.componentName = componentName; 12 | } 13 | 14 | /** 15 | * Verifies the Deployment Lifecycle page heading 16 | */ 17 | public async checkPageHeading(page: Page): Promise { 18 | const heading = page.getByRole('heading', { name: ArgocdPO.deploymentLifecycleHeading }); 19 | await expect(heading).toBeVisible(); 20 | } 21 | 22 | /** 23 | * Verifies the Deployment Summary table on the overview page 24 | */ 25 | public async checkDeploymentSummary(page: Page): Promise { 26 | const heading = page.getByRole('heading', { name: ArgocdPO.deploymentSummaryHeading }); > 27 | await expect(heading).toBeVisible(); | ^ Error: expect(locator).toBeVisible() failed 28 | 29 | const table = page.locator('table').filter({ has: page.getByText(ArgocdPO.argocdAppColumn) }); 30 | await expect(table).toBeVisible(); 31 | 32 | for (const column of ArgocdPO.deploymentSummaryColumns) { 33 | await expect(table.getByText(column, { exact: true })).toBeVisible(); 34 | } 35 | 36 | const rows = table.locator('tbody tr').filter({ has: page.locator('td') }); 37 | expect(await rows.count()).toBeGreaterThan(0); 38 | 39 | await this.checkDeploymentSummaryRows(table); 40 | } 41 | 42 | /** 43 | * Verifies that an environment card is displayed with correct information 44 | */ 45 | public async checkEnvironmentCard(page: Page, environment: string): Promise { 46 | const cardTestId = getArgocdCardTestId(this.componentName, environment); 47 | const card = page.getByTestId(cardTestId); 48 | 49 | await expect(card).toBeVisible(); 50 | await expect(card).toContainText(`${this.componentName}-${environment}`); 51 | 52 | await this.checkExternalLink(card, environment); 53 | await this.checkSyncStatus(card); 54 | await this.checkHealthStatus(card); 55 | await this.checkCardContent(card); 56 | } 57 | 58 | /** 59 | * Verifies the drawer content after clicking a card 60 | */ 61 | public async checkDrawerContent(page: Page, environment: string): Promise { 62 | const drawer = await this.openCardDrawer(page, environment); 63 | 64 | await this.checkExternalLink(drawer, environment); 65 | await this.checkSyncStatus(drawer); 66 | await this.checkHealthStatus(drawer); 67 | await this.checkDrawerInfoContent(drawer); 68 | await this.checkResourcesTable(drawer); 69 | 70 | await this.closeDrawer(page); 71 | } 72 | 73 | /** 74 | * Verifies rows in the Deployment Summary table 75 | */ 76 | private async checkDeploymentSummaryRows(table: Locator): Promise { 77 | const rows = table.locator('tbody tr').filter({ hasText: this.componentName }); 78 | 79 | for (const env of ArgocdPO.environments) { 80 | const appName = `${this.componentName}-${env}`; 81 | const row = rows.filter({ hasText: appName }).first(); 82 | 83 | const appLink = row.getByRole('link').first(); 84 | await expect(appLink).toContainText(appName); 85 | await expect(appLink).toHaveAttribute('href'); 86 | 87 | const revisionLink = row.getByRole('link', { name: ArgocdPO.commitShaPattern }); 88 | await expect(revisionLink).toHaveAttribute('href'); 89 | 90 | await expect(row.getByTestId(ArgocdPO.syncedIconTestId)).toBeVisible(); 91 | await expect(row.getByTestId(ArgocdPO.healthyIconTestId)).toBeVisible(); 92 | } 93 | } 94 | 95 | /** 96 | * Verifies the ArgoCD external link is present 97 | */ 98 | private async checkExternalLink(container: Locator, environment: string): Promise { 99 | const linkTestId = getArgocdLinkTestId(this.componentName, environment); 100 | const link = container.getByTestId(linkTestId); 101 | await expect(link).toBeVisible(); 102 | await expect(link).toHaveAttribute('href'); 103 | } 104 | 105 | /** 106 | * Verifies sync status chip is displayed correctly 107 | */ 108 | private async checkSyncStatus(container: Locator): Promise { 109 | const syncChip = container.getByTestId(ArgocdPO.syncStatusChipTestId); 110 | await expect(syncChip).toBeVisible(); 111 | await expect(container.getByTestId(ArgocdPO.syncedIconTestId).first()).toBeVisible(); 112 | await expect(syncChip).toContainText(ArgocdPO.syncedLabel); 113 | } 114 | 115 | /** 116 | * Verifies health status chip is displayed correctly 117 | */ 118 | private async checkHealthStatus(container: Locator): Promise { 119 | const healthChip = container.getByTestId(ArgocdPO.healthStatusChipTestId); 120 | await expect(healthChip).toBeVisible(); 121 | await expect(container.getByTestId(ArgocdPO.healthyIconTestId).first()).toBeVisible(); 122 | await expect(healthChip).toContainText(ArgocdPO.healthyLabel); 123 | } 124 | 125 | /** 126 | * Verifies commit information is displayed correctly 127 | */ ```