Phase-1 fallout: delete tests for deleted pages, re-point moved-behavior tests to the trip/home page where the content now lives. - maps.spec: keep M4/M7/M8 (home+trip maps); drop M1-3,5,6,9-11 (/map, /dailies & /stories mini-maps) - map-ux: re-point MUX4/5 sort toggle to #trip-sort-toggle on trip page - nav: N1->trip page, N2->home, drop N3 (/stats) + N5 (obsolete skip) - dailies: T1->trip page; T2->trip page with oldest-first assertion; fix T3-T6 stale entry-detail selectors (.entry-* -> .journal-post-*, pre-existing failures from an earlier entry redesign) - stories: S1/S5 -> trip feed story cards ([data-type=story]) - gpx-journey: load MapUtils from the trip page instead of /map - a11y: A4 photo strips -> trip page; drop AX3 (covered by AX2) - post/helpers: verify posted entry on the trip page (ACTIVE_TRIP_URL) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
91 lines
4.0 KiB
JavaScript
91 lines
4.0 KiB
JavaScript
// @ts-check
|
||
// Tests: G1–G5 — buildJourneySegments algorithm correctness
|
||
// These tests load the italy-2026-demo trip page (which has GPX + the map bundle) 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-2026-demo');
|
||
await expect(page.locator('#trip-map 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, { connectMode: 'intelligent_gpx' }, []).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], { connectMode: 'intelligent_gpx' }, [track]).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], { connectMode: 'intelligent_gpx' }, [track]).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], { connectMode: 'intelligent_gpx' }, [trackA, trackB]).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], { connectMode: 'intelligent_gpx' }, [track]);
|
||
return segs.length;
|
||
});
|
||
|
||
expect(count).toBe(1); // one segment: [e2 → e3]
|
||
});
|