Subchapter 11.12
tests/validation.mdMarkdown3 KBView on GitHub
These cases match the assertions in the Turnstile Spin PRD. Run them after editing this skill to confirm an agent loading it can still execute the wizard end-to-end.
Step 10’s validate.sh sends a deliberately-invalid token directly to challenges.cloudflare.com/turnstile/v0/siteverify using the captured secret. The expected response is success: false with error-codes: ["invalid-input-response"]. Anything else means the secret is wrong or the widget is misconfigured.
printf '%s' "$WIDGET_SECRET" |
python3 -I -c 'import sys,urllib.parse; print(urllib.parse.urlencode({"secret":sys.stdin.read(),"response":"XXXX.DUMMY.TOKEN.XXXX"}),end="")' |
curl --disable --fail --silent --show-error \
"https://challenges.cloudflare.com/turnstile/v0/siteverify" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-binary @- |
jq -e '.success == false and (.["error-codes"] | index("invalid-input-response"))'Expected exit code: 0.
printf '%s' "$WIDGET_SECRET" |
scripts/validate.sh \
--sitekey "$SITEKEY" \
--account-id "$ACCOUNT_ID" \
--expected-domains '["example.com","localhost","127.0.0.1"]'Expected exit code: 0 for all valid clearance levels: no_clearance, interactive, managed, and jschallenge. A secret from another sitekey must fail.
Inspect every generated frontend and backend pair:
signup, login, or contact.result.action value.result.hostname to match its deployment-specific frontend hostname allowlist.localhost or 127.0.0.1.Native forms that navigate do not need reset logic. For each same-page flow, verify that the code retains the widget ID returned by turnstile.render() and calls turnstile.reset(widgetId) after the request completes. Multiple protected surfaces must not share a widget ID or reset without an ID.
After Step 11:
test -f .claude/skills/turnstile-spin/SKILL.md \
|| test -f .codex/skills/turnstile-spin/SKILL.md \
|| test -f .opencode/skills/turnstile-spin/SKILL.mdExpected exit code: 0. File-oriented rules targets install the hosted prompt.md directly instead of using persist-skill.sh.
The consuming test harness must pass the widget secret through standard input. It must not export it or place it in a command argument.
(run-all.sh is not bundled with this skill; the cases above are intended to be wired into the consuming agent’s own test harness, or run by hand after a deploy.)