// @ts-check // Tests: G1–G4 — buildJourneySegments algorithm correctness // These tests load the italy-2025 map page (which has GPX) to get MapUtils in scope, // then call the functions with synthetic data via page.evaluate. // Requires demo data: run `make demo-load` before this suite. const { test, expect } = require('@playwright/test'); async function getMapUtils(page) { await page.goto('/trips/italy-2025/map'); await expect(page.locator('canvas.maplibregl-canvas')).toBeVisible({ timeout: 10000 }); } // G1: No GPX → all pairs connected in one segment test('G1: all markers connected when no GPX files present', async ({ page }) => { await getMapUtils(page); var count = await page.evaluate(function () { var entries = [ { lat: '43.0', lng: '11.0', force_connect: false }, { lat: '44.0', lng: '12.0', force_connect: false }, { lat: '45.0', lng: '13.0', force_connect: false } ]; return MapUtils.buildJourneySegments(entries, [], 10).length; }); expect(count).toBe(1); }); // G2: Same GPX file covers both markers → connector suppressed (0 segments) test('G2: connector suppressed when same GPX file covers both markers', async ({ page }) => { await getMapUtils(page); var count = await page.evaluate(function () { var e1 = { lat: '43.000', lng: '11.000', force_connect: false }; var e2 = { lat: '43.010', lng: '11.010', force_connect: false }; // Trackpoints covering both (stored as [lat, lng]) var track = [[43.000, 11.000], [43.005, 11.005], [43.010, 11.010]]; return MapUtils.buildJourneySegments([e1, e2], [track], 10).length; }); expect(count).toBe(0); }); // G3: force_connect overrides GPX suppression test('G3: force_connect keeps connector even when GPX covers both markers', async ({ page }) => { await getMapUtils(page); var count = await page.evaluate(function () { var e1 = { lat: '43.000', lng: '11.000', force_connect: false }; var e2 = { lat: '43.010', lng: '11.010', force_connect: true }; var track = [[43.000, 11.000], [43.005, 11.005], [43.010, 11.010]]; return MapUtils.buildJourneySegments([e1, e2], [track], 10).length; }); expect(count).toBe(1); }); // G4: Markers near DIFFERENT GPX files → connector kept test('G4: connector kept when markers are near different GPX files', async ({ page }) => { await getMapUtils(page); var count = await page.evaluate(function () { var e1 = { lat: '43.000', lng: '11.000', force_connect: false }; var e2 = { lat: '45.000', lng: '13.000', force_connect: false }; // Two separate files — each only covers one marker var trackA = [[43.000, 11.000], [43.005, 11.005]]; // near e1 only var trackB = [[45.000, 13.000], [45.005, 13.005]]; // near e2 only return MapUtils.buildJourneySegments([e1, e2], [trackA, trackB], 10).length; }); expect(count).toBe(1); }); // G5: First pair suppressed, second pair kept → one segment [e2, e3] test('G5: suppressed first pair leaves one segment from e2 to e3', async ({ page }) => { await getMapUtils(page); var count = await page.evaluate(function () { // e1→e2: covered by track → suppressed; e1 is orphaned (< 2 pts, not pushed) // e2→e3: not covered → connector kept → segment [e2, e3] var e1 = { lat: '43.000', lng: '11.000', force_connect: false }; var e2 = { lat: '43.010', lng: '11.010', force_connect: false }; var e3 = { lat: '45.000', lng: '13.000', force_connect: false }; var track = [[43.000, 11.000], [43.005, 11.005], [43.010, 11.010]]; // covers e1 and e2 only var segs = MapUtils.buildJourneySegments([e1, e2, e3], [track], 10); return segs.length; }); expect(count).toBe(1); // one segment: [e2 → e3] });