Skip to content

feat(#288): real-form signup E2E with a Mailpit mail-catcher#347

Merged
TortoiseWolfe merged 1 commit into
mainfrom
feat/288-signup-mailer-e2e
Jul 24, 2026
Merged

feat(#288): real-form signup E2E with a Mailpit mail-catcher#347
TortoiseWolfe merged 1 commit into
mainfrom
feat/288-signup-mailer-e2e

Conversation

@TortoiseWolfe

Copy link
Copy Markdown
Owner

What

#288, item 3 — the real human signup path, end-to-end, including the mailer. This is the thing #287 proved was untested: the deployed product was unusable (email confirmation broke) while every test stayed green, because tests minted users via admin.createUser({email_confirm:true}) — bypassing the form and the mailer.

This test does what a human does:

real /sign-up form → the real confirmation email lands in Mailpit → click the emailed link → session established → authenticated.

Refs #288 (not Closes — item 2 @smoke + wiring the auth-config drift gate into CI still remain).

Why local Supabase + Mailpit

The cloud shared project has no readable inbox (Resend is send-only). The local Supabase stack already bundles Mailpit (supabase-mail), so a test can actually read the confirmation email. Owner chose the mail-catcher (best practice) over minting the link via the admin API, because proving email delivery is the whole point of #288.

Changes

  • tests/e2e/signup-mailer/signup-confirm.spec.ts + tests/e2e/utils/mailpit.ts — the spec + a Mailpit REST helper (waitForMessageTo / extractConfirmationLink / clearMailbox). It fails loudly if no email arrives — that is exactly the Production OAuth broken since the Supabase project migration: client IDs are placeholders (recurrence of #85, closed-but-never-fixed) #287 signal, never a silent skip.
  • playwright.signup-mailer.config.ts — dedicated config with no globalSetup (the main config's globalSetup requires cloud creds + shared PRIMARY/TERTIARY users, absent on the ephemeral local stack). The spec is excluded from the main config's gen/mobile/tablet projects so it never runs against cloud.
  • docker-compose.yml — (1) parameterize GOTRUE_MAILER_AUTOCONFIRM (default 'true' unchanged — normal local dev still auto-confirms; the E2E sets it false to emit a real confirmation email); (2) fix a real local-stack bug: pin GOTRUE_MAILER_URLPATHS_* to /auth/v1/verify. GoTrue's default is a bare /verify, but API_EXTERNAL_URL points at Kong (which only routes /auth/v1/*), so the emailed link would 404. (Matches the official Supabase stack.)
  • .github/workflows/signup-mailer.yml — new CI job (modeled on conformance.yml + e2e.yml): local Supabase + Mailpit with autoconfirm off, a root-anchored build pointed at the local stack, serve, run. Per-ref concurrency — the stack is per-runner ephemeral, so it needs no shared e2e-supabase mutex.

Verified

Locally (the novel/risky mechanics), against the running local stack:

  • autoconfirm=false → GoTrue sends "Confirm Your Email" into Mailpit.
  • With the URLPATHS fix, the emailed link is http://localhost:54321/auth/v1/verify?token=…&type=signup&redirect_to=…/auth/callback/, and visiting it returns 303 → http://localhost:3000/auth/callback/#access_token=…&type=signup — the token verifies, session tokens land in the callback hash (implicit flow) exactly as the spec expects.
  • The Mailpit helper extracts the link correctly.
  • type-check + lint clean.

The full browser flow + CI orchestration are proven by the new signup-mailer job in this PR.

🤖 Generated with Claude Code

#288 item 3 — take the REAL human path end-to-end, the thing #287 proved untested: sign up via the real form → the real confirmation email lands in Mailpit → click the emailed link → authenticated. Runs against the LOCAL Supabase stack (Mailpit), because the cloud project has no readable inbox (Resend is send-only).

- tests/e2e/signup-mailer/signup-confirm.spec.ts + tests/e2e/utils/mailpit.ts: the spec + a Mailpit REST helper. Fails LOUDLY if no email arrives — that is the #287 signal.

- playwright.signup-mailer.config.ts: dedicated config (no globalSetup — the cloud-user prereq doesn't apply). Excluded from the main config's gen/mobile/tablet projects so it never runs against cloud.

- docker-compose.yml: parameterize GOTRUE_MAILER_AUTOCONFIRM (default 'true' unchanged; the E2E sets it false to emit a real confirmation email) + pin GOTRUE_MAILER_URLPATHS_* to /auth/v1/verify (GoTrue's bare /verify default 404s at Kong — a real local-stack bug this surfaced).

- .github/workflows/signup-mailer.yml: new CI job (local Supabase + Mailpit, autoconfirm off, root-anchored build pointed at the local stack, serve, run). Per-ref concurrency — ephemeral stack, no shared-backend mutex.

Verified locally: autoconfirm=false → 'Confirm Your Email' in Mailpit; the fixed link 303-redirects to /auth/callback#access_token=…&type=signup; helper extraction works. type-check + lint clean. Full browser flow + CI orchestration proven by the new job.

Refs #288

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@TortoiseWolfe
TortoiseWolfe merged commit e029b50 into main Jul 24, 2026
20 checks passed
@TortoiseWolfe
TortoiseWolfe deleted the feat/288-signup-mailer-e2e branch July 24, 2026 17:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants