feat(e2e): #157 basePath-served Playwright project + signup smoke#178
Merged
Conversation
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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/RepoNamebasePath — 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 runtimenext/linkprefixing behavior that #159's unit tests structurally can't (jsdom doesn't populate__NEXT_ROUTER_BASEPATH).How
scripts/serve-basepath.sh— builds aNEXT_PUBLIC_BASE_PATH=/ScriptHammerexport (assets baked at/ScriptHammer/_next/*, client basePath injected) and symlink-serves it under the prefix.servehas no subpath flag →serve-root/ScriptHammer -> ../out-basepath. Underoutput: 'export'the static export lands directly inNEXT_DIST_DIR(Next 15.5 doesn't createout/when distDir is overridden), so distDir is the output dir — a gotcha caught and handled during local validation.playwright.config.ts— newbasepathproject (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 assertsredirect_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-containedbasepathjob (needs: build) that builds its own prefix artifact, symlink-serves on :3000, runs--project=basepath. Supplies the test-user secrets the sharedglobalSetuphard-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=basepath→ 1 passed. Confirmed/ScriptHammer/sign-up/= 200, prefixed CSS asset = 200, root/sign-up/= 404 (faithful to a project-site), andredirect_tocarries the prefixed trailing-slash callback.type-check+ fulleslintclean; YAML validated.Closes #157
🤖 Generated with Claude Code