Playwright E2E + acceptance video — the whole public journey on one host, and the old app-host paths redirecting
Type: test · Executor: coding_agent · Repo: motir-core · ONE PR. The story's end-to-end walk, and — because the deliverable is a surface a person watches — its acceptance receipt.
The flow, which is the story's verification recipe automated
- Load the public site's root — the landing renders, with its three doors.
- Click Explore in the header —
/explorerenders, same host, same chrome, with real project cards. - Open a topic page from the footer's crawl links; go back.
- Open Docs, then a legal document from the footer — each stays on the public host.
- Fetch
/robots.txtand/sitemap.xmlfrom the public host — one of each, allow + the surfaces this host serves. - Request each moved path on the application host — a permanent redirect to the public one, query preserved.
- Request a public project page on the application host — 200, not a redirect (the story boundary).
- Take a door to the application host and arrive at the sign-in surface with its parameter intact.
States, not just the happy path
- Empty —
/explorewith no public projects: the empty state, not a crash. - Loading — the square's ranked tabs and "load more", waited on by their authoritative signals rather than a timeout.
- Error —
explore/error.tsxrenders when the directory read fails. - Terminal / destructive — the redirect is permanent: assert the status code, not merely the final URL, because a 302 and a 308 look identical after the browser follows them.
⚠️ Host simulation, and the scaffold check that governs it
Both hosts must be reachable from one Playwright run. Read the lane's own configuration before writing a line in it: this repository's E2E lanes carry a base URL and a webServer, and a host branch resolved from a request header is drivable per test, while one resolved from a process-wide server-side environment read is NOT — it would have no per-test override, the assertion would pass on unfixed code, and the failure mode is a permanently green guard rather than a red one. Name the exact mechanism in the spec's own comment, and assert the page is on the host it claims before asserting anything about it, so nothing can pass vacuously.
The acceptance video
The story's deliverable is user-observable, so this card records and publishes the walk to the story as its acceptance receipt. It is PACED for a human — a reviewer watches it to accept the story — so the spec waits on real signals and does not race. There is no duration cap; the only machine check is a floor, and a clip too fast to watch fails the publish.
Acceptance criteria
- One spec covering steps 1–8, green in CI, waiting on authoritative signals throughout (no arbitrary timeouts).
- Each of the four state cases above is asserted.
- Step 6 asserts the redirect status code and the destination; step 7 asserts a 200 on
/p/*and that no redirect occurred. - The spec asserts the host of each page it is on before making claims about that page.
- The acceptance video is recorded, paced for a human, and published to the story; the publish is green.
- The spec adds no flake: it is run repeatedly in the lane before the card closes, and any environmental failure is triaged and logged rather than re-run blind.
Context refs
motir-core/tests/e2e/— the lane configuration, the fixtures, and the acceptance-video patternmotir-core/docs/decisions/acceptance-video.md— the receipt's contract and its floormotir-core/app/(public)/explore/error.tsx— the error state this drivesmotir-core/CLAUDE.md— the E2E discipline (authoritative waits)- The root-route, robots/sitemap and redirect cards this is
blocked_by— the behaviour it walks
Comments (0)
No comments yet — be the first to weigh in.