Skip to content

feat(e2e): #157 basePath-served Playwright project + signup smoke#178

Merged
TortoiseWolfe merged 1 commit into
mainfrom
feat/157-basepath-e2e-project
Jul 5, 2026
Merged

feat(e2e): #157 basePath-served Playwright project + signup smoke#178
TortoiseWolfe merged 1 commit into
mainfrom
feat/157-basepath-e2e-project

Conversation

@TortoiseWolfe

Copy link
Copy Markdown
Owner

What

Adds a basePath-served Playwright project (basepath) + a signup-redirect smoke spec + a self-contained CI job, closing the last structural blind spot in the basePath hardening arc (#157).

Why

The template deploys to a custom domain (public/CNAME), so basePath is '' and the E2E suite builds+serves at the root. A fork on a GitHub Pages project-site needs a /RepoName basePath — and the whole class of bug where auth redirects / hand-built URLs escape that prefix is invisible to a root-anchored suite. The URL construction is unit-tested (project.config.test.ts, #154) but had zero E2E coverage under an actual basePath-served build. This closes that gap — and it's what pins the runtime next/link prefixing behavior that #159's unit tests structurally can't (jsdom doesn't populate __NEXT_ROUTER_BASEPATH).

How

  • scripts/serve-basepath.sh — builds a NEXT_PUBLIC_BASE_PATH=/ScriptHammer export (assets baked at /ScriptHammer/_next/*, client basePath injected) and symlink-serves it under the prefix. serve has no subpath flag → serve-root/ScriptHammer -> ../out-basepath. Under output: 'export' the static export lands directly in NEXT_DIST_DIR (Next 15.5 doesn't create out/ when distDir is overridden), so distDir is the output dir — a gotcha caught and handled during local validation.
  • playwright.config.ts — new basepath project (testMatch: '**/basepath/**', no auth/setup dep — the smoke intercepts the signup POST). Excluded from every root-anchored project (chromium/firefox/webkit-gen + Mobile/Tablet) so they never run it against the wrong build.
  • tests/e2e/basepath/signup-redirect.spec.ts — loads /ScriptHammer/sign-up/, drives the form, intercepts and fulfills the Supabase signup POST (no real user, no email), and asserts redirect_to === <origin>/ScriptHammer/auth/callback/ (prefixed + trailing slash — the exact #154 seam). Also fails if any /_next/* asset 404s (guards the serve mechanism).
  • .github/workflows/e2e.yml — self-contained basepath job (needs: build) that builds its own prefix artifact, symlink-serves on :3000, runs --project=basepath. Supplies the test-user secrets the shared globalSetup hard-requires. Independent of the report/merge job.
  • .gitignore / eslint.config.mjs — ignore the prefix build + symlink scratch dirs (out-basepath, serve-root, .next-basepath) for both git and ESLint (else the 7k generated chunks trip the pre-push lint).

Verification

Ran the full mechanism locally end-to-end before wiring CI: prefix build → symlink-serve → --project=basepath1 passed. Confirmed /ScriptHammer/sign-up/ = 200, prefixed CSS asset = 200, root /sign-up/ = 404 (faithful to a project-site), and redirect_to carries the prefixed trailing-slash callback. type-check + full eslint clean; YAML validated.

Closes #157

🤖 Generated with Claude Code

The template deploys to a custom domain (basePath ''), so the E2E suite builds
and serves at the ROOT. A fork on a GitHub Pages project-site needs a /RepoName
basePath, and the whole class of bug where auth redirects / hand-built URLs
escape that prefix is structurally invisible to the root-anchored suite. The URL
construction is unit-tested (project.config.test.ts, #154) but has had ZERO E2E
coverage under an actual basePath-served build. Close that blind spot.

- scripts/serve-basepath.sh: build a NEXT_PUBLIC_BASE_PATH=/ScriptHammer export
  (assets baked at /ScriptHammer/_next/*) and symlink-serve it under the prefix
  (serve has no subpath flag → serve-root/ScriptHammer -> ../out-basepath). Under
  `output: export` the static export lands in NEXT_DIST_DIR directly (no out/),
  so distDir IS the output dir — verified locally end-to-end.
- playwright.config.ts: new `basepath` project (testMatch **/basepath/**, no
  auth/setup dep — the smoke intercepts the signup POST). Excluded from every
  root-anchored project (chromium/firefox/webkit-gen + Mobile/Tablet) so they
  don't run it against the wrong build.
- tests/e2e/basepath/signup-redirect.spec.ts: load /ScriptHammer/sign-up/, drive
  the form, intercept+fulfill the Supabase signup POST (no real user/email), and
  assert redirect_to === <origin>/ScriptHammer/auth/callback/ (prefixed, trailing
  slash — the exact #154 seam). Also guards that no /_next/* asset 404s.
- .github/workflows/e2e.yml: self-contained `basepath` job (needs: build) that
  builds its own prefix artifact, symlink-serves on :3000, runs --project=basepath.
  Supplies the test-user secrets the shared globalSetup hard-requires.
- .gitignore: ignore the prefix build + symlink scratch dirs.

Closes #157

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@TortoiseWolfe TortoiseWolfe merged commit eafa146 into main Jul 5, 2026
18 checks passed
@TortoiseWolfe TortoiseWolfe deleted the feat/157-basepath-e2e-project branch July 5, 2026 02:01
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.

E2E: add a basePath-enabled Playwright project so Pages project-site bugs are catchable

2 participants