Skip to content

fix(e2e): comment out Turnstile keys in .env.local (PP-uc8 redesign)#1283

Open
timothyfroehlich wants to merge 4 commits intomainfrom
feat/pp-uc8-turnstile-webserver
Open

fix(e2e): comment out Turnstile keys in .env.local (PP-uc8 redesign)#1283
timothyfroehlich wants to merge 4 commits intomainfrom
feat/pp-uc8-turnstile-webserver

Conversation

@timothyfroehlich
Copy link
Copy Markdown
Owner

@timothyfroehlich timothyfroehlich commented May 5, 2026

Summary

The original PR's dev:e2e script approach was solving the right problem (Turnstile bypass for E2E) in the wrong place. It added a separate npm script that overrode .env.local vars after sourcing, which worked for Playwright's webServer but left local dev with the wrong default — the Turnstile widget still rendered when using next dev directly, Storybook, or any other tool.

New approach: scripts/worktree_setup.py now writes the Turnstile keys commented-out in .env.local. They're visible as opt-in documentation but inactive by default.

How it works

The application already handles unset keys gracefully:

  • TurnstileWidget renders nothing if siteKey is falsy
  • verifyTurnstileToken returns true (skip) in non-prod if secretKey is falsy

So absent keys = bypass, uniformly across all dev tools (next dev, Playwright webServer, Storybook, etc.). No special scripts needed.

To test CAPTCHA UI locally (opt-in)

chmod 644 .env.local
# uncomment the two TURNSTILE_* lines
chmod 444 .env.local

The TURNSTILE_TEST_SECRET carveout in turnstile.ts is preserved — it now protects the explicit opt-in path (developer uncomments the keys to test CAPTCHA in headless mode where the widget JS may not complete).

E2E benefits

  • Widget never renders → no Cloudflare round-trip → no headless flakiness
  • playwright.config.ts uses plain pnpm run dev (reverted from dev:e2e)
  • dev:e2e script removed entirely

Changes

  • scripts/worktree_setup.py: Turnstile lines written commented-out with opt-in docs
  • scripts/tests/test_worktree_setup.py: New test asserting keys appear as # KEY=value
  • playwright.config.ts: webServer command reverted to pnpm run dev
  • package.json: dev:e2e script removed
  • All active worktree .env.local files updated (Turnstile lines commented out, chmod 444 restored)

playwright.config.ts webServer.env only forwarded PORT and MOCK_BLOB_STORAGE
to the dev server it spawns. The dev server therefore inherited whatever
Turnstile keys .env.local had, which made the login form's enforceCaptcha
check (`hasTurnstile && NODE_ENV !== "test"`) evaluate true and required
agents to manually clear the env vars before running E2E.

Now passing empty NEXT_PUBLIC_TURNSTILE_SITE_KEY and TURNSTILE_SECRET_KEY
through webServer.env activates the existing graceful-bypass logic:
- Client: TurnstileWidget returns null when site key is empty, so the form
  doesn't enforce a token.
- Server: verifyTurnstileToken returns true in non-prod when the secret key
  is missing, so submission succeeds.

No new logic — only plumbing the existing bypass through to the spawned
dev server. Production unaffected (real keys still apply outside Playwright).

Refs PP-2on (epic).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 5, 2026 01:15
@vercel
Copy link
Copy Markdown

vercel Bot commented May 5, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
pin-point Ready Ready Preview, Comment May 5, 2026 8:45pm

@supabase
Copy link
Copy Markdown

supabase Bot commented May 5, 2026

This pull request has been ignored for the connected project udhesuizjsgxfeotqybn due to reaching the limit of concurrent preview branches.
Go to Project Integrations Settings ↗︎ if you wish to update this limit.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR attempts to disable Turnstile for the dev server that Playwright uses during E2E runs, so local test runs are not blocked by real CAPTCHA keys in .env.local.

Changes:

  • Adds empty NEXT_PUBLIC_TURNSTILE_SITE_KEY and TURNSTILE_SECRET_KEY values to playwright.config.ts webServer.env.
  • Documents that these empty values are intended to trigger the app’s existing Turnstile bypass behavior in test/dev contexts.

Comment thread playwright.config.ts Outdated
Comment on lines +121 to +122
NEXT_PUBLIC_TURNSTILE_SITE_KEY: "",
TURNSTILE_SECRET_KEY: "",
Comment thread playwright.config.ts Outdated
Comment on lines +118 to +122
// trip the existing graceful-bypass logic in src/lib/security/turnstile.ts
// (server) and src/components/security/TurnstileWidget.tsx (client) so
// tests do not need to manually clear these env vars.
NEXT_PUBLIC_TURNSTILE_SITE_KEY: "",
TURNSTILE_SECRET_KEY: "",
….env.local (PP-uc8)

- Add dev:e2e script that sources .env.local then re-exports empty
  NEXT_PUBLIC_TURNSTILE_SITE_KEY and TURNSTILE_SECRET_KEY, so real keys
  from .env.local cannot clobber the bypass (Copilot #1 on playwright.config.ts:122)
- Change playwright.config.ts webServer.command from dev to dev:e2e
- Remove now-redundant Turnstile vars from webServer.env (the script handles it)
- Update PR description with reuseExistingServer caveat for local dev workflows
  (Copilot #2 on playwright.config.ts:122)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@timothyfroehlich
Copy link
Copy Markdown
Owner Author

Re: Copilot's two unresolved threads on playwright.config.ts

Both Copilot comments describe the pre-fix state. The fix in commit 4ba8a2fa introduced a separate dev:e2e script (NOT dev) which addresses both concerns:

Comment 1 (pnpm run dev re-sources .env.local, overwriting empty Turnstile values):
The webServer command is pnpm run dev:e2e, not pnpm run dev. From package.json:
```
"dev:e2e": "bash -lc 'set -a; source .env.local; set +a; export NEXT_PUBLIC_TURNSTILE_SITE_KEY= TURNSTILE_SECRET_KEY=; bash scripts/ensure-supabase.sh && exec ./node_modules/.bin/next dev --port "$PORT"'"
```
Sourcing happens FIRST, then the empty exports override. Empty values win. CAPTCHA is bypassed.

Comment 2 (reuseExistingServer may reuse a CAPTCHA-enabled local dev):
reuseExistingServer: !process.env["CI"] — in CI, this is FALSE, so Playwright always spawns a fresh dev:e2e server. Locally, if a developer has pnpm run dev already running with real CAPTCHA, Playwright reuses that — but that's an intentional dev choice. If you want CAPTCHA bypass locally, run pnpm run dev:e2e instead of pnpm run dev.

Both threads should auto-resolve on Copilot's next review pass. —Claude

@timothyfroehlich timothyfroehlich added the ready-for-review PR passed CI and has no unresolved review comments label May 5, 2026
Copilot AI review requested due to automatic review settings May 5, 2026 20:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

The previous approach added a dev:e2e npm script that overrode .env.local
after sourcing it. This solved E2E but left local dev with the wrong
default — the Turnstile widget rendered on every form (with a Cloudflare
round-trip) for no real value.

New approach: scripts/worktree_setup.py writes the Turnstile keys
commented-out by default, so .env.local has them visible as opt-in
documentation but inactive. The application code already handles
unset/empty correctly:
- TurnstileWidget renders nothing if siteKey is falsy
- verifyTurnstileToken returns true (skip) in non-prod if secretKey is falsy

To test CAPTCHA UI locally:
  chmod 644 .env.local
  # uncomment the two TURNSTILE_* lines
  chmod 444 .env.local

The TURNSTILE_TEST_SECRET carveout in turnstile.ts is preserved — it now
protects the explicit opt-in path (developer uncomments keys to debug
CAPTCHA in headless mode where the widget JS may not complete).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@timothyfroehlich timothyfroehlich changed the title fix(e2e): pass empty Turnstile keys to Playwright webServer (PP-uc8) fix(e2e): comment out Turnstile keys in .env.local (PP-uc8 redesign) May 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-review PR passed CI and has no unresolved review comments

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants