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.
This commit is contained in:
2026-05-05 06:50:21 +00:00
committed by Gandalf the Greybeard [agent]
parent af07e46930
commit 14f4b4d17d
+12 -4
View File
@@ -1,28 +1,35 @@
import { test, expect } from '@playwright/test'; 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('kube-vip plugin smoke tests', () => { test.describe('kube-vip plugin smoke tests', () => {
test('sidebar contains kube-vip entry', async ({ page }) => { test('sidebar contains kube-vip entry', async ({ page }) => {
await page.goto('/'); await page.goto('/');
const sidebar = page.getByRole('navigation', { name: 'Navigation' }); const sidebar = await waitForSidebar(page);
await expect(sidebar).toBeVisible({ timeout: 15_000 });
await expect(sidebar.getByRole('button', { name: /kube.vip/i })).toBeVisible(); await expect(sidebar.getByRole('button', { name: /kube.vip/i })).toBeVisible();
}); });
test('kube-vip sidebar entry navigates to kube-vip view', async ({ page }) => { test('kube-vip sidebar entry navigates to kube-vip view', async ({ page }) => {
await page.goto('/'); await page.goto('/');
const sidebar = page.getByRole('navigation', { name: 'Navigation' }); const sidebar = await waitForSidebar(page);
await expect(sidebar).toBeVisible({ timeout: 15_000 });
const entry = sidebar.getByRole('button', { name: /kube.vip/i }); const entry = sidebar.getByRole('button', { name: /kube.vip/i });
await expect(entry).toBeVisible(); await expect(entry).toBeVisible();
await entry.click(); await entry.click();
await page.waitForLoadState('networkidle');
await expect(page).toHaveURL(/kube-vip/); await expect(page).toHaveURL(/kube-vip/);
await expect(page.getByRole('heading', { name: /kube.vip/i })).toBeVisible(); await expect(page.getByRole('heading', { name: /kube.vip/i })).toBeVisible();
}); });
test('kube-vip page renders content', async ({ page }) => { test('kube-vip page renders content', async ({ page }) => {
await page.goto('/c/main/kube-vip'); await page.goto('/c/main/kube-vip');
await waitForSidebar(page);
await expect(page.getByRole('heading', { name: /kube.vip/i })).toBeVisible({ await expect(page.getByRole('heading', { name: /kube.vip/i })).toBeVisible({
timeout: 15_000, timeout: 15_000,
@@ -35,6 +42,7 @@ test.describe('kube-vip plugin smoke tests', () => {
test('plugin settings page shows kube-vip plugin entry', async ({ page }) => { test('plugin settings page shows kube-vip plugin entry', async ({ page }) => {
await page.goto('/settings/plugins'); await page.goto('/settings/plugins');
await page.waitForLoadState('networkidle');
const pluginEntry = page.locator('text=/kube.vip/i').first(); const pluginEntry = page.locator('text=/kube.vip/i').first();
await expect(pluginEntry).toBeVisible({ timeout: 30_000 }); await expect(pluginEntry).toBeVisible({ timeout: 30_000 });