tsaol/awesome-claude/ui-test-guard
Claude Code and agent skill by tsaol/awesome-claude
- community
Checking that the SKILL.md file is still in the repository.
A Stop hook that catches Claude when it claims a UI change is "done", "deployed", or "verified" without showing evidence that a real-browser UI test actually passed. Stops the curl + grep illusion of testing.
Install
npx vskill@latest install tsaol/awesome-claude/ui-test-guardSKILL.md
ui-test-guard — Stop Hook for Honest UI Testing
A Claude Code Stop hook that intercepts replies claiming a UI change is complete and asks: did you actually run a real-browser test? If not, it injects a system-reminder so Claude has to either run the test or admit it skipped.
The problem
Claude will happily report a UI change as "deployed and verified" after running only curl | grep "expected text". Curl can confirm the server returns a 200 with the right string in its body, but it cannot catch:
- CSS layout breakage
- React hydration errors
- RSC flight payloads served as raw text instead of rendered HTML
- Blank screens caused by JS runtime errors
- Visual regressions
- Missing fonts, broken images, overflow, mobile-only bugs
A user can spend hours trusting "verified" reports that were never actually verified.
The fix
A Stop hook scans Claude's last reply. If it contains:
- A claim word:
deployed,verified,done,shipped,live,tested,complete,works,ALL PASSED - AND a URL or known web route:
https://...,/login,/dashboard,/portfolio, etc. - AND no evidence of a real-browser test:
ui-test,run_tests.py,ALL PASSED,playwright,cypress
…the hook returns exit 2 with a reminder. Claude sees the reminder on the next turn and has to either run the test or explicitly say it skipped.
How it works
| Phase | What happens | |
|---|---|---|
| Stop event fires | After every Claude reply is composed | |
| Hook reads transcript | Pulls the last assistant message text via jq | |
| Three regexes evaluated | CLAIM_RE AND URL_RE AND NOT EVIDENCE_RE | |
| If all true | exit 2 + system-reminder via stderr | |
| Otherwise | exit 0, silent pass |
Fail-open by design: if jq is missing, the transcript is unreadable, or anything else goes wrong, the hook exits 0. No false positives blocking real work.
Install
1. Copy the hook
2. Register in settings.json
Add this to ~/.claude/settings.json under hooks:
See settings.example.json for the project-relative path version.
3. Verify
Customize the regexes
Override any regex via environment variables before the hook runs. Useful when you want to scope to a specific project URL:
| Env var | Default | Example override | ||||
|---|---|---|---|---|---|---|
UI_TEST_GUARD_CLAIM_RE | `(deployed | verified | ...)` | `(deployed | shipped)` for stricter | |
UI_TEST_GUARD_URL_RE | generic web routes + http URLs | (myapp\.example\.com) for project scope | ||||
UI_TEST_GUARD_EVIDENCE_RE | `(ui-test | run_tests\.py | ALL PASSED | ...)` | add your team's test harness name | |
UI_TEST_GUARD_LOG | /tmp/ui-test-guard.log | /var/log/... |
Wrap the hook in a wrapper script to apply the env, e.g.:
Pair this with a real-browser test runner
This hook only nags. It does not run the test. You still need a test harness. Pairs well with:
ui-testskill (AWS AgentCore Browser, in this repo)- Playwright
- Cypress
- Selenium
The EVIDENCE_RE matches the names of the most common harnesses, so it stays quiet when any of them are mentioned in the reply.
Why a Stop hook, not PreToolUse
Two design choices were considered:
Stop hook (this skill): soft, advisory. Reminds Claude after the fact. Does not block any tool. Lets Claude finish a thought, then nudges. Best for repeated education.
PreToolUse hook (alternative): hard block. Refuses git commit or aws ssm send-command if recent test results don't show pass. Stronger, but risks blocking legitimate non-UI work and frustrating the user.
This skill picks the soft path. Upgrade to PreToolUse only if Stop reminders aren't enough.
File layout
Limitations
- Only as good as the regexes. If Claude phrases its claim creatively, the hook won't fire.
- Reads the JSONL transcript — sensitive to changes in Claude Code's transcript schema. Tested on Claude Code 2.x.
- One hook per Stop event. If you have other Stop hooks, register them all in the same array.
Security
- Security scanPassed, 90 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/ui-test-guard/SKILL.md
Popularity
- Repository stars
- 62
- Repository forks
- 4
- 7-day trend score
- 21
Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/tsaol/awesome-claude/ui-test-guard)