MotirBuilding in public
MOTIR · moooon
onMotir
You’re viewing a public project. Anyone can view it — no account needed. Sign in to submit, upvote, or comment on requests.View-only — you can’t edit work items
MOTIR-3886

Playwright E2E + acceptance video — the whole public journey on one host, and the old app-host paths redirecting

Blocked
Description

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

  1. Load the public site's root — the landing renders, with its three doors.
  2. Click Explore in the header — /explore renders, same host, same chrome, with real project cards.
  3. Open a topic page from the footer's crawl links; go back.
  4. Open Docs, then a legal document from the footer — each stays on the public host.
  5. Fetch /robots.txt and /sitemap.xml from the public host — one of each, allow + the surfaces this host serves.
  6. Request each moved path on the application host — a permanent redirect to the public one, query preserved.
  7. Request a public project page on the application host — 200, not a redirect (the story boundary).
  8. 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/explore with 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.
  • Errorexplore/error.tsx renders 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 pattern
  • motir-core/docs/decisions/acceptance-video.md — the receipt's contract and its floor
  • motir-core/app/(public)/explore/error.tsx — the error state this drives
  • motir-core/CLAUDE.md — the E2E discipline (authoritative waits)
  • The root-route, robots/sitemap and redirect cards this is blocked_by — the behaviour it walks