From 8d2ec06e4103351312bed845cdd3f85a395b4614 Mon Sep 17 00:00:00 2001 From: Chris Farhood Date: Tue, 5 May 2026 06:50:21 +0000 Subject: [PATCH] fix(e2e): add waitForSidebar helper and networkidle waits for reliability Add waitForSidebar helper function with explicit sidebar visibility wait and networkidle state to ensure page is fully loaded before assertions. This addresses flaky E2E tests where elements were not consistently found due to timing issues during page transitions. --- e2e/rook.spec.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/e2e/rook.spec.ts b/e2e/rook.spec.ts index 081d599..bb6f15d 100644 --- a/e2e/rook.spec.ts +++ b/e2e/rook.spec.ts @@ -1,28 +1,35 @@ import { test, expect } from '@playwright/test'; +async function waitForSidebar(page: import('@playwright/test').Page) { + const sidebar = page.getByRole('navigation', { name: 'Navigation' }); + await expect(sidebar).toBeVisible({ timeout: 15_000 }); + await page.waitForLoadState('networkidle'); + return sidebar; +} + test.describe('Rook plugin smoke tests', () => { test('sidebar contains Rook entry', async ({ page }) => { await page.goto('/'); - const sidebar = page.getByRole('navigation', { name: 'Navigation' }); - await expect(sidebar).toBeVisible({ timeout: 15_000 }); + const sidebar = await waitForSidebar(page); await expect(sidebar.getByRole('button', { name: /rook/i })).toBeVisible(); }); test('Rook sidebar entry navigates to overview', async ({ page }) => { await page.goto('/'); - const sidebar = page.getByRole('navigation', { name: 'Navigation' }); - await expect(sidebar).toBeVisible({ timeout: 15_000 }); + const sidebar = await waitForSidebar(page); const rookEntry = sidebar.getByRole('button', { name: /rook/i }); await expect(rookEntry).toBeVisible(); await rookEntry.click(); - await expect(page).toHaveURL(/\/rook-ceph/); + await page.waitForLoadState('networkidle'); + await expect(page).toHaveURL(/rook-ceph/); await expect(page.getByRole('heading', { name: /overview/i })).toBeVisible(); }); test('overview page renders content', async ({ page }) => { await page.goto('/c/main/rook-ceph'); + await waitForSidebar(page); await expect(page.getByRole('heading', { name: /overview/i })).toBeVisible({ timeout: 15_000, @@ -41,12 +48,14 @@ test.describe('Rook plugin smoke tests', () => { await expect(storageClassesLink).toBeVisible({ timeout: 10_000 }); await storageClassesLink.click(); - await expect(page).toHaveURL(/\/rook-ceph\/storage-classes/); + await page.waitForLoadState('networkidle'); + await expect(page).toHaveURL(/rook-ceph\/storage-classes/); await expect(page.getByRole('heading', { name: /storage class/i })).toBeVisible({ timeout: 15_000 }); }); test('plugin settings page shows rook plugin entry', async ({ page }) => { await page.goto('/settings/plugins'); + await page.waitForLoadState('networkidle'); const pluginEntry = page.locator('text=rook').first(); await expect(pluginEntry).toBeVisible({ timeout: 30_000 });