const { test, expect } = require('@playwright/test'); async function waitForMaps(page) { await expect(page.locator('#mapApprox')).toBeVisible(); await expect(page.locator('#mapTrue')).toBeVisible(); await expect.poll(async () => page.locator('.leaflet-marker-icon').count(), { timeout: 10000 }).toBeGreaterThan(0); } test.describe('kort7 dual map demo', () => { test('loads both maps and renders vehicles', async ({ page }) => { await page.goto('/kort7.html'); await waitForMaps(page); await expect(page.locator('#status')).toContainText('Simuleret tid'); await expect(page.locator('#runtimeWarning')).toBeHidden(); await expect.poll(async () => page.locator('.leaflet-tile').count(), { timeout: 10000 }).toBeGreaterThan(0); }); test('shows different map titles for approximate and precise views', async ({ page }) => { await page.goto('/kort7.html'); await expect(page.locator('.map-title').first()).toContainText('Tilnærmet position'); await expect(page.locator('.map-title').nth(1)).toContainText('Præcis position'); }); test('clicking off-map indicator updates detail panel', async ({ page }) => { await page.goto('/kort7.html'); await page.getByRole('button', { name: 'Pause' }).click(); const indicator = page.locator('#offmapIndicatorsApprox .offmap-indicator').filter({ hasText: 'Bil 9' }); await expect(indicator).toBeVisible(); await indicator.click(); const selection = page.locator('#selectedVehicleInfo'); await expect(selection).toContainText('Bil 9'); await expect(selection).toContainText('Tilnærmet position'); await expect(selection).toContainText('hjørneindikator'); await expect(indicator).toHaveClass(/active/); }); test('renders uncertainty circles only on approximate map', async ({ page }) => { await page.goto('/kort7.html'); await waitForMaps(page); await expect.poll(async () => { return await page.locator('#mapApprox path').evaluateAll((nodes) => nodes.filter((node) => { const strokeDasharray = node.getAttribute('stroke-dasharray'); return strokeDasharray && strokeDasharray.length > 0; }).length ); }).toBeGreaterThan(0); await expect.poll(async () => { return await page.locator('#mapTrue path').evaluateAll((nodes) => nodes.filter((node) => { const strokeDasharray = node.getAttribute('stroke-dasharray'); return strokeDasharray && strokeDasharray.length > 0; }).length ); }).toBe(0); }); test('shows off-map indicators on both views', async ({ page }) => { await page.goto('/kort7.html'); await expect(page.locator('#offmapIndicatorsApprox .offmap-indicator')).toHaveCount(2); await expect(page.locator('#offmapIndicatorsTrue .offmap-indicator')).toHaveCount(2); await expect(page.locator('#offmapIndicatorsApprox')).toContainText('Bil 9'); await expect(page.locator('#offmapIndicatorsTrue')).toContainText('Bil 10'); }); test('approximate and precise positions differ for the same vehicle', async ({ page }) => { await page.goto('/kort7.html'); await page.getByRole('button', { name: 'Pause' }).click(); const selection = page.locator('#selectedVehicleInfo'); const approxIndicator = page.locator('#offmapIndicatorsApprox .offmap-indicator').filter({ hasText: 'Bil 9' }); await approxIndicator.click(); const approxText = await selection.textContent(); const trueIndicator = page.locator('#offmapIndicatorsTrue .offmap-indicator').filter({ hasText: 'Bil 9' }); await trueIndicator.click(); const trueText = await selection.textContent(); expect(approxText).not.toEqual(trueText); expect(approxText).toContain('Tilnærmet position'); expect(trueText).toContain('Præcis position'); }); test('playback updates simulation status over time', async ({ page }) => { await page.goto('/kort7.html'); const status = page.locator('#status'); const initialText = await status.textContent(); const initialMatch = initialText.match(/Simuleret tid: ([\d.]+) s/); expect(initialMatch).not.toBeNull(); const initialTime = Number(initialMatch[1]); await page.waitForTimeout(1800); const text = await status.textContent(); const match = text.match(/Simuleret tid: ([\d.]+) s/); expect(match).not.toBeNull(); expect(Number(match[1])).toBeGreaterThan(initialTime + 0.5); }); });