trails/e2e
Ullrich Schäfer a05c8e87a1
e2e: close the interact-before-hydration race (cold-start flake)
Diagnosis (reproduced by looping cold-server runs): the recurring
"cold start" failures in the auth/follow specs were a hydration race,
not a Vite dep-reload (the server.warmup config already handles that —
no reload events in the logs). FollowButton is an onClick button, and
Playwright considers it actionable (visible + enabled) before React
attaches the handler on a freshly-navigated page. A click in that
window is dropped (or triggers a native form submit), so the expected
state change never happens — e.g. notifications.test.ts:59 clicked
"Request to follow" with no hydration wait and the button never
flipped to "Requested".

The existing waitForHydration guard was applied per-interaction and so
was easy to forget (test 1 had it, test 3 didn't). Fix it at the
navigation instead:

- add gotoHydrated(page, url) = goto + waitForHydration, documented as
  the default for "navigate then interact with a React control"
- use it before every FollowButton interaction in notifications +
  social
- consolidate the setProfileVisibility helper (copy-pasted in three
  specs, two missing the hydration wait) into e2e/helpers/profile.ts,
  built on gotoHydrated

Validation against a fresh Postgres, cold servers: notifications 0/10
failures (was the proven flaker); notifications+social+explore 0/5
(55 tests); planner unaffected (25/25).

Note: two other "cold-start"-attributed flakes are NOT this race and
are out of scope here — planner map-load latency (mitigated by warmup
+ CI retries) and the /explore directory assertion (a local artifact
of the scratch DB accumulating >20 public users; CI's fresh DB stays
under the page size, so it doesn't bite there).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 14:09:00 +02:00
..
federation feat(journal): two-instance federation harness + trails↔trails Accept fix (§11) 2026-06-07 13:36:35 +02:00
fixtures e2e: close the interact-before-hydration race (cold-start flake) 2026-06-11 14:09:00 +02:00
helpers e2e: close the interact-before-hydration race (cold-start flake) 2026-06-11 14:09:00 +02:00
auth.test.ts e2e: shared auth + journal seed helpers; flag unregistered specs 2026-06-10 07:31:51 +02:00
demo-bot.test.ts Fix e2e fallout from default-private profile_visibility 2026-04-25 23:46:56 +02:00
explore.test.ts e2e: close the interact-before-hydration race (cold-start flake) 2026-06-11 14:09:00 +02:00
integration.test.ts e2e: shared auth + journal seed helpers; flag unregistered specs 2026-06-10 07:31:51 +02:00
journal-planner-save.test.ts e2e: shared auth + journal seed helpers; flag unregistered specs 2026-06-10 07:31:51 +02:00
journal.test.ts Rebuild the Journal home around a public feed and flagship marketing 2026-04-24 20:00:23 +02:00
komoot-import.test.ts e2e: shared auth + journal seed helpers; flag unregistered specs 2026-06-10 07:31:51 +02:00
notifications.test.ts e2e: close the interact-before-hydration race (cold-start flake) 2026-06-11 14:09:00 +02:00
planner-coloring.test.ts test(e2e/planner-coloring): bump canvas timeout 10s→20s 2026-05-25 23:44:53 +02:00
planner-multiday.test.ts Split planner E2E tests into focused feature files 2026-05-22 21:58:10 +02:00
planner-overlays.test.ts Split planner E2E tests into focused feature files 2026-05-22 21:58:10 +02:00
planner-routing.test.ts Split planner E2E tests into focused feature files 2026-05-22 21:58:10 +02:00
planner-session.test.ts Split planner E2E tests into focused feature files 2026-05-22 21:58:10 +02:00
public-content.test.ts e2e: shared auth + journal seed helpers; flag unregistered specs 2026-06-10 07:31:51 +02:00
settings.test.ts e2e: register and repair the settings/explore/social specs 2026-06-11 08:32:18 +02:00
social.test.ts e2e: close the interact-before-hydration race (cold-start flake) 2026-06-11 14:09:00 +02:00