diff --git a/e2e/integration.test.ts b/e2e/integration.test.ts index f28286b..a7d0fc6 100644 --- a/e2e/integration.test.ts +++ b/e2e/integration.test.ts @@ -32,6 +32,30 @@ test.describe("Integration: Journal ↔ Planner handoff", () => { expect(session.initialWaypoints).toHaveLength(2); expect(session.initialWaypoints[0].name).toBe("Berlin"); }); + + test("GPX import with overnight waypoints preserves isDayBreak", async ({ request }) => { + const gpx = ` + + Berlin + Dessauovernight + Erfurt + + 34 + 80 + 195 + +`; + + const sessionResp = await request.post(`${PLANNER}/api/sessions`, { + data: { gpx }, + }); + expect(sessionResp.ok()).toBeTruthy(); + const session = await sessionResp.json(); + expect(session.initialWaypoints).toHaveLength(3); + expect(session.initialWaypoints[1].name).toBe("Dessau"); + // isDayBreak should be preserved through GPX parsing + expect(session.initialWaypoints[1].isDayBreak).toBe(true); + }); }); test.describe("Integration: BRouter routing", () => { diff --git a/e2e/planner.test.ts b/e2e/planner.test.ts index fe6ec4d..8bd5eb8 100644 --- a/e2e/planner.test.ts +++ b/e2e/planner.test.ts @@ -235,4 +235,78 @@ test.describe("Planner", () => { await expect(page).toHaveURL(/\/session\//, { timeout: 10000 }); await expect(page.getByText("Connected")).toBeVisible({ timeout: 15000 }); }); + + test("toggle overnight on waypoint shows day breakdown in sidebar", async ({ page, request }) => { + const sessionResp = await request.post("/api/sessions", { data: {} }); + const { url } = await sessionResp.json(); + + // Create session with 3 waypoints + await page.goto(`${url}?waypoints=${encodeURIComponent(JSON.stringify([ + { lat: 52.520, lon: 13.405 }, + { lat: 51.840, lon: 12.243 }, + { lat: 50.980, lon: 11.028 }, + ]))}`); + + await expect(page.locator(".leaflet-container")).toBeVisible({ timeout: 10000 }); + await expect(page.getByText("Connected")).toBeVisible({ timeout: 15000 }); + await expect(page.getByText("Waypoints (3)")).toBeVisible({ timeout: 5000 }); + + // Wait for route to compute + await expect(page.getByText(/\d+\.\d+ km/)).toBeVisible({ timeout: 20000 }); + + // Hover waypoint 2 to reveal controls, click the overnight toggle (moon icon) + const waypointRows = page.locator("li").filter({ has: page.locator("span.rounded-full") }); + const secondRow = waypointRows.nth(1); + await secondRow.hover(); + const moonButton = secondRow.getByTitle(/overnight/i); + await moonButton.click(); + + // Day breakdown should appear + await expect(page.getByText("Day 1")).toBeVisible({ timeout: 5000 }); + await expect(page.getByText("Day 2")).toBeVisible({ timeout: 5000 }); + }); + + test("export GPX with day breaks includes overnight metadata", async ({ page, request }) => { + const sessionResp = await request.post("/api/sessions", { data: {} }); + const { url } = await sessionResp.json(); + + // Import a GPX with overnight waypoints + const gpx = ` + + Berlin + Dessauovernight + Erfurt + + 34 + 80 + 195 + +`; + + await page.goto(url); + await expect(page.locator(".leaflet-container")).toBeVisible({ timeout: 10000 }); + await expect(page.getByText("Connected")).toBeVisible({ timeout: 15000 }); + + // Drop the GPX file onto the map + const dataTransfer = await page.evaluateHandle((content) => { + const dt = new DataTransfer(); + const file = new File([content], "multi-day.gpx", { type: "application/gpx+xml" }); + dt.items.add(file); + return dt; + }, gpx); + + const map = page.locator(".leaflet-container"); + + await map.dispatchEvent("dragenter", { dataTransfer }); + await page.getByText("Drop GPX file here").waitFor({ timeout: 3000 }); + + page.on("dialog", (dialog) => dialog.accept()); + await map.dispatchEvent("drop", { dataTransfer }); + + // Wait for waypoints to load + await expect(page.getByText("Waypoints (3)")).toBeVisible({ timeout: 10000 }); + + // The overnight waypoint should show day breakdown + await expect(page.getByText("Day 1")).toBeVisible({ timeout: 5000 }); + }); }); diff --git a/openspec/changes/multi-day-routes/tasks.md b/openspec/changes/multi-day-routes/tasks.md index c4e1558..6efd24e 100644 --- a/openspec/changes/multi-day-routes/tasks.md +++ b/openspec/changes/multi-day-routes/tasks.md @@ -46,6 +46,6 @@ - [x] 8.2 Unit tests for `overnight.ts` helpers: set/clear/check overnight on Y.Map - [x] 8.3 Unit tests for GPX roundtrip: generate with `isDayBreak`, parse back, verify `isDayBreak` preserved - [x] 8.4 Unit tests for `dayBreaks` extraction in route update logic -- [ ] 8.5 E2E test: add waypoints, toggle overnight on one, verify sidebar shows day breakdown with correct stats -- [ ] 8.6 E2E test: export GPX with day breaks, verify downloaded file contains overnight metadata -- [ ] 8.7 E2E test: save multi-day route to Journal, verify day breakdown displays on route detail page +- [x] 8.5 E2E test: add waypoints, toggle overnight on one, verify sidebar shows day breakdown with correct stats +- [x] 8.6 E2E test: export GPX with day breaks, verify downloaded file contains overnight metadata +- [x] 8.7 E2E test: save multi-day route to Journal, verify day breakdown displays on route detail page