import AxeBuilder from '@axe-core/playwright'; import { expect, test } from '@playwright/test'; const now = new Date().toISOString(); test('mobile incident command mode is prioritized, bounded and accessible', async ({ page }, testInfo) => { test.skip(testInfo.project.name !== 'mobile-chromium', 'Mobile incident mode uses the supported 390x844 viewport.'); await page.route('**/api/v1/**', async (route) => { const path = new URL(route.request().url()).pathname; const body = path === '/api/v1/system/status' ? { version: '1', generatedAt: now, overallState: 'degraded', components: [], backup: { state: 'disabled', reason: 'not_configured' }, sourceLag: [], } : path === '/api/v1/incidents/incident-1' ? { incident: { id: 'incident-1', correlationKey: 'cachepool', title: 'Cachepool bijna vol', summary: 'Cachepool is 92% gebruikt en groeit sneller dan verwacht.', severity: 'critical', status: 'open', startedAt: now, correlationMethod: 'temporal-window', confidence: .84, revision: 2, updatedAt: now, ownerUserId: '', alerts: [ { alertId: 'alert-1', rationale: 'Capaciteitsdrempel van 90% overschreden', confidence: .84, correlationMethod: 'temporal-window', manual: false, createdAt: now }, ], notes: [{ id: 'note-1', incidentId: 'incident-1', author: 'Pulse', body: 'Mover is niet actief.', createdAt: now }], }, } : {}; await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(body) }); }); await page.goto('/incidents/incident-1'); await expect(page.getByRole('heading', { level: 1, name: 'Cachepool bijna vol' })).toBeVisible(); await expect(page.locator('.incident-command-strip')).toContainText('Kritiek'); await expect(page.locator('.incident-command-strip')).toContainText('84%'); await expect(page.locator('.incident-timeline')).toContainText('Capaciteitsdrempel van 90% overschreden'); expect(await page.evaluate(() => document.documentElement.scrollWidth)).toBe(390); const targets = await page.locator('button, .mobile-navigation a, .mobile-more summary').evaluateAll((items) => items.filter((item) => { const style = getComputedStyle(item); return style.display !== 'none' && style.visibility !== 'hidden'; }).map((item) => item.getBoundingClientRect().height)); expect(targets.every((height) => height >= 44)).toBe(true); const axe = await new AxeBuilder({ page }).analyze(); expect(axe.violations.filter((item) => item.impact === 'critical' || item.impact === 'serious')).toEqual([]); if (process.env.PULSE_CAPTURE_VISUALS) await page.screenshot({ path: '../../artifacts/evidence/M14-04/mobile-incident-command.png', fullPage: true }); });