Public source validation / validate (push) Failing after 3m8s
86 lines
4.9 KiB
TypeScript
86 lines
4.9 KiB
TypeScript
import AxeBuilder from '@axe-core/playwright';
|
|
import { expect, test } from '@playwright/test';
|
|
import path from 'node:path';
|
|
|
|
const systemStatus = {
|
|
version: '1.3.0',
|
|
release: { version: '1.3.0', commit: 'abc1234', builtAt: '2026-08-21T12:00:00Z', migrationVersion: '0024' },
|
|
generatedAt: new Date().toISOString(),
|
|
overallState: 'healthy',
|
|
components: [],
|
|
backup: { state: 'healthy', reason: 'backup_verified', ageSeconds: 30 * 60 * 60, verifiedAt: '2026-08-20T06:00:00Z' },
|
|
sourceLag: [{ sourceId: 'unraid', state: 'healthy', reason: 'fresh', ageSeconds: 5 }],
|
|
};
|
|
|
|
const onboarding = {
|
|
state: { completed: true, step: 'completed', dashboardChoice: 'default', rulesChoice: 'default', dashboardId: 'overview', rulesReady: true },
|
|
capabilities: [
|
|
{ id: 'auth', state: 'ready', detail: 'Aanmelding geconfigureerd.' },
|
|
{ id: 'database', state: 'ready', detail: 'Database beschikbaar.' },
|
|
{ id: 'prometheus', state: 'ready', detail: 'Meetgegevens beschikbaar.' },
|
|
{ id: 'unraid', state: 'ready', detail: 'Unraid-bron beschikbaar.' },
|
|
],
|
|
resume: false,
|
|
};
|
|
|
|
test('beheerhub, afgeronde onboarding en backupouderdom blijven taakgericht en waarheidsgetrouw', async ({ page }, testInfo) => {
|
|
test.skip(testInfo.project.name === 'wallboard-chromium', 'Beheerflows gebruiken de desktop-, tablet- en mobiele shell.');
|
|
await page.route('**/api/v1/**', async (route) => {
|
|
const pathname = new URL(route.request().url()).pathname;
|
|
if (pathname === '/api/v1/system/status') {
|
|
if (route.request().method() === 'POST') {
|
|
await route.fulfill({ status: 403, contentType: 'application/problem+json', body: '{}' });
|
|
return;
|
|
}
|
|
await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ ...systemStatus, generatedAt: new Date().toISOString() }) });
|
|
return;
|
|
}
|
|
if (pathname === '/api/v1/onboarding') {
|
|
await route.fulfill({ contentType: 'application/json', body: JSON.stringify(onboarding) });
|
|
return;
|
|
}
|
|
await route.fulfill({ status: 404, contentType: 'application/problem+json', body: '{}' });
|
|
});
|
|
|
|
await page.goto('/settings');
|
|
await expect(page.getByRole('heading', { name: 'Pulse configureren' })).toBeVisible();
|
|
const hub = page.getByRole('region', { name: 'Beheerfuncties' });
|
|
await expect(hub.getByRole('link')).toHaveCount(6);
|
|
await expect(hub.getByRole('link', { name: /Systeemstatus en backup/ })).toHaveAttribute('href', '/status');
|
|
await expect(hub.getByRole('link', { name: /Eerste configuratie/ })).toHaveAttribute('href', '/onboarding');
|
|
await expect(hub.getByRole('link', { name: /Alertregels/ })).toHaveAttribute('href', '/alerts?section=rules');
|
|
await expect(hub.getByRole('link', { name: /Stiltes en onderhoud/ })).toHaveAttribute('href', '/alerts?section=controls');
|
|
await expect(hub.getByText('Backupactie: beheerder')).toBeVisible();
|
|
await expect(hub.getByText('Wijzigen: operator')).toBeVisible();
|
|
if (process.env.PULSE_CAPTURE_VISUALS && (testInfo.project.name === 'desktop-chromium' || testInfo.project.name === 'mobile-chromium')) {
|
|
await page.screenshot({ path: path.resolve('../../artifacts/evidence/M14-03', `settings-${testInfo.project.name}.png`), fullPage: true });
|
|
}
|
|
|
|
await hub.getByRole('link', { name: /Systeemstatus en backup/ }).click();
|
|
const backup = page.getByRole('article').filter({ has: page.getByText('Backupstatus', { exact: true }) });
|
|
await expect(page.getByRole('heading', { name: 'Pulse-systeemstatus' })).toBeVisible();
|
|
await expect(backup.locator('.status-badge')).toContainText('Aandacht');
|
|
await expect(backup.getByText(/backup is verlopen/i)).toBeVisible();
|
|
await expect(backup.getByText(/1 dag geleden/)).toBeVisible();
|
|
await expect(backup.getByText(/ouder dan 24 uur/)).toBeVisible();
|
|
await backup.getByRole('button', { name: 'Maak geverifieerde backup' }).click();
|
|
await expect(backup.getByRole('alert')).toContainText('Alleen beheerders');
|
|
|
|
await page.goto('/settings');
|
|
await page.getByRole('region', { name: 'Beheerfuncties' }).locator('a[href="/onboarding"]').click();
|
|
await expect(page.getByRole('heading', { name: 'Pulse is geconfigureerd' })).toBeVisible();
|
|
await expect(page.getByRole('radio')).toHaveCount(0);
|
|
await page.getByRole('button', { name: 'Herconfiguratie openen' }).click();
|
|
await expect(page.getByRole('radio')).toHaveCount(4);
|
|
await page.getByRole('button', { name: 'Annuleren' }).click();
|
|
await expect(page.getByRole('radio')).toHaveCount(0);
|
|
|
|
expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth + 1)).toBe(true);
|
|
const axe = await new AxeBuilder({ page }).analyze();
|
|
expect(axe.violations.filter((item) => item.impact === 'serious' || item.impact === 'critical')).toEqual([]);
|
|
if (testInfo.project.name === 'mobile-chromium') {
|
|
const linkHeights = await page.locator('.settings-hub-card a').evaluateAll((links) => links.map((link) => link.getBoundingClientRect().height));
|
|
expect(linkHeights.every((height) => height >= 44)).toBe(true);
|
|
}
|
|
});
|