// @ts-check // Tests: M4, M7, M8 — MapLibre GL renders on the two live map surfaces (home + trip page). // The standalone /map, /dailies mini-map and /stories mini-map surfaces were retired // (see docs/working/plans/2026-07-04-standalone-page-cleanup.md); their coverage now // lives on the trip and home maps, both driven by MapUtils.initEntryMap(). // Requires demo data: run `make demo-load` before this suite. const { test, expect } = require('@playwright/test'); // ── M4: Home map renders MapLibre canvas ───────────────────────────────────── test('M4: Home page map renders MapLibre GL canvas without JS errors', async ({ page }) => { const errors = []; page.on('pageerror', e => errors.push(e.message)); await page.goto('/'); await expect(page.locator('#home-map canvas.maplibregl-canvas')).toBeVisible({ timeout: 10000 }); expect(errors, 'No JS errors on home page').toHaveLength(0); }); // ── M7: Clicking a trip-page map marker adds is-highlighted to the entry card ── test('M7: clicking map marker briefly highlights the corresponding entry card', async ({ page }) => { await page.goto('/trips/italy-2026-demo'); // Wait for map canvas and at least one marker await expect(page.locator('#trip-map canvas.maplibregl-canvas')).toBeVisible({ timeout: 10000 }); await expect(page.locator('.maplibregl-marker').first()).toBeVisible({ timeout: 15000 }); // Wait for tripMap to finish animating (fitBounds animation completes) await page.waitForFunction(function () { return window.tripMap && !window.tripMap.isMoving() && !window.tripMap.isZooming() && !window.tripMap.isRotating(); }, { timeout: 15000 }); // Click the first marker (force bypasses overlap when start/end share the same location) await page.locator('.maplibregl-marker').first().click({ force: true }); // Within 500ms of click + delay, one journal-post should have is-highlighted await expect(page.locator('.journal-post.is-highlighted')).toBeVisible({ timeout: 1500 }); }); // ── M8: Home map has GPX journey source on active trip ──────────────────────── test('M8: home map has a journey source after GPX settles (active trip)', async ({ page }) => { // Requires travelling: true in user/config/site.yaml. // Requires GPX files attached to the active trip (italy-2026-demo has 7). const errors = []; page.on('pageerror', e => errors.push(e.message)); await page.goto('/'); await expect(page.locator('#home-map canvas.maplibregl-canvas')).toBeVisible({ timeout: 10000 }); await expect(page.locator('#home-map .maplibregl-marker').first()).toBeVisible({ timeout: 15000 }); await page.waitForFunction(function () { return window.homeMap && (window.homeMap.getSource('home-journey') !== undefined || window.homeMap.getSource('home-gpx-0') !== undefined); }, { timeout: 20000 }); const hasSource = await page.evaluate(function () { return !!(window.homeMap.getSource('home-journey') || window.homeMap.getSource('home-gpx-0')); }); expect(hasSource, 'Home map has a journey or GPX source').toBe(true); expect(errors, 'No JS errors on home page').toHaveLength(0); });