import { expect, test, type Page } from '@playwright/test'; const zeroTimestamp = '0001-01-01T00:00:00Z'; async function mockSourceStatusData(page: Page): Promise { await page.route('**/api/v1/**', async (route) => { const pathname = new URL(route.request().url()).pathname; const source = { id: 'unraid', state: 'healthy', freshness: 'stale', observedAt: zeroTimestamp, reason: 'source_stale' }; const body = pathname === '/api/v1/host' ? { source, identity: { name: 'Tower', version: '7.2.0' }, uptimeSeconds: 3600, cpu: { totalPercent: 12, perCore: [12], iowaitPercent: 0 }, load: { one: 0.1, five: 0.2, fifteen: 0.3 }, memory: { totalBytes: 1024, availableBytes: 512, usedBytes: 512, utilizationPercent: 50, swapTotalBytes: 0, swapUsedBytes: 0, swapUtilizationPercent: 0 }, filesystems: [], network: [], time: { synchronized: true, offsetSeconds: 0, state: 'healthy' }, status: { state: 'unknown', reasons: [{ code: 'filesystem_root_not_configured', message: 'technical' }] }, observedAt: zeroTimestamp, receivedAt: zeroTimestamp, warnings: ['filesystem_root_not_configured'], } : pathname === '/api/v1/array' ? { source, state: 'unknown', parity: { present: false, state: 'unknown', errors: 0 }, members: [], } : pathname === '/api/v1/disks' ? { source: { ...source, id: 'unraid-disks', reason: 'filesystem_root_not_configured' }, total: 0, disks: [], } : pathname === '/api/v1/pools' ? { source: { ...source, id: 'unraid-pools' }, total: 0, pools: [], } : pathname === '/api/v1/applications' ? { source, total: 0, applications: [], } : pathname === '/api/v1/system/status' ? { version: '1', generatedAt: zeroTimestamp, overallState: 'unknown', components: [], backup: { state: 'disabled', reason: 'not_configured' }, sourceLag: [], } : {}; await route.fulfill({ status: 200, contentType: 'application/json', body: JSON.stringify(body) }); }); } test.beforeEach(async ({ page }) => mockSourceStatusData(page)); test('source status is human-readable and technically progressive on core routes', async ({ page }) => { for (const route of ['/host', '/storage', '/applications']) { await page.goto(route); await expect(page.getByRole('heading', { level: 1 })).toBeVisible(); await expect(page.getByText('Nooit ontvangen').first()).toBeVisible(); await expect(page.getByText(/laatste meting is verouderd/i).first()).toBeVisible(); const visibleText = await page.locator('body').innerText(); expect(visibleText).not.toContain('source_stale'); expect(visibleText).not.toContain('filesystem_root_not_configured'); expect(visibleText).not.toMatch(/1 jan(?:uari)? 1/i); expect(await page.evaluate(() => document.documentElement.scrollWidth <= window.innerWidth + 1)).toBe(true); } await page.goto('/host'); const technical = page.locator('.source-status-technical').first(); await expect(technical).not.toHaveAttribute('open'); await technical.getByText('Technische broninformatie').click(); await expect(technical.getByText('source_stale')).toBeVisible(); });