| name | qa |
| version | 2.0.0 |
| description | QA test a web application using Playwright. Use when asked to "qa", "QA", "test this site", "find bugs", "dogfood", "verify frontend behavior", "check UI rendering", "test user flows", "debug visual issues", "take a snapshot", "take a screenshot", "browser automation", "Playwright MCP", "ref system", or review quality of any web app (local or deployed). Five modes: diff-aware (auto on feature branches), full (systematic exploration), quick (30-second smoke test), single-page (verify one page or component), regression (compare against baseline). Produces structured report with health score, screenshots, and repro steps. Uses Playwright MCP tools or CLI fallback. Includes Playwright MCP reference (tool selection, ref system, token optimization, session management).
|
| argument-hint | [url] [--quick|--single|--regression baseline.json] |
| allowed-tools | ["Bash","Read","Write","AskUserQuestion"] |
/qa: Systematic QA Testing
You are a QA engineer. Test web applications like a real user โ click everything, fill every form, check every state. Produce a structured report with evidence.
For Playwright MCP reference and the cloned-profile helper workflow, see playwright.md.
Setup
Parse the user's request for these parameters:
| Parameter | Default | Override example |
|---|
| Target URL | (auto-detect or required) | https://myapp.com, http://localhost:3000 |
| Mode | full | --quick, --regression baseline.json |
| Output dir | .qa-reports/ | Output to /tmp/qa |
| Scope | Full app (or diff-scoped) | Focus on the billing page |
| Auth | None | Sign in to user@example.com |
If no URL is given and you're on a feature branch: Automatically enter diff-aware mode.
Determine the browser automation tool:
Check in this order:
- Playwright MCP tools โ check if
mcp__plugin_playwright_playwright__browser_navigate is available as a tool. If yes, use Playwright MCP tools (preferred).
- Playwright CLI โ check if
npx playwright works. If yes, write and run Playwright scripts.
- Neither available โ tell the user: "No browser automation available. Install Playwright (
npx playwright install chromium) or ensure Playwright MCP is configured."
Create output directories:
REPORT_DIR=".qa-reports"
mkdir -p "$REPORT_DIR/screenshots"
Browser Automation Abstraction
This skill works with whatever Playwright is available. Here's the mapping:
Using Playwright MCP tools (preferred)
| Action | Tool |
|---|
| Navigate | browser_navigate with url |
| Click | browser_click with selector or ref |
| Fill form | browser_fill_form with field data |
| Take screenshot | browser_take_screenshot |
| Get page snapshot | browser_snapshot |
| Check console | browser_console_messages |
| Run JS | browser_evaluate with script |
| Wait for element | browser_wait_for with selector |
| Resize viewport | browser_resize with width/height |
| Press key | browser_press_key with key |
| Hover | browser_hover with selector |
| Handle dialog | browser_handle_dialog |
| Upload file | browser_file_upload with paths |
| Check network | browser_network_requests |
Using Playwright CLI (fallback)
Write a Node.js script using Playwright API and run it via node /tmp/qa-script.js. Script pattern:
const { chromium } = require("playwright");
(async () => {
const browser = await chromium.launch();
const page = await browser.newContext().then((c) => c.newPage());
await page.goto("TARGET_URL");
await page.screenshot({ path: "/tmp/screenshot.png", fullPage: true });
await browser.close();
})();
Modes
Diff-aware (automatic when on a feature branch with no URL)
-
Analyze the branch diff:
git diff main...HEAD --name-only
git log main..HEAD --oneline
-
Identify affected pages/routes from changed files:
- Controller/route files -> which URL paths they serve
- View/template/component files -> which pages render them
- Model/service files -> which pages use those models
- CSS/style files -> which pages include those stylesheets
- API endpoints -> test them directly
- Static pages -> navigate to them directly
-
Detect the running app โ check common local dev ports:
lsof -i :3000 2>/dev/null && echo "Found app on :3000" || \
lsof -i :4000 2>/dev/null && echo "Found app on :4000" || \
lsof -i :5173 2>/dev/null && echo "Found app on :5173" || \
lsof -i :8080 2>/dev/null && echo "Found app on :8080"
If nothing found, ask the user for the URL.
-
Test each affected page/route โ navigate, screenshot, check console, test interactions.
-
Cross-reference with commit messages to understand intent and verify the change actually works.
-
Report findings scoped to the branch changes.
Full (default when URL is provided)
Systematic exploration. Visit every reachable page. Document 5-10 well-evidenced issues. Produce health score. Takes 5-15 minutes.
Quick (--quick)
30-second smoke test. Homepage + top 5 navigation targets. Check: loads? Console errors? Broken links? Health score. No detailed issue docs.
Single-page (--single)
Verify one page or component. Navigate, screenshot, check console errors, test interactive elements, report. Use when the user says "check if this works", "verify this page", "test this component", or provides a single URL with a focused ask. No health score โ just a pass/fail checklist:
- Page loads without errors
- Screenshot looks correct (describe what you see)
- Console is clean (or list errors)
- Interactive elements work (click buttons, fill forms)
- Accessibility snapshot has no obvious issues
Regression (--regression <baseline>)
Run full mode, then load baseline JSON. Diff: which issues fixed? Which new? Score delta?
Workflow
Phase 1: Initialize
- Determine browser automation tool
- Create output directories
- Start timer for duration tracking
Phase 2: Authenticate (if needed)
Navigate to login page, fill credentials, submit. NEVER include real passwords in reports โ write [REDACTED].
If 2FA/OTP required: ask the user for the code.
If CAPTCHA blocks: tell the user to complete it manually.
Phase 3: Orient
Get a map of the application:
- Navigate to target URL
- Take screenshot of landing page
- Get page snapshot to map navigation structure
- Check console for errors
Detect framework (note in report):
__next or _next/data -> Next.js
csrf-token meta tag -> Rails
wp-content -> WordPress
- Client-side routing with no reloads -> SPA
For SPAs: Use page snapshot to find nav elements instead of link enumeration.
Phase 4: Explore
Visit pages systematically. At each page:
- Navigate to page
- Take screenshot
- Check console for errors
Then follow the per-page exploration checklist:
- Visual scan โ Look at screenshot for layout issues
- Interactive elements โ Click buttons, links, controls. Do they work?
- Forms โ Fill and submit. Test empty, invalid, edge cases
- Navigation โ Check all paths in and out
- States โ Empty state, loading, error, overflow
- Console โ Any new JS errors after interactions?
- Responsiveness โ Check mobile viewport if relevant (resize to 375x812)
Spend more time on core features, less on secondary pages.
Quick mode: Only homepage + top 5 nav targets. Just check: loads, console errors, broken links.
Phase 5: Document
Document each issue immediately when found.
Interactive bugs: Screenshot before action, perform action, screenshot after, describe what changed.
Static bugs: Single screenshot showing the problem + description.
Phase 6: Wrap Up
- Compute health score (see rubric below)
- Write "Top 3 Things to Fix"
- Console health summary
- Update severity counts
- Fill report metadata
- Save baseline JSON
Issue Taxonomy
Severity Levels
| Severity | Definition |
|---|
| critical | Blocks a core workflow, causes data loss, or crashes the app |
| high | Major feature broken or unusable, no workaround |
| medium | Feature works but with noticeable problems, workaround exists |
| low | Minor cosmetic or polish issue |
Categories
- Visual/UI โ Layout breaks, broken images, z-index, font/color issues, animation glitches
- Functional โ Broken links, dead buttons, form validation, incorrect redirects, state issues, race conditions
- UX โ Confusing nav, missing loading indicators, slow interactions, unclear errors, dead ends
- Content โ Typos, outdated text, placeholder text, truncation, wrong labels
- Performance โ Slow loads (>3s), janky scrolling, layout shifts, excessive requests
- Console/Errors โ JS exceptions, failed requests, deprecation warnings, CORS, mixed content
- Accessibility โ Missing alt text, unlabeled inputs, keyboard nav broken, focus traps, contrast
Grading Visual/UI and UX issues: When you spot animation, easing, timing, focus, hit-target, shadow, radius, or typography problems, grade them against the userinterface-wiki skill's 152 rules and cite the violated rule ID in the issue (e.g. "violates timing-under-300ms", "violates ux-fitts-target-size", "violates visual-concentric-radius"). This turns vague "feels off" findings into concrete, fixable diagnoses.
Health Score Rubric
Each category score (0-100), weighted average.
- Critical issue: -25, High: -15, Medium: -8, Low: -3 (per category, minimum 0)
Weights
| Category | Weight |
|---|
| Console | 15% |
| Links | 10% |
| Visual | 10% |
| Functional | 20% |
| UX | 15% |
| Performance | 10% |
| Content | 5% |
| Accessibility | 15% |
Console scoring: 0 errors=100, 1-3=70, 4-10=40, 10+=10
Links scoring: 0 broken=100, each broken link: -15
Report Template
# QA Report: {APP_NAME}
| Field | Value |
| ----------------- | ---------------------------------------- |
| **Date** | {DATE} |
| **URL** | {URL} |
| **Scope** | {SCOPE or "Full app"} |
| **Mode** | {full / quick / diff-aware / regression} |
| **Duration** | {DURATION} |
| **Pages visited** | {COUNT} |
| **Screenshots** | {COUNT} |
| **Framework** | {DETECTED or "Unknown"} |
## Health Score: {SCORE}/100
| Category | Score |
| ------------- | ------- |
| Console | {0-100} |
| Links | {0-100} |
| Visual | {0-100} |
| Functional | {0-100} |
| UX | {0-100} |
| Performance | {0-100} |
| Accessibility | {0-100} |
## Top 3 Things to Fix
1. **{ISSUE-NNN}: {title}** โ {one-line description}
2. ...
3. ...
## Console Health
| Error | Count | First seen |
| --------------- | ----- | ---------- |
| {error message} | {N} | {URL} |
## Summary
| Severity | Count |
| -------- | ----- |
| Critical | 0 |
| High | 0 |
| Medium | 0 |
| Low | 0 |
## Issues
### ISSUE-001: {Short title}
| Field | Value |
| ------------ | -------------------------------------------------------------------------- |
| **Severity** | critical / high / medium / low |
| **Category** | visual / functional / ux / content / performance / console / accessibility |
| **URL** | {page URL} |
**Description:** {What is wrong, expected vs actual.}
**Repro Steps:**
1. Navigate to {URL}
2. {Action}
3. **Observe:** {what goes wrong}
Framework-Specific Guidance
Next.js
- Check for hydration errors in console
- Monitor
_next/data requests โ 404s = broken data fetching
- Test client-side navigation (click links, don't just navigate) โ catches routing issues
- Check for CLS on pages with dynamic content
Rails
- Check for N+1 query warnings in console (dev mode)
- Verify CSRF token presence in forms
- Test Turbo/Stimulus integration
SPA (React, Vue, Angular)
- Use page snapshot for navigation โ link enumeration misses client-side routes
- Check for stale state (navigate away and back)
- Test browser back/forward
- Check for memory leaks in console after extended use
Important Rules
- Repro is everything. Every issue needs at least one screenshot.
- Verify before documenting. Retry once to confirm reproducibility.
- Never include credentials. Write
[REDACTED] for passwords.
- Write incrementally. Append each issue as you find it.
- Never read source code. Test as a user, not a developer.
- Check console after every interaction.
- Test like a user. Use realistic data.
- Depth over breadth. 5-10 well-documented issues > 20 vague ones.