Public source validation / validate (push) Failing after 3m8s
95 lines
5.5 KiB
TypeScript
95 lines
5.5 KiB
TypeScript
import AxeBuilder from '@axe-core/playwright';
|
|
import { expect, test } from '@playwright/test';
|
|
import path from 'node:path';
|
|
|
|
const alerts = Array.from({ length: 25 }, (_, index) => ({
|
|
id: `alert-${String(index + 1).padStart(2, '0')}`,
|
|
state: index === 1 ? 'acknowledged' : 'firing',
|
|
retainedState: 'firing',
|
|
ruleName: `Melding ${String(index + 1).padStart(2, '0')}`,
|
|
severity: index % 5 === 0 ? 'critical' : 'attention',
|
|
entityName: index % 2 === 0 ? 'Tower' : 'Database',
|
|
reason: 'threshold_exceeded',
|
|
revision: index + 1,
|
|
updatedAt: new Date(Date.UTC(2026, 7, 21, 12, 0, 0) - index * 60_000).toISOString(),
|
|
}));
|
|
|
|
test('alertwerkruimte prioriteert operatie en opent configuratie doelgericht', async ({ page }, testInfo) => {
|
|
test.skip(testInfo.project.name === 'wallboard-chromium', 'De alertwerkruimte gebruikt de desktop-, tablet- en mobiele shell.');
|
|
let operationHeaders: Record<string, string> | undefined;
|
|
await page.route('**/api/v1/**', async (route) => {
|
|
const request = route.request();
|
|
const pathname = new URL(request.url()).pathname;
|
|
if (pathname === '/api/v1/system/status') {
|
|
await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ version: 'test', generatedAt: new Date().toISOString(), overallState: 'healthy', components: [], backup: { state: 'disabled', reason: 'not_configured' }, sourceLag: [] }) });
|
|
return;
|
|
}
|
|
if (pathname === '/api/v1/alert-rules') {
|
|
await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ items: [] }) });
|
|
return;
|
|
}
|
|
if (pathname === '/api/v1/metrics/catalog') {
|
|
await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ metrics: [{ semanticName: 'host.cpu.utilization', unit: 'percent', defaultAggregation: 'avg' }] }) });
|
|
return;
|
|
}
|
|
if (pathname === '/api/v1/alerts' && request.method() === 'GET') {
|
|
await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ items: alerts }) });
|
|
return;
|
|
}
|
|
if (pathname.startsWith('/api/v1/alerts/') && request.method() === 'POST') {
|
|
operationHeaders = request.headers();
|
|
await route.fulfill({ contentType: 'application/json', body: '{}' });
|
|
return;
|
|
}
|
|
if (pathname === '/api/v1/alert-silences' || pathname === '/api/v1/maintenance-windows') {
|
|
await route.fulfill({ contentType: 'application/json', body: JSON.stringify({ items: [] }) });
|
|
return;
|
|
}
|
|
await route.fulfill({ status: 404, contentType: 'application/problem+json', body: '{}' });
|
|
});
|
|
|
|
await page.goto('/alerts');
|
|
await expect(page.getByRole('heading', { name: 'Meldingen en incidenten' })).toBeVisible();
|
|
await expect(page.getByRole('button', { name: /Actief 25/ })).toHaveAttribute('aria-pressed', 'true');
|
|
await expect(page.getByRole('button', { name: /Kritiek actief 5/ })).toBeVisible();
|
|
const rows = page.locator('.alert-operation-list-items > li');
|
|
await expect(rows).toHaveCount(20);
|
|
await expect(rows.first()).toContainText('Kritiek');
|
|
await expect(page.getByRole('heading', { name: 'Geregistreerde regels' })).toHaveCount(0);
|
|
|
|
const acknowledge = page.getByRole('button', { name: 'Erkennen' }).first();
|
|
page.once('dialog', (dialog) => dialog.dismiss());
|
|
await acknowledge.click();
|
|
expect(operationHeaders).toBeUndefined();
|
|
page.once('dialog', (dialog) => dialog.accept());
|
|
await acknowledge.click();
|
|
await expect.poll(() => operationHeaders?.['if-match']).toBe('1');
|
|
expect(operationHeaders?.['idempotency-key']).toBeTruthy();
|
|
|
|
await page.getByRole('button', { name: /Alertregels Detectie en drempels/ }).click();
|
|
await expect(page).toHaveURL(/section=rules/);
|
|
await expect(page.getByRole('heading', { name: 'Geregistreerde regels' })).toBeVisible();
|
|
await expect(page.getByRole('heading', { name: 'Actieve en recente meldingen' })).toHaveCount(0);
|
|
await page.getByRole('button', { name: /Stiltes en onderhoud Tijdelijke uitzonderingen/ }).click();
|
|
await expect(page).toHaveURL(/section=controls/);
|
|
await expect(page.getByRole('heading', { name: 'Tijdelijke onderdrukking en onderhoud' })).toBeVisible();
|
|
await expect(page.getByRole('heading', { name: 'Geregistreerde regels' })).toHaveCount(0);
|
|
await page.reload();
|
|
await expect(page.getByRole('heading', { name: 'Tijdelijke onderdrukking en onderhoud' })).toBeVisible();
|
|
await expect(page.getByRole('button', { name: /Stiltes en onderhoud Tijdelijke uitzonderingen/ })).toHaveAttribute('aria-current', 'page');
|
|
await page.getByRole('button', { name: /Actieve meldingen Prioriteiten en erkenning/ }).click();
|
|
await expect(page).not.toHaveURL(/section=/);
|
|
|
|
expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth + 1)).toBe(true);
|
|
expect(await page.evaluate(() => document.documentElement.scrollHeight / window.innerHeight)).toBeLessThan(10);
|
|
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 heights = await page.locator('.alert-section-nav button').evaluateAll((buttons) => buttons.map((button) => button.getBoundingClientRect().height));
|
|
expect(heights.every((height) => height >= 44)).toBe(true);
|
|
}
|
|
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', `alerts-${testInfo.project.name}.png`), fullPage: true });
|
|
}
|
|
});
|