Skip to content

moooon

Motir

Vibe your whole project. Bring an idea — Motir's three AI layers plan it, track it, and ship it, end to end. You're looking at Motir, built in Motir.

  • Vibe Project
  • Open Source
  • AI Agent
  • AI Loop
1
requests
0
upvotes
145
planned
1,361
shipped

Motir · Roadmap

MOTIR-4226Implemented

E2E (Playwright, motir-marketing) + acceptance video — a tenant host and a customer host render the project, the canonical names the primary, and the non-primary address redirects

Opened by Zhu Yue ·

The browser walk of the public half of the story's verification recipe — a visitor arrives on a tenant subdomain and on a customer domain, reads the project, follows a link and stays on that host, and a request on a non-primary address lands on the primary — recorded at a pace a person can watch, and published to this card. motir-marketing's Playwright lane exists (MOTIR-4112): playwright.config.ts builds the app against e2e/stub/publicApiStub.ts and records video; the agent publishes the clip over the MCP (attach_file) — CI does not upload it, by decision.

The harness this needs, verified before a line is written

  • Tenant hosts in the lane: Chromium resolves any *.localhost name to loopback, so the stub site is reachable as acme.localhost:<SITE_PORT> and roadmap.localhost:<SITE_PORT> with no /etc/hosts change — the router card records this in e2e/stub/origin.ts. Read that file first; if the constant is not there, the router card did not finish and this card stops.
  • The stub answers the host contract: publicApiStub.ts gains routes for GET /api/public/hosts/{host} returning the three DTO shapes for the two hosts above and an alias host, plus addresses on the subject fixture and primaryHost on the index fixture — recorded from motir-core's OpenAPI document, the way the existing e2e/fixtures/*.json were.
  • The base domain at build time: the lane's webServer command sets NEXT_PUBLIC_MOTIR_TENANT_DOMAIN=localhost:<SITE_PORT> (or the shape the router card's accessor accepts for tests) alongside the app origin it already sets.

The spec — e2e/specs/acceptance-public-address.spec.ts

  1. Open http://acme.localhost:<port>/ — the workspace's public-project list renders inside the site chrome; click the project card → /<identifier> renders the Overview; the tab bar's hrefs are host-relative; open Board and Items, page Items once — every navigation stays on acme.localhost.
  2. Open http://roadmap.localhost:<port>/board — the project's Board renders at the root of a custom domain; the canonical <link> and og:url name the primary host the fixture declares.
  3. Open http://acme.localhost:<port>/<identifier> when the fixture says the primary is the custom domain → the browser lands on roadmap.localhost:<port>/ (a 301, asserted from the response chain), path preserved for a tab.
  4. Open an alias host (old.localhost:<port>/<identifier>) → 301 to the live subdomain, path preserved.
  5. GET /sitemap.xml and /robots.txt on each host — the sitemap lists only that host's URLs, robots names that host's sitemap.
  6. The empty, loading and error states: the workspace list with zero public projects; the ERROR state when the stub's host resolution answers 500 (never a 404 for an outage); the not-found page for an unknown host.
  7. The recording of steps 1–4 is paced for a person (the lane's slowMo / explicit pauses at each landing), and the agent attaches the video to this card with attach_file.

Waits are on authoritative signals (the landmark, the canonical tag present, the response status) — never on timers, per the E2E discipline in motir-core/CLAUDE.md this lane inherited.

Acceptance criteria

  • The spec passes in the e2e CI job on the PR, walking all seven steps above against the stub, with the video and trace artefacts produced.
  • Steps 1–4 assert from the response chain that every cross-host move is a 301 and every same-host move is a 200, and that no href rendered on a tenant host names /p/ or motir.co.
  • Step 5 asserts the sitemap's and robots' host per host kind; step 6 distinguishes the error state from the not-found page.
  • The stub's new routes and fixtures are recorded from the OpenAPI document (the recording command is in the PR body), not typed by hand.
  • The acceptance video is attached to this card, and its recorded happy path shows each landing long enough to read.
  • No file outside motir-marketing is touched.

Context refs

  • motir-marketing/playwright.config.ts (the build-in-webServer note, video: 'on', the no-uploader decision) · e2e/stub/origin.ts · e2e/stub/publicApiStub.ts · e2e/fixtures/ · e2e/specs/acceptance-public-project.spec.ts — the precedent walk
  • the router · the canonical card — the behaviour under test; the host contract — the DTO the stub records
  • motir-core/docs/decisions/acceptance-video.md — the agent publishes the clip; MOTIR-4122 — the previous story's acceptance walk on this host
  • MOTIR-3878 — the verification recipe, steps 1 and 3

Discussion

No comments yet.

Adding to this discussion signs you in on app.motir.co and brings you back to this request.

Add a comment