diff --git a/frontend/test/e2e/accessibility.spec.ts b/frontend/test/e2e/accessibility.spec.ts index 0969183..8da4ea0 100644 --- a/frontend/test/e2e/accessibility.spec.ts +++ b/frontend/test/e2e/accessibility.spec.ts @@ -3,6 +3,20 @@ import AxeBuilder from '@axe-core/playwright'; const NODE_ID = 'A'.repeat(64); +const TEST_MAP_STYLE = { + version: 8, + sources: { + openmaptiles: { + type: 'vector', + url: 'https://tiles.openfreemap.org/planet', + }, + }, + glyphs: 'https://tiles.openfreemap.org/fonts/{fontstack}/{range}.pbf', + layers: [ + { id: 'bg', type: 'background', paint: { 'background-color': '#080d14' } }, + ], +}; + const chartStats = { packetsPerHour: [{ hour: '12:00', count: 24 }], packetsPerDay: [{ day: 'Mon', count: 120 }], @@ -155,12 +169,24 @@ async function fulfillApi(route: Route) { return route.fulfill({ json: {} }); } +async function installMapRoutes(page: Page) { + await page.route('https://tiles.openfreemap.org/**', async (route) => { + const pathname = new URL(route.request().url()).pathname; + if (pathname === '/styles/dark' || pathname === '/styles/positron') { + await route.fulfill({ json: TEST_MAP_STYLE }); + return; + } + await route.abort(); + }); + await page.route('**/*basemaps.cartocdn.com/**', (route) => route.abort()); +} + async function installFixtures(page: Page, dismissDisclaimer = true) { await page.addInitScript((dismiss) => { localStorage.setItem('meshcore-cookie-consent-v1', '1'); if (dismiss) localStorage.setItem('meshcore-disclaimer-dismissed', '1'); }, dismissDisclaimer); - await page.route('https://*.basemaps.cartocdn.com/**', (route) => route.abort()); + await installMapRoutes(page); await page.route('**/api/**', fulfillApi); } diff --git a/frontend/test/e2e/dashboard.spec.ts b/frontend/test/e2e/dashboard.spec.ts index 85198af..8f7ad19 100644 --- a/frontend/test/e2e/dashboard.spec.ts +++ b/frontend/test/e2e/dashboard.spec.ts @@ -1,7 +1,41 @@ -import { expect, test } from '@playwright/test'; +import { expect, test, type Page } from '@playwright/test'; import AxeBuilder from '@axe-core/playwright'; +const TEST_MAP_STYLE = { + version: 8, + sources: { + openmaptiles: { + type: 'vector', + url: 'https://tiles.openfreemap.org/planet', + }, + }, + glyphs: 'https://tiles.openfreemap.org/fonts/{fontstack}/{range}.pbf', + layers: [ + { id: 'bg', type: 'background', paint: { 'background-color': '#080d14' } }, + ], +}; + +async function installMapRoutes(page: Page, delayPlanetMetadata = false) { + await page.route('https://tiles.openfreemap.org/**', async (route) => { + const pathname = new URL(route.request().url()).pathname; + if (pathname === '/styles/dark' || pathname === '/styles/positron') { + await route.fulfill({ json: TEST_MAP_STYLE }); + return; + } + if (pathname === '/planet' && delayPlanetMetadata) { + await new Promise((resolve) => setTimeout(resolve, 1_500)); + await route.continue(); + return; + } + await route.abort(); + }); +} + test.beforeEach(async ({ page }) => { + await installMapRoutes(page); + await page.route('**/*basemaps.cartocdn.com/**', () => { + throw new Error('CARTO tiles should not be requested after OpenFreeMap migration'); + }); await page.addInitScript(() => { localStorage.setItem('meshcore-disclaimer-dismissed', '1'); @@ -147,10 +181,8 @@ test('enabled HopReach coverage survives metadata winning the initial map-load r const path = new URL(request.url()).pathname; if (path.startsWith('/rf-coverage/tiles/standard/')) tileRequests.push(path); }); - await page.route('**/vector/carto.streets/v1/tiles.json', async (route) => { - await new Promise((resolve) => setTimeout(resolve, 1_500)); - await route.continue(); - }); + await page.unroute('https://tiles.openfreemap.org/**'); + await installMapRoutes(page, true); await page.goto('/', { waitUntil: 'domcontentloaded' }); diff --git a/frontend/test/e2e/owner.spec.ts b/frontend/test/e2e/owner.spec.ts index 6b4182d..ce9b57f 100644 --- a/frontend/test/e2e/owner.spec.ts +++ b/frontend/test/e2e/owner.spec.ts @@ -1,7 +1,21 @@ -import { expect, test } from '@playwright/test'; +import { expect, test, type Page } from '@playwright/test'; const NODE_ID = 'A'.repeat(64); +const TEST_MAP_STYLE = { + version: 8, + sources: { + openmaptiles: { + type: 'vector', + url: 'https://tiles.openfreemap.org/planet', + }, + }, + glyphs: 'https://tiles.openfreemap.org/fonts/{fontstack}/{range}.pbf', + layers: [ + { id: 'bg', type: 'background', paint: { 'background-color': '#080d14' } }, + ], +}; + const dashboard = { nodes: [{ node_id: NODE_ID, @@ -18,13 +32,25 @@ const dashboard = { }], }; +async function installMapRoutes(page: Page) { + await page.route('https://tiles.openfreemap.org/**', async (route) => { + const pathname = new URL(route.request().url()).pathname; + if (pathname === '/styles/dark' || pathname === '/styles/positron') { + await route.fulfill({ json: TEST_MAP_STYLE }); + return; + } + await route.abort(); + }); + await page.route('**/*basemaps.cartocdn.com/**', (route) => route.abort()); +} + test('session polling does not reset the repeater owner content', async ({ page }) => { let sessionRequests = 0; let liveRequests = 0; let liveRequestLimit: number | null = null; await page.clock.install({ time: new Date('2026-07-16T12:00:00Z') }); - await page.route('https://*.basemaps.cartocdn.com/**', (route) => route.abort()); + await installMapRoutes(page); await page.route('**/api/owner/session', async (route) => { sessionRequests += 1; await route.fulfill({ json: { ok: true, dashboard, mqttUsername: 'alpha-owner' } }); @@ -92,7 +118,7 @@ test('owner map construction remains one across repeated live polls', async ({ p } }).observe(document, { childList: true, subtree: true }); }); - await page.route('https://*.basemaps.cartocdn.com/**', (route) => route.abort()); + await installMapRoutes(page); await page.route('**/api/owner/session', (route) => route.fulfill({ json: { ok: true, dashboard, mqttUsername: 'alpha-owner' }, }));