Compare commits

..

3 Commits

Author SHA1 Message Date
Chris Farhood 7d56a903c8 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.
2026-05-05 06:50:21 +00:00
Chris Farhood ef7183a2d6 Fix E2E workflow: use pnpm-capable reusable workflow branch
The reusable plugin-e2e.yaml@main lacks pnpm support. Switching to
the PR branch that has pnpm detector, Corepack setup, and pnpm commands.

Will revert to @main once PR #141 merges.

- PRI-619 E2E fix

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-05 06:10:20 +00:00
Chris Farhood 6d48470691 Add E2E test infrastructure for tns-csi plugin
Scaffolded via e2e-scaffold.sh (proactive improvement).
- playwright.config.ts, e2e/auth.setup.ts, e2e/tns-csi.spec.ts
- scripts/deploy-e2e-headlamp.sh, scripts/teardown-e2e-headlamp.sh
- .github/workflows/e2e.yaml uses reusable workflow
- @playwright/test ^1.58.2 devDep

- PRI-639

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-05 05:14:51 +00:00
4 changed files with 59 additions and 7 deletions
+1 -1
View File
@@ -18,6 +18,6 @@ jobs:
e2e:
uses: privilegedescalation/.github/.github/workflows/plugin-e2e.yaml@hugh/add-pnpm-support-plugin-e2e
with:
node-version: "22"
node-version: '22'
headlamp-version: v0.40.1
e2e-namespace: headlamp-dev
+6
View File
@@ -5,3 +5,9 @@ dist/
.env
.env.local
.eslintcache
# E2E
e2e/.auth/
.env.e2e
playwright-report/
test-results/
+14 -6
View File
@@ -1,30 +1,37 @@
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('TNS CSI plugin smoke tests', () => {
test('sidebar contains TNS CSI 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: /tns.csi/i })).toBeVisible();
});
test('TNS CSI sidebar entry navigates to TNS CSI view', 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 entry = sidebar.getByRole('button', { name: /tns.csi/i });
await expect(entry).toBeVisible();
await entry.click();
await page.waitForLoadState('networkidle');
await expect(page).toHaveURL(/tns-csi/);
await expect(page.getByRole('heading', { name: /TNS.CSI/i })).toBeVisible();
await expect(page.getByRole('heading', { name: /tns.csi.*overview/i })).toBeVisible();
});
test('TNS CSI page renders content', async ({ page }) => {
await page.goto('/c/main/tns-csi');
await waitForSidebar(page);
await expect(page.getByRole('heading', { name: /TNS.CSI/i })).toBeVisible({
await expect(page.getByRole('heading', { name: /tns.csi.*overview/i })).toBeVisible({
timeout: 15_000,
});
@@ -35,6 +42,7 @@ test.describe('TNS CSI plugin smoke tests', () => {
test('plugin settings page shows TNS CSI plugin entry', async ({ page }) => {
await page.goto('/settings/plugins');
await page.waitForLoadState('networkidle');
const pluginEntry = page.locator('text=/tns.csi/i').first();
await expect(pluginEntry).toBeVisible({ timeout: 30_000 });
+38
View File
@@ -17,6 +17,9 @@ importers:
'@mui/material':
specifier: ^5.15.14
version: 5.18.0(@emotion/react@11.14.0(@types/react@18.3.28)(react@18.3.1))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@18.3.28)(react@18.3.1))(@types/react@18.3.28)(react@18.3.1))(@types/react@18.3.28)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
'@playwright/test':
specifier: ^1.58.2
version: 1.59.1
'@testing-library/jest-dom':
specifier: ^6.4.8
version: 6.9.1
@@ -988,6 +991,11 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
'@playwright/test@1.59.1':
resolution: {integrity: sha512-PG6q63nQg5c9rIi4/Z5lR5IVF7yU5MqmKaPOe0HSc0O2cX1fPi96sUQu5j7eo4gKCkB2AnNGoWt7y4/Xx3Kcqg==}
engines: {node: '>=18'}
hasBin: true
'@popperjs/core@2.11.8':
resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==}
@@ -3049,6 +3057,11 @@ packages:
fs.realpath@1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
fsevents@2.3.2:
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@@ -4185,6 +4198,16 @@ packages:
resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==}
engines: {node: '>=10'}
playwright-core@1.59.1:
resolution: {integrity: sha512-HBV/RJg81z5BiiZ9yPzIiClYV/QMsDCKUyogwH9p3MCP6IYjUFu/MActgYAvK0oWyV9NlwM3GLBjADyWgydVyg==}
engines: {node: '>=18'}
hasBin: true
playwright@1.59.1:
resolution: {integrity: sha512-C8oWjPR3F81yljW9o5OxcWzfh6avkVwDD2VYdwIGqTkl+OGFISgypqzfu7dOe4QNLL2aqcWBmI3PMtLIK233lw==}
engines: {node: '>=18'}
hasBin: true
possible-typed-array-names@1.1.0:
resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==}
engines: {node: '>= 0.4'}
@@ -6522,6 +6545,10 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
'@playwright/test@1.59.1':
dependencies:
playwright: 1.59.1
'@popperjs/core@2.11.8': {}
'@reduxjs/toolkit@2.11.2(react-redux@9.2.0(@types/react@18.3.28)(react@18.3.1)(redux@5.0.1))(react@18.3.1)':
@@ -9033,6 +9060,9 @@ snapshots:
fs.realpath@1.0.0: {}
fsevents@2.3.2:
optional: true
fsevents@2.3.3:
optional: true
@@ -10413,6 +10443,14 @@ snapshots:
dependencies:
find-up: 5.0.0
playwright-core@1.59.1: {}
playwright@1.59.1:
dependencies:
playwright-core: 1.59.1
optionalDependencies:
fsevents: 2.3.2
possible-typed-array-names@1.1.0: {}
postcss-modules-extract-imports@3.1.0(postcss@8.5.10):