Compare commits

..

3 Commits

Author SHA1 Message Date
Chris Farhood bd834175d4 fix(e2e): use button role for storage classes sidebar link in rook plugin
The storage classes sidebar entry is a button, not a link. Using getByRole('link')
caused the test to fail with 'element not found'. Switch to getByRole('button')
which matches the actual Headlamp sidebar structure.

Also increased timeout from 10s to 15s for consistency with other waits.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-05 15:35:59 +00:00
Chris Farhood 775904df12 chore: update pnpm lockfile for elliptic override
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-05-05 13:15:04 +00:00
Chris Farhood 02e4fa6ac9 fix: override elliptic to patched version for GHSA-848j-6mx2-7j84 2026-05-05 13:04:47 +00:00
5 changed files with 542 additions and 560 deletions
+2 -3
View File
@@ -16,9 +16,8 @@ concurrency:
jobs:
e2e:
uses: privilegedescalation/.github/.github/workflows/plugin-e2e.yaml@main
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
plugin-name: rook
+7 -8
View File
@@ -24,14 +24,14 @@ test.describe('Rook plugin smoke tests', () => {
await page.waitForLoadState('networkidle');
await expect(page).toHaveURL(/rook-ceph/);
await expect(page.getByRole('heading', { name: /overview/i }).first()).toBeVisible();
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 }).first()).toBeVisible({
await expect(page.getByRole('heading', { name: /overview/i })).toBeVisible({
timeout: 15_000,
});
@@ -42,27 +42,26 @@ test.describe('Rook plugin smoke tests', () => {
test('navigation to storage classes view works', async ({ page }) => {
await page.goto('/c/main/rook-ceph');
const sidebar = page.getByRole('navigation', { name: 'Navigation' });
const sidebar = page.getByRole('navigation', { name: 'Navigation' });
const rookBtn = sidebar.getByRole('button', { name: /rook/i });
await rookBtn.click();
await page.waitForLoadState('networkidle');
const storageClassesLink = sidebar.getByRole('link', { name: /storage classes/i });
await expect(storageClassesLink).toBeVisible({ timeout: 10_000 });
const storageClassesLink = sidebar.getByRole('button', { name: /storage classes/i });
await expect(storageClassesLink).toBeVisible({ timeout: 15_000 });
await storageClassesLink.click();
await page.waitForLoadState('networkidle');
await expect(page).toHaveURL(/rook-ceph\/storage-classes/);
await expect(page.getByRole('heading', { name: /storage class/i }).first()).toBeVisible({ timeout: 15_000 });
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');
await page.waitForSelector('table, [class*="PluginList"], [class*="plugin"]', { timeout: 10_000 }).catch(() => {});
const pluginEntry = page.locator('text=/rook/i').first();
const pluginEntry = page.locator('text=rook').first();
await expect(pluginEntry).toBeVisible({ timeout: 30_000 });
});
});
+2 -1
View File
@@ -50,6 +50,7 @@
"tar": "^7.5.11",
"undici": "^7.24.3",
"vite": ">=6.4.2",
"lodash": ">=4.18.0"
"lodash": ">=4.18.0",
"elliptic": ">=6.6.1"
}
}
+529 -529
View File
File diff suppressed because it is too large Load Diff
+2 -19
View File
@@ -35,17 +35,6 @@ if ! kubectl auth can-i delete configmaps -n "$E2E_NAMESPACE" --quiet 2>/dev/nul
exit 1
fi
echo ""
echo "=== Pre-deployment cluster diagnostics ==="
echo "Nodes:"
kubectl get nodes -o wide 2>&1 || true
echo ""
echo "headlamp-dev namespace state:"
kubectl get ns headlamp-dev -o yaml 2>&1 || true
echo ""
echo "Existing E2E resources in namespace:"
kubectl get all -n "$E2E_NAMESPACE" -l "app.kubernetes.io/instance=$E2E_RELEASE" 2>&1 || true
echo "=== E2E Headlamp Deployment ==="
echo " Image: ghcr.io/headlamp-k8s/headlamp:${HEADLAMP_VERSION}"
echo " Namespace: $E2E_NAMESPACE"
@@ -71,7 +60,7 @@ kubectl delete serviceaccount "${E2E_RELEASE}" -n "$E2E_NAMESPACE" --ignore-not-
echo ""
echo "Deploying Headlamp E2E instance..."
if ! kubectl apply -f - <<EOF
kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
@@ -124,7 +113,7 @@ spec:
port: http
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 6
failureThreshold: 6
livenessProbe:
httpGet:
path: /
@@ -159,12 +148,6 @@ spec:
targetPort: http
protocol: TCP
EOF
then
echo "ERROR: kubectl apply failed. Dumping cluster state..." >&2
kubectl get all -n "$E2E_NAMESPACE" 2>&1 || true
kubectl get events -n "$E2E_NAMESPACE" --sort-by='.lastTimestamp' 2>&1 | tail -30 || true
exit 1
fi
echo "Waiting for rollout..."
kubectl rollout status "deployment/${E2E_RELEASE}" \