test-playwright — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited test-playwright (Agent Skill) and scored it 45/100 (orange). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
A base64 string of 128+ characters appears in a documentation file. Encoded prompt injection hides the hostile instruction in base64 — invisible to keyword filters — and relies on the agent's ability to decode it at runtime. There is no normal authoring reason to embed a multi-hundred-byte base64 blob in skill docs.
*.sig, SIGNATURES) outside the documentation.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
The job is not done when the code compiles. It is done when you have driven the live app as a user, found what's broken or clunky, and fixed it. This skill exists because agents implement a change, declare victory, and skip the Check and Act phases of PDCA. You will not skip them.
Plan = the change you just made. Do = it's already in the code. Check = drive the live app as a real user (this skill). Act = fix every pain point and error you find, in the same turn.
Before ANY browser action, read `protocol-browser-anti-stall` (`~/.cursor/skills/protocol-browser-anti-stall/SKILL.md`) and apply every rule — especially Rule 0 (manual & headed, never scripted), plus the navigation guard, ≤3s waits, fresh browser_snapshot after every state change, max-4-attempts-per-goal, timeout budgets, tab discipline, and persisted auth (references/playwright-session-coordination.md).
Drive a visible browser by hand, never a script. Headed (never--headless). Click, type, scroll, read, react — one real action at a time, as someone discovering the feature for the first time.browser_evaluate/browser_run_code_unsafeare inspection-only; never write*.spec.tsor runnpx playwright test. You're here to feel the pain points, not pass a green check.
Test only what this session changed — plus its blast radius. Not a full-app crawl (that's test-qa). Scope to the files you edited and the pages/flows/APIs that consume them. Touch a shared component → test every page that renders it.Fix as you go — full-stack. Hit a bug, 500, confusing label, dead button, ugly layout → fix the root cause now (frontend, backend, migration, RLS, config), then re-test the same flow. Don't batch fixes for "later".
Evidence or it didn't happen. Every finding needs a screenshot + console + network. Every fix needs a live re-test that proves it against the real backend (a 200, persisted data, clean console).
Red-team your own work. Assume your change is subtly wrong. Try to break it. Be the harshest critic of the UX you just shipped.
PDCA Progress:
- [ ] Phase 1: Scope — what did this session change? (blast radius)
- [ ] Phase 2: Environment — dev server up, app loads, authenticated
- [ ] Phase 3: Walk the changed flows as a real user
- [ ] Phase 4: Fix pain points + errors as you find them (full-stack)
- [ ] Phase 5: Backend truth-check (Sentry / Supabase / logs)
- [ ] Phase 6: Red-team + critique + enhancement ideas
- [ ] Phase 7: Re-test everything you fixed; reportFigure out exactly what to test. Do NOT test the whole app.
git status --short
git diff --stat HEAD
git diff HEAD --name-onlyIf work spans multiple repos in the workspace, run this in each repo root.
each one (grep -rl "ComponentName" src/). This is the blast radius.
touch those tables, as the role the client actually uses.
package.json scripts.dev (3000 / 5173 / etc.)..env.local, .env.test, README). If none,ask the user once.
plugin-supabase-supabase),Sentry (plugin-sentry-sentry), Firecrawl (user-firecrawl).
SESSION SCOPE:
- Repos touched: [list]
- Changed surfaces (pages/flows): [list]
- Blast radius (shared code → consumers): [list]
- Backend paths touched (APIs/tables/RPCs): [list]
- Dev URL: http://localhost:[port] Auth: [method / test account]
- User journeys to drive: [ordered list of 2–6 real flows]Read `protocol-browser-anti-stall/references/playwright-session-coordination.md` before opening the browser — shared Playwright instance, tab claiming, Google/OAuth session reuse.
terminals/ folder for a running dev server (npm run dev, next dev,vite, etc.). If none is running, start it (block_until_ms sized to startup) and wait until it serves, or tell the user and stop.
browser_tabs → list — note open tabs; read .playwright-mcp/session.json if present.select the auth tab from session.json, or new withthe dev URL. Do not hijack another agent's tab.
browser_navigate (in your tab only) → anti-stall (wait 2s → browser_snapshot →verify content).
browser_console_messages + browser_network_requests → baseline before touching thechanged feature.
persistent profile by default, so a one-time manual login survives across turns and sessions — you rarely re-login.
need you to approve in the browser). Then verify a protected route loads.
.playwright-mcp/auth/<host>.json via browser_run_code_unsafe if theserver runs --isolated (no persistent profile) — see coordination reference.
For each user journey from the Phase 1 plan, live it step by step.
Per step, follow this cycle (anti-stall applies throughout):
1. browser_navigate (if moving pages)
2. wait 2s → browser_snapshot → confirm the page/feature rendered
3. browser_take_screenshot → visual evidence
4. Interact like a user: browser_click / browser_type / browser_fill_form /
browser_select_option / browser_hover / browser_press_key / browser_drag
5. browser_snapshot (FRESH refs) after every interaction
6. browser_console_messages → any NEW error vs baseline?
7. browser_network_requests → any 4xx/5xx, CORS, timeout, or missing call?
8. Judge it: does it WORK and does it feel GOOD? PASS or PAIN POINT.What to hunt for on every changed surface:
| Category | Look for |
|---|---|
| Broken | Blank screen, error boundary, 404/500, stuck spinner, dead button, no-op submit |
| Data wrong | undefined / null / NaN / [object Object] / Invalid Date on screen, totals that don't add up, stale data after a mutation |
| Pipeline | Mutation shows in UI but API failed; created item not in list until refresh; deleted item reappears; optimistic update never confirms |
| Validation | Empty/invalid submit gives no feedback; no inline errors; silent backend rejection |
| UX friction | Confusing label/copy, no loading state, no success/error feedback, hidden primary action, too many clicks, surprising navigation |
| Visual | Overflow/clipping, cramped or wasted space, broken images/icons, dark-mode breakage, layout shift, misalignment (verify in screenshot) |
| A11y basics | Inputs without labels, controls without accessible names, focus not visible, low contrast |
Mutations must be verified end-to-end: after create/update/delete, confirm (a) the network call returned 2xx, (b) the UI reflects it, (c) it survives a hard browser_navigate reload, and (d) — if Supabase MCP is available — the row actually changed in the DB. Prefix any test data with QA-TEST- and clean it up at the end.
This is the Act phase agents skip. The moment you find a problem, fix its root cause before moving on. Do not just log it.
validation/serialization. Use debug-fe-be-integration mindset if FE↔BE mismatch.
relation does not exist / function not found / missing column → the migrationwasn't deployed. Deploy it via the Supabase MCP (apply_migration for DDL, execute_sql for data) AND keep the versioned migration file on disk in sync. (See the always-on full-stack-ship-discipline rule — schema the user just asked for ships without re-asking; DELETE/UPDATE/TRUNCATE on real rows asks first.)
SET ROLE anon; /authenticated;), fix the policy, re-verify.
unrelated refactors). Run ReadLints on files you edited.
2xx network, correct UI, persisted data. A fix is not done until re-tested live.
recommendation rather than silently shipping a broken flow.
Keep a running fix log:
FIX LOG:
- [surface] [symptom] → root cause: [...] → fix: [file(s)] → re-test: PASS/▢Don't trust the UI alone. Confirm against the systems of record using enabled MCPs.
Sentry — did your session introduce or relate to production errors? Look up tool schemas under mcps/plugin-sentry-sentry/tools/ first, then:
CallMcpTool(server: "plugin-sentry-sentry", toolName: "search_issues", arguments: {
"organizationSlug": "<ORG>", "naturalLanguageQuery": "unresolved issues in the last 7 days",
"projectSlugOrId": "<PROJECT>", "regionUrl": "<REGION_URL>", "limit": 25
})Cross-reference issues with the surfaces you touched. Use analyze_issue_with_seer for root cause on anything that maps to your change. Only update_issue to resolve AFTER a verified fix.
Supabase — verify schema, data, and logs for the paths you touched. Check tool schemas under mcps/plugin-supabase-supabase/tools/ first, then use list_tables, execute_sql, get_logs(service: 'api'|'postgres'), and get_advisors. Treat new ERROR-level advisors from your change as part of your work. Confirm any migration you deployed actually exists on the remote (information_schema / pg_proc / pg_policies).
App logs / terminal — read the dev-server terminal file for server-side stack traces that never reached the browser.
Switch hats: you are now a skeptical senior reviewer + a demanding user who is hard to impress. For the changed surfaces, push hard:
direct-URL deep links, empty states, huge inputs, special chars (<script>, '; DROP TABLE, emoji, very long strings), slow/failed network.
immediate and clear? Is anything redundant, cramped, or confusing? Would a real user get stuck? (Lean on enhance-web-ux / enhance-web-ui heuristics if deep polish is warranted.)
did this change introduce drift?
feature/pattern, use Firecrawl (user-firecrawl) to check current best practices, then map findings back to concrete changes:
CallMcpTool(server: "user-firecrawl", toolName: "firecrawl_search", arguments: {
"query": "[pattern/feature] best practices [current year]", "limit": 5,
"sources": [{ "type": "web" }]
})Capture enhancement ideas — concrete, not vague. For each: what to add/change, why it helps the user, and rough effort. Distinguish "fix now" (done in Phase 4) from "suggested next" (proposed in the report).
QA-TEST- data; reset any settings you changed; verify cleanup in DB ifapplicable.
## PDCA Test Report — [feature / session summary]
### Scope (what this session changed)
- Repos: [...] Surfaces tested: [...] Backend paths: [...]
- Dev URL: [...] Auth: [...]
### Flows driven (as a user)
| # | Journey | Result | Evidence |
|---|---------|--------|----------|
| 1 | [...] | PASS / FIXED / BLOCKED | [screenshot/console/network] |
### Fixed this turn (Act)
| # | Surface | Symptom | Root cause | Fix (files) | Re-tested |
|---|---------|---------|-----------|-------------|-----------|
| 1 | [...] | [...] | [FE/BE/DB/config] | [...] | ✅ |
### Still broken / out of scope (needs decision)
| # | Surface | Issue | Why not fixed | Recommendation |
|---|---------|-------|---------------|----------------|
### Backend truth-check
- Sentry: [new/related issues + status]
- Supabase: [schema/data/logs/advisors verified — migration deployed? Y/N]
### Red-team findings
| # | Surface | Severity | Finding | Evidence |
|---|---------|----------|---------|----------|
### Enhancement suggestions (Plan the next cycle)
1. [concrete idea] — why it helps — rough effort
2. ...
### Verdict
**Ship / Ship after fixes / Not ready** — [1–2 sentence justification]
Console clean: [Y/N] · All flows green on re-test: [Y/N] · Test data cleaned: [Y/N]user-playwright)Headed by default; snapshot/ref-based (accessibility tree), no lock/unlock — just snapshot freshly after each change.
Drive with these (real user actions): browser_navigate, browser_navigate_back, browser_click, browser_type, browser_fill_form, browser_select_option, browser_hover, browser_drag, browser_drop, browser_press_key, browser_file_upload, browser_handle_dialog, browser_resize, browser_tabs.
Observe with these: browser_snapshot, browser_take_screenshot, browser_wait_for, browser_console_messages, browser_network_requests, browser_network_request.
Inspection-only (never to drive the UI): browser_evaluate, browser_run_code_unsafe.
time; browser_evaluate / browser_run_code_unsafe for inspection only; no *.spec.ts, no npx playwright test. See anti-stall Rule 0.
a full-app sweep use test-qa.
browser_tabs list before everyturn; work in your tab only; never close tabs you didn't open.
don't log out unless testing logout.
attempts per goal; skip a stuck step ([TIMEOUT]) rather than freeze the session.
on disk; verify the remote actually has it.
DELETE /UPDATE / TRUNCATE on production rows asks first.
.env* values by name only; never print them.re-test.
If you couldn't fix something, say so clearly with a recommendation.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.