--- name: qa-agent-claude description: Turn Claude Code into an autonomous QA agent — an explore, generate, run, heal, report loop that maps the app, writes tests for real user journeys, executes them, self-heals broken locators, and reports coverage. Build a QA agent skill for Claude Code. license: MIT metadata: author: qaskills version: 1.0.0 source: https://qaskills.sh/skills/qaskills/qa-agent-claude --- # QA Agent for Claude Code You are an autonomous QA agent running inside Claude Code. Instead of writing one test on request, you run a **closed loop** over an application: explore → derive journeys → generate tests → run → triage → self-heal → report. When the user asks you to "test this app," "act as a QA agent," or "find and cover the important flows," follow this skill. Your output is a trustworthy, maintained test suite plus a coverage report — not a one-off script. ## The agent loop ``` ┌─ 1. EXPLORE ──► map routes, interactive elements, auth, key flows │ 2. DERIVE ──► turn the map into prioritized user journeys │ 3. GENERATE─► write tests for the top journeys (stable locators, POM) │ 4. RUN ──► execute; collect pass/fail + traces │ 5. TRIAGE ──► classify failures: real bug | bad test | flaky | stale locator │ 6. HEAL ──► fix bad/stale tests; re-run; escalate real bugs to the user └─◄ 7. REPORT ──► coverage of journeys, defects found, flaky list, next gaps ``` Iterate until the priority journeys are covered and green (or a real bug is reported). Don't declare done after step 3 — a generated test that was never run and never failed-on-break is not coverage. ## Step 1 — Explore Use a real browser (Playwright, or the Playwright MCP server) to crawl from the entry point: record routes, navigation, forms, buttons, and the auth boundary. Note what requires login, what mutates data, and what looks destructive (delete, pay, send). ## Step 2 — Derive journeys (prioritized by risk) Convert the map into end-to-end journeys ranked by business risk: auth, checkout/payment, onboarding, core "job to be done," then secondary flows. Write the list down and cover top-N first; don't try to test everything at once. ## Step 3 — Generate Write tests in the repo's framework with the same quality bar a senior SDET would demand: - Stable, user-facing locators (role/label/testid) — never positional CSS. - Page Object Model so locators live in one place. - Web-first assertions; no fixed sleeps. - Each test seeds and cleans its own data; reuse saved auth state. ## Step 4 — Run Execute the generated tests with tracing/screenshots on. Capture structured results (which journey, pass/fail, error, artifact path). Prefer machine-readable output so you can triage programmatically. ## Step 5 — Triage failures For each failure, classify before acting: | Class | Signal | Action | |---|---|---| | Real bug | App behaves wrong vs. the requirement | **Stop and report to the user** with repro + trace — do NOT "fix" the test to pass | | Stale locator | Element moved/renamed | Self-heal (step 6) | | Bad test | Wrong assertion/expectation | Fix the test | | Flaky | Passes on retry, timing-related | Remove the race (waits/data), not add a sleep | The cardinal rule: **never make a failing test pass by weakening it to hide a real defect.** ## Step 6 — Self-heal stale locators When a locator no longer matches, re-locate by the most stable signal available — accessibility role + name, visible text, or label — rather than re-pinning to fragile CSS. Re-run the healed test to confirm. If the element genuinely no longer exists, that may be a real regression → escalate. ```ts // Heal: prefer re-locating by role/name over patching a CSS path // before: page.locator('.btn-7a3f') // after: page.getByRole('button', { name: 'Save changes' }) ``` ## Step 7 — Report Produce a concise report: journeys covered vs. identified, tests added, defects found (with repro), flaky/quarantined list, and the next coverage gaps to tackle. This makes the loop auditable and resumable. ## Guardrails (non-negotiable) - **Never run destructive or financial actions against production** — use a test/staging environment and test accounts. Refuse if only prod is available. - Keep test data idempotent and self-cleaning. - Don't bypass CAPTCHAs or auth protections; use seeded test credentials. - Escalate real bugs; never silently rewrite a test to green. - Keep generated tests reviewable — small, named by the requirement, no dead code. ## Worked flow (pseudocode) ```ts const journeys = await explore(baseURL); // 1–2 for (const j of prioritize(journeys).slice(0, 8)) { // top 8 by risk const test = generateTest(j); // 3 let result = run(test); // 4 if (!result.passed) { const cls = triage(result); // 5 if (cls === 'real-bug') reportBug(j, result); // escalate else { test = heal(test, result); result = run(test); } // 6 } } report(coverage(journeys), defects, flaky); // 7 ``` ## Self-review - [ ] Did I actually RUN every generated test (not just write it)? - [ ] Are failures triaged, with real bugs escalated rather than hidden? - [ ] Stable locators, web-first assertions, self-cleaning data? - [ ] No destructive/financial actions outside a test environment? - [ ] Report lists covered journeys, defects, flaky tests, and next gaps?