← the whole session plugin/skills/playwright-validator/SKILL.md
Validate UX flows using the chrome-devtools MCP browser driver. Capture screenshots as evidence for whatever you're tracking work in — UX assignments, system logs, proposals, or a plain note. Use after making code changes to self-verify before creating a UX assignment, or when asked to validate a flow. Evidence lands in a local folder, no server or API key required.
Playwright Validator
Capture screenshot evidence of UX flows to accelerate human verification. Agents validate their own work and attach visual proof — locally, with no external service required.
Naming note: despite the name, this drives the chrome-devtools MCP server, not a Playwright MCP — there is no mcp-playwright shipped or expected. If your own project has a real Playwright test suite for headless CI runs, that's a separate, complementary thing; this skill is about an agent capturing evidence of what it just did, interactively, in the same browser session /devtools-site-testing uses.
When to Use
- After completing code changes, before creating a UX assignment
- When a human marks a UX assignment as needing verification
- To validate a reported bug exists or is fixed
- To capture current state for comparison
Prerequisites
This drives the chrome-devtools MCP server (tools like navigate_page, take_screenshot, click, evaluate_script, list_console_messages) — the same driver /devtools-site-testing uses. If those tools aren't available, that MCP server isn't configured yet; see that skill's Prerequisites section. If /alignment-harness:harness-setup recorded your app's local URL and login, reuse it rather than asking again.
Core Pattern
Agent completes code change
↓
Agent navigates the flow with the chrome-devtools MCP
↓
Agent captures screenshots at each step
↓
Agent saves each screenshot + a short record to the local evidence folder
↓
Agent creates a UX assignment (or proposal, or note) referencing the evidence path
↓
Human opens the folder or the referenced files, verifies in seconds
Where Evidence Lives (local, no server)
EVIDENCE_DIR=$(alignment-harness records evidence 2>/dev/null)
mkdir -p "$EVIDENCE_DIR/${sourceType}-${sourceId}"
Each screenshot is saved as a PNG under that folder, and a small JSON index file (index.json in the same folder) records the metadata for each step — the same information a human or another skill would otherwise have to ask you for:
{
"sourceType": "ux-assignment",
"sourceId": "<assignmentId or proposal id or whatever you're validating>",
"itemId": "<itemId, if applicable>",
"steps": [
{
"stepIndex": 0,
"stepDescription": "Login page loaded",
"filename": "step-0-login.png",
"url": "http://localhost:3000/login",
"viewport": { "width": 1280, "height": 720 },
"passed": true,
"consoleErrors": [],
"agentNotes": "Login form rendered correctly",
"capturedAt": "2026-01-01T00:00:00Z"
}
]
}
Append to this file after each step rather than holding it all in memory — if you run out of runway partway through, the steps you already captured still survive on disk.
Source Types
sourceType is whatever you're attaching evidence to — it isn't limited to one product's own tracker:
| Type | Use Case |
|---|---|
ux-assignment |
Evidence for a UX verification item, if your project has this kind of tracker |
system-log |
Screenshots showing an error state |
proposal |
Visual context for a proposal (see /how-to-submit-and-track-proposals) |
manual-test |
Ad-hoc captures with no formal tracker at all |
Validation Workflow
1. Navigate and Capture
Using the chrome-devtools MCP tools (same as /devtools-site-testing):
1. navigate_page({ url: "http://localhost:3000/checkout" })
2. take_screenshot() -> save as PNG under the evidence folder
3. Write/append the step record to index.json
4. click({ uid: "<element uid from a prior snapshot>" })
5. take_screenshot() -> save as PNG
6. Append step 2's record
2. Check for Errors
After each step:
- Capture console errors via
list_console_messages - Check for visible error elements (a snapshot or screenshot will usually show them)
- Mark
passed: falsein that step's record if issues found
3. Attach to Whatever You're Tracking
When creating a UX assignment, proposal, or note:
{
"title": "Checkout flow validation",
"steps": ["Navigate to /checkout", "Click submit", "Verify confirmation"],
"evidenceNote": "Screenshots and step-by-step notes saved locally — see <EVIDENCE_DIR>/<sourceType>-<sourceId>/"
}
If your project's own tracker (an admin UI, a dashboard) knows how to render a folder of evidence as thumbnails, point it at this folder. If it doesn't, the folder and its index.json are still a complete, human-readable record on their own — open the PNGs directly.
Query Evidence
# List every step recorded for one thing you validated
cat "$EVIDENCE_DIR/ux-assignment-<assignmentId>/index.json" | jq '.steps'
# Check whether something already has evidence (for your own gating logic)
test -f "$EVIDENCE_DIR/ux-assignment-<assignmentId>/index.json" && echo "has evidence" || echo "no evidence yet"
Storage
- Screenshots and their index are stored locally under the folder
alignment-harness records evidenceprints — no cloud upload, no external service, fast local access. - No automatic cleanup by default. Screenshots accumulate until you remove them. If you want a retention policy, prune by modification time yourself, for example:
find "$EVIDENCE_DIR" -mtime +30 -deletefor a 30-day cutoff. Don't claim automatic expiry unless you've actually wired something to run that on a schedule.
Best Practices
DO:
- Capture at each meaningful step
- Include console errors in the step record
- Mark
passed: falsefor failures - Add descriptive
agentNotes - Use consistent viewport sizes
DON'T:
- Capture redundant screenshots (every second)
- Skip error checking
- Save a screenshot without context (missing
stepDescription) - Forget to set
sourceType/sourceIdso the evidence is findable later
Integration with UX Assignments
After capturing evidence:
- Create the UX assignment (or proposal, or note) as normal
- Reference the evidence folder path in it (
sourceType+sourceIdname the folder) - If your own tracker's UI can render a folder of images as thumbnails, wire that up once; otherwise, opening the folder directly is the intended path
- A human opens the folder, looks at the PNGs and the
agentNotesinindex.json, and verifies in seconds instead of minutes
Example: Full Flow
// 1. Agent navigates
await navigate_page({ url: 'http://localhost:3000/checkout' });
// 2. Capture step 1
const step1Png = await take_screenshot();
await saveEvidence({
sourceType: 'ux-assignment',
sourceId: assignmentId,
itemId: itemId,
png: step1Png,
filename: 'checkout-page.png',
stepIndex: 0,
stepDescription: 'Checkout page loaded',
url: 'http://localhost:3000/checkout',
passed: true,
});
// 3. Click button (use a uid from a prior snapshot/find call)
await click({ uid: submitButtonUid });
// 4. Check for errors
const errors = await list_console_messages({ onlyErrors: true });
// 5. Capture result
const step2Png = await take_screenshot();
await saveEvidence({
sourceType: 'ux-assignment',
sourceId: assignmentId,
itemId: itemId,
png: step2Png,
filename: 'confirmation.png',
stepIndex: 1,
stepDescription: 'After submit click',
url: 'http://localhost:3000/checkout/confirm',
passed: errors.length === 0,
consoleErrors: errors,
});
// `saveEvidence` here is shorthand for: write the PNG to the evidence folder,
// then append this step's metadata to that folder's index.json.