import { test, expect, type Page } from '@playwright/test'; // Terrain is disabled in e2e (?terrain=0) for deterministic headless rendering; // the terrain code path stays toggleable on by default in the app. const APP_URL = '/?terrain=0'; async function waitForAirportCount(page: Page): Promise { const countEl = page.getByTestId('airport-count'); await expect.poll(async () => { const text = (await countEl.textContent()) ?? ''; const m = text.match(/(\d+)/); return m ? parseInt(m[1], 10) : -1; }).toBeGreaterThan(0); const text = (await countEl.textContent()) ?? ''; return parseInt(text.match(/(\d+)/)?.[1] ?? '0', 10); } test('page loads with the map and EU airport count', async ({ page }) => { await page.goto(APP_URL); await expect(page.getByTestId('map')).toBeVisible(); const count = await waitForAirportCount(page); expect(count).toBeGreaterThan(0); }); test('clicking an airport marker opens a popup with name and ICAO', async ({ page }) => { await page.goto(APP_URL); await waitForAirportCount(page); // Wait until the map instance exists and airport circles are actually rendered // (the GeoJSON source is parsed in a worker, so features arrive after addSource). await expect.poll(async () => page.evaluate( () => (window as any).__flightMap?.queryRenderedFeatures(undefined, { layers: ['airports-circles'], })?.length ?? 0, ), { timeout: 15_000 }, ).toBeGreaterThan(0); // Project EKRN (Bornholm) to screen space via the dev hook, then click it. // Bornholm is used because its nearest other airport is ~0.8° away (~19 px at the // initial zoom), so its marker cannot be overlapped by a neighbouring circle. const pt = await page.evaluate(() => { const map = (window as any).__flightMap; const p = map.project([14.7596, 55.063301]); const rect = map.getContainer().getBoundingClientRect(); return { x: rect.left + p.x, y: rect.top + p.y }; }); await page.mouse.click(pt.x, pt.y); const popup = page.getByTestId('airport-popup'); await expect(popup).toBeVisible(); await expect(popup).toContainText('Bornholm Airport'); await expect(popup).toContainText('EKRN'); });