Commit graph

26 commits

Author SHA1 Message Date
Ullrich Schäfer
f94020a93a
Block unmocked external requests in E2E tests
Surface net for the class of bug we hit in #282 — a POI test silently
relied on a live Overpass server for months because its `page.route`
mock was targeting a URL the browser no longer hit directly. CI stayed
green on coincidence (real OSM data happened to satisfy the "any
marker renders" assertion) until upstream behaviour drifted.

Add a shared Playwright fixture (e2e/fixtures/test.ts) that installs a
catch-all `page.route("**", ...)` before each test. Requests to
localhost + known tile CDNs pass through via `route.continue()`;
anything else is aborted and accumulated. At test teardown, a non-empty
blocked list throws, failing the test with the offending URLs and a
pointer to the fixture.

All seven e2e *.test.ts files updated to import test/expect (+ types)
from ./fixtures/test.

Full suite passes with this fixture in place (50/50 at --workers=2;
catch-all never fires, meaning no test currently relies on an
unallowlisted external service).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 22:42:29 +02:00
Ullrich Schäfer
9c9d53d3bd
Fix POI E2E test: mock the planner proxy, not upstream Overpass
The test was added in 0ff04aa (Apr 11), back when the browser called
overpass-api.de directly. When a4df5a4 (Apr 18) moved POI queries
behind the planner's `/api/overpass` proxy, the test's
`page.route("**/api/interpreter", ...)` mock became dead code —
Playwright can only intercept browser traffic, and the browser now
only sees `/api/overpass`. The real upstream got hit and didn't
return a drinking_water node at exactly 52.52, 13.405, so zero
markers rendered and the test failed.

Mock `/api/overpass` instead. Response body shape is unchanged
(the proxy is transparent).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 21:48:21 +02:00
Ullrich Schäfer
b7fe68359c
Fix flaky overnight E2E test: increase timeouts
The "Waypoints (3)" assertion timed out at 5s in CI. The waypoints
load from URL params but the sidebar needs BRouter mock response +
Yjs sync before updating. Increase to 15s to match other assertions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 02:27:59 +02:00
Ullrich Schäfer
97184f4b82
Fix E2E: use 'residential' instead of 'cycleway' in legend test
'cycleway' now matches both the highway legend and the Cycleway
dropdown option, causing a strict mode violation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:13:44 +02:00
Ullrich Schäfer
4bcd6137de
Fix E2E select locator and add speed limit color mode
E2E fixes:
- Color mode select locator now uses option[value='highway'] filter
  instead of fragile page.locator("select").last()

Speed limit color mode:
- Extract maxspeed tags from BRouter tiledesc (with forward/backward
  direction handling following brouter-web's pattern)
- Color route and chart by speed limit: green ≤30, yellow ≤50,
  orange ≤70, red ≤100, dark red 100+ km/h
- Legend with speed thresholds, hover shows "X km/h"
- i18n: EN "Speed Limit" / DE "Tempolimit"
- Mock fixtures include maxspeed data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:13:43 +02:00
Ullrich Schäfer
1e2f6beded
Add road type color mode to route visualization
Extract highway=* tags from BRouter tiledesc messages alongside surface
data and add a new "Road Type" color mode that colors the route polyline
and elevation chart by OSM highway classification (cycleway, residential,
path, etc.). Includes color palette, legend, hover labels, i18n (EN+DE),
unit tests for tag extraction, and E2E tests.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 11:13:43 +02:00
Ullrich Schäfer
9752eb77e8
Fix E2E: color mode toggle test needs a route for elevation chart
The color mode selector moved from the header to the elevation chart,
which only renders when a route exists. Updated test to use mocked
BRouter with waypoints.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 03:21:40 +02:00
Ullrich Schäfer
86f5d082d2
Fix E2E: match CodeMirror placeholder by visible text
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 03:07:45 +02:00
Ullrich Schäfer
378dc41c05
Fix E2E: notes tab test uses CM placeholder instead of textarea
CodeMirror renders placeholders as .cm-placeholder elements, not
HTML placeholder attributes. Updated the sidebar tabs test to look
for the CodeMirror content area instead.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 03:05:55 +02:00
Ullrich Schäfer
3ff4245f6f
Fix E2E: mock BRouter for GPX day breaks test
The test dropped GPX with far-apart waypoints (Berlin/Dessau/Erfurt)
which timed out waiting for BRouter on CI. Switched to nearby Berlin
waypoints and added mockBRouter for instant deterministic routing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 02:23:35 +02:00
Ullrich Schäfer
be36a5f650
Change default routing profile to fastbike, move hiking to end
The app is primarily for cycling. Default profile is now "Cycling (fast)"
instead of "Hiking". Profile order: fastbike, safety, shortest, car,
trekking.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 02:17:46 +02:00
Ullrich Schäfer
0ff04aaec7
Add E2E tests for hillshading overlay and POI markers
- Hillshading: mock tile endpoint, enable via DOM evaluate, verify
  tile requests fired
- POI markers: mock Overpass API response, zoom to threshold, enable
  category, verify marker rendered in marker pane

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 02:14:56 +02:00
Ullrich Schäfer
e6c68fb71b
Add BRouter mock for deterministic E2E tests
- brouter-mock.ts: Canned route responses for 2 and 3 waypoint sessions,
  plus latLngToPixel helper for pixel-precise map interactions
- planner.test.ts: Route split, map zoom, and overnight tests now use
  mockBRouter() for instant deterministic responses instead of real
  BRouter — fixes all 3 flaky tests
- Used .first() for sidebar km locator to avoid strict mode violations
  when both header summary and stats footer match

All 38 E2E tests pass in 9.7s (was 34s+ with real BRouter).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 01:07:39 +02:00
Ullrich Schäfer
f90571fc2c
Fix overnight E2E test: use nearby waypoints, scope locators to sidebar
The test used waypoints 300km apart causing BRouter timeouts. Switched
to nearby Berlin waypoints for fast route computation. Scoped all
locators to the sidebar to avoid strict mode violations from map
elements matching the same text.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 01:02:02 +02:00
Ullrich Schäfer
b6bca0229b
Fix E2E strict mode violations in multi-day tests
- "km" locator matched both header summary and stats footer — narrowed
  to match "km ·" pattern unique to the header
- "Day 1" locator matched both map label pill and sidebar header —
  scoped to sidebar with page.locator("aside")

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:59:03 +02:00
Ullrich Schäfer
2970a460f8
Add E2E tests, Journal map coloring, and remaining unit tests
- planner.test.ts: E2E test for overnight toggle → day breakdown in sidebar,
  and GPX import with overnight metadata
- integration.test.ts: E2E test for isDayBreak preservation through GPX import
- RouteMapThumbnail: Per-day route coloring with alternating colors
- overnight.test.ts: Y.Doc-aware tests for isOvernight/setOvernight
- daybreaks-extraction.test.ts: GPX → dayBreaks index extraction tests

All 28 tasks complete.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 00:14:08 +02:00
Ullrich Schäfer
a9f8ee61f0
Add GPX file import to planner + archive change
Two import entry points:
- Home page: "Import GPX" button next to "Start Planning"
- In-session: drag-and-drop GPX onto the map (with confirmation)

Parses GPX client-side, extracts waypoints (Douglas-Peucker) and
no-go areas from extensions. Non-GPX files show error toast.

Also:
- Fix spec drift: non-GPX drop now shows error toast (was silent)
- Add E2E tests for import button, invalid GPX, and session creation
- Archive gpx-import-planner change, sync specs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 17:31:44 +01:00
copilot-swe-agent[bot]
1b9683752f
Fit map to route bounds when opening a route in the planner
Agent-Logs-Url: https://github.com/trails-cool/trails/sessions/558ccff8-ed5d-432a-a5d3-aca49c0e531e

Co-authored-by: stigi <13815+stigi@users.noreply.github.com>
2026-03-29 12:31:40 +00:00
Ullrich Schäfer
b080a15fb1
Add route interactions: click-to-split, drag-to-reshape, colored route rendering
- Enrich BRouter response with per-point 3D coordinates and segment boundary
  tracking (EnrichedRoute interface)
- ColoredRoute component: plain, elevation gradient (green→yellow→red), and
  surface color modes with invisible wide polyline for click targeting
- Click-to-split: click on route polyline inserts waypoint at nearest point,
  mapped to correct segment via boundary indices
- MidpointHandles: draggable CircleMarkers at route segment midpoints for
  reshaping, hidden below zoom 12, opaque on hover
- Color mode toggle (select) synced via Yjs routeData
- i18n keys for color mode labels (en + de)
- Unit tests for segment boundary tracking (13 tests)
- E2E tests for enriched route response and color mode toggle

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 21:15:55 +01:00
Ullrich Schäfer
0a8dd0b766
Add transactional emails (SMTP) and planner features (no-go areas, notes, crash recovery)
Transactional emails:
- Add nodemailer SMTP email module with dev-mode console logging
- Magic link template and welcome template with HTML + plain text
- Wire sendMagicLink into login flow, sendWelcome into registration
- Update privacy page and deploy docs for SMTP configuration

Planner features:
- No-go areas: draw polygons on map (leaflet-geoman), synced via Yjs,
  passed to BRouter as nogos parameter, route recomputes on change
- Session notes: collaborative Y.Text textarea in sidebar tab
- Crash recovery: periodic localStorage save of Yjs state, restore on reconnect
- Rate limit session creation (10/IP/hour) in /new route

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 01:00:42 +01:00
Ullrich Schäfer
bb4f193405 Add app navigation bars to Journal and Planner
Journal gets a nav bar in root.tsx with conditional links: Routes and
Activities for authenticated users, Sign In and Register for guests.
Active route is highlighted via useLocation(). User menu shows username
linking to profile and a logout button.

Planner SessionView header title becomes a home link back to /.

Adds i18n keys (en + de) for all nav labels. Updates E2E tests to use
scoped nav selectors now that links appear in both nav bar and page body.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 03:12:27 +00:00
Ullrich Schäfer
4ddaad8c5f
Add planner landing page with features and CTAs
Replace blank home page with a landing page explaining collaborative
route planning. Hero section with "Start Planning" CTA, 5 feature cards
(collaboration, routing, elevation, GPX, no account), secondary CTA
linking to Journal, and footer with privacy/source/attribution links.

All strings in en + de via i18n.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 04:03:06 +01:00
Ullrich Schäfer
b71117e4ca
Add PostgreSQL + BRouter to CI E2E tests
CI now runs the full stack for E2E tests:
- PostgreSQL as a service container + schema push via drizzle
- BRouter JAR + Berlin segment (E10_N50) with caching
- Both cached across runs (BRouter JAR + segment)

Removed all skip/workaround logic from tests — all 20 E2E tests
now run in CI with real services.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:58:01 +01:00
Ullrich Schäfer
e86ff5a8a3
Fix E2E tests in CI: skip DB-dependent tests when no PostgreSQL
Planner session tests and integration tests now check for DB
availability before running. Skip gracefully in CI where no
PostgreSQL or BRouter is available.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:33:03 +01:00
Ullrich Schäfer
79e6ae6ea2
Add E2E and integration tests (Group 11)
Journal tests (6):
- Home page, auth pages render correctly
- No password fields on register/login
- Protected routes redirect to login

Planner tests (9):
- Session creation via API
- Map loads in session
- Yjs WebSocket connects (Connected status)
- Profile selector, export button, waypoint sidebar
- Session with initial GPX waypoints
- Expired session returns 404

Integration tests (5):
- GPX import returns parsed waypoints
- BRouter computes Berlin routes
- Routes pass through all waypoints (segment by segment)
- Rate limit headers present
- Rejects < 2 waypoints

Total: 32 unit tests + 20 E2E tests, all passing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 23:20:04 +01:00
Ullrich Schäfer
40b9c425a0
Add testing strategy: Vitest for unit tests, Playwright for E2E
- Vitest: unit tests for packages, components, and app logic (jsdom env,
  @testing-library/react, co-located test files)
- Playwright: E2E browser tests per app (journal.test.ts, planner.test.ts),
  auto-starts dev servers, scoped via testMatch
- Sample unit test for types package
- Smoke E2E tests for both apps
- Updated CLAUDE.md with test commands and strategy

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 12:36:09 +01:00