From fable-it
Generic autonomous QA suite for any project — reads a test plan (markdown file or inline spec), runs all tests using Chrome CDP + iterate cycles, fixes bugs found, and produces a final QA report. Works with any web stack. Trigger with /full-qa [path-to-test-plan.md]. Use before releases, after significant changes, or whenever you want a full system health check.
How this skill is triggered — by the user, by Claude, or both
Slash command
/fable-it:full-qaThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are running an autonomous, project-agnostic QA pipeline. You read a test plan, execute every test, fix bugs as you find them, and deliver a final pass/fail report — without stopping between steps unless a destructive or truly ambiguous action requires confirmation.
You are running an autonomous, project-agnostic QA pipeline. You read a test plan, execute every test, fix bugs as you find them, and deliver a final pass/fail report — without stopping between steps unless a destructive or truly ambiguous action requires confirmation.
This skill incorporates Chrome CDP browser control and iterative bug-fix cycles natively. You do not need to invoke /chrome-cdp-control or /iterate separately.
CDP mechanics live in one shared reference — read ../references/cdp-core.md (relative to this skill's base directory) before any browser work. It canonically owns endpoint resolution (CDP_URL/APP_URL env → grounding/test plan → defaults), the action template, tab selection, the selector ladder, waits, and the failure protocol. Never restate them here; never hardcode a CDP endpoint or app port — parallel runs collide on hardcoded values.
Route guard (cdp-core.md §9): autonomous mode is for TEST ENVIRONMENTS ONLY. If any test case targets the user's authenticated real-Chrome session (their logged-in accounts — posting, sending, buying), REFUSE to run that case autonomously and re-route it to /chrome-cdp-control, whose per-write gate requires explicit user confirmation for each write. Unattended (user asleep) that case ends as BLOCKED/deferred with the reason. There is no autonomous write path on an authenticated session.
First action: identify the test plan.
/full-qa ./E2E-test-plan.md), read that file immediately.From the test plan, extract:
localhost:PORT or external URLs mentionedIf any of these are missing from the plan, infer reasonable defaults and state your assumptions before starting Phase 1.
Verify every service the test plan references is alive. Do this silently and fix anything that is down before proceeding.
For each URL in the test plan:
curl -s -o /dev/null -w "%{http_code}" <SERVICE_URL>/health
# or if no /health endpoint:
curl -s -o /dev/null -w "%{http_code}" <SERVICE_URL>
Expected: 200 (or the status code the plan specifies). Any non-200 is a failure to investigate.
Resolve the CDP endpoint per cdp-core.md §1 (env CDP_URL → grounding/test plan → the core's default), then:
curl -s "$CDP_URL/json/version" | python3 -c "import sys,json; d=json.load(sys.stdin); print('Chrome:', d.get('Browser','?'))"
If CDP fails, stop and give the user the relaunch instruction from cdp-core.md §2, then say: "Then run /full-qa again."
python3 -c "import playwright; print('playwright ok')" 2>&1 || pip3 install playwright && python3 -m playwright install chromium
Print a compact table before moving on:
PREFLIGHT
✓ Service A http://localhost:XXXX 200
✓ Service B http://localhost:YYYY 200
✓ Chrome CDP $CDP_URL Chrome/XXX
✗ Service C http://localhost:ZZZZ ECONNREFUSED ← fixing...
Do not proceed to Phase 2 if any service is down after your fix attempt.
Run any setup steps from the test plan: DB resets, seed imports, migrations, fixture loading.
If the test plan has no explicit setup steps, check for common patterns:
docker exec ... psql (Postgres via Docker/Supabase)npm run seed / yarn seedpython manage.py migrate && loaddataImportant: If setup involves destructive operations (DROP, DELETE ALL, reset), print exactly what you're about to run and wait for a "yes" from the user before executing. Exception: if the test plan explicitly says "clean slate required", proceed without confirming.
After setup, verify the expected baseline state (row counts, seed user logins, etc.) using whatever the test plan specifies. If not specified, verify at minimum that auth works for the first test credential listed.
Run every test case from the plan, in order. For each test:
▶ Running [TEST_ID] — [Test Name]✓ PASS [TEST_ID] or ✗ FAIL [TEST_ID] — [reason]Use curl for REST/GraphQL endpoints and psql/sqlite3/mysql for DB verification. Collect concrete evidence — response bodies and row counts — not assumptions.
Every browser action follows the 5-step sequence — no exceptions:
Step 1 — Screenshot (see current state) · Step 2 — Decide the single next action · Step 3 — Execute one action · Step 4 — Screenshot again to verify the expected state · Step 5 — Repeat until the scenario completes.
For every step's mechanics use cdp-core.md verbatim: the canonical action template (§4, with CDP_URL resolved, never hardcoded), tab selection (§5), the selector ladder (§6), the wait strategy (§7). One QA-specific delta on the core failure protocol (§8): after the 2-attempt limit, record FAIL for the test case, document seen-vs-expected, and continue to the next test rather than stopping the run.
Before any test step that writes, deletes, posts, sends, submits, or modifies shared state beyond the test environment, STOP and confirm with the user. Tests within a local dev environment (localhost) do not require confirmation for write operations. Authenticated real-Chrome cases never reach this gate: the route guard (top of this file / cdp-core.md §9) already re-routed them to /chrome-cdp-control.
Triggered immediately on each FAIL. Follows the diagnosis → fix → test → evaluate loop.
DIAGNOSIS: <one sentence root cause>
HYPOTHESIS: <what I believe is happening>
EVIDENCE: <logs / DB query / screenshot / response body>
FIX PLAN: <minimal code change — file:line>
Rules:
Explore subagent for broad codebase research (tracing data flows across >3 files). Keep yourself for reasoning.Re-run the specific test that failed. Collect concrete evidence:
| Task type | Verification method |
|---|---|
| API route | curl the route, check response code + body |
| DB state | Query the specific table/row |
| UI behavior | Screenshot + check URL + check text content |
| Compilation | Run tsc --noEmit or the project's build command |
RESULT: PASS | FAIL | PARTIAL
EVIDENCE: <observed output>
REMAINING ISSUES: <if partial>
NEXT ACTION: continue tests | new diagnosis cycle | escalate to user
After fixing any bug: re-run any previously-PASS test that touches the same service/component. A fix that breaks something else is worse than a known failure.
After all plan-specified tests complete, run exploratory testing as a loop that stops only after 2 consecutive dry rounds — never a fixed "top N". Each round:
Explore subagent to find untested paths:Explore subagent prompt:
"In [PROJECT_ROOT], identify likely bug-prone areas not covered by the tests run so
far (list them). Focus on:
- Unguarded edge cases in service/controller layers
- Missing error handling in critical flows
- Data display issues in UI components
- Race conditions or state management issues
For each suspicious area, propose a concrete test (what to click or API to call),
the expected behavior, and the likely failure mode.
Return a ranked list of up to 5 NEW tests (not variations of ones already run)
with: ID, description, steps, expected result."
This report is a feeder. Running under /fable-it, every result maps onto the conductor's unified report and the Go-Live verdict maps onto the DoD table — it never stands as a second, competing verdict. Standalone runs use the format directly. Either way, append each test's evidence (command · quoted output · verdict) to .taskstate/evidence.md as it happens — the conductor's claim gate and verifier read that ledger.
When all tests complete (or you've exhausted fix cycles), output:
## QA Report — [Project Name] — [Date]
### Summary
| Metric | Count |
|--------|-------|
| Tests run | N |
| Passed | N |
| Failed | N |
| Bugs fixed | N |
| Exploratory tests | N |
| Deferred | N |
### Test Results
| ID | Test Name | Result | Notes |
|-----|-----------|--------|-------|
| T01 | [Name] | ✓ PASS | |
| T02 | [Name] | ✗ FAIL | [what failed] |
| T03 | [Name] | ⚠ SKIP | [reason] |
### Bugs Fixed
| # | File:Line | Description | Fix Applied |
|---|-----------|-------------|-------------|
| 1 | src/foo.ts:42 | [what broke] | [what changed] |
### Known Issues / Deferred
- [Item]: [why deferred — needs product decision / out of scope / requires manual action]
### No silent caps
- [every test skipped, sampled, bounded, or loop stopped early, and why — or "nothing was capped"]
### Go-Live Readiness
**READY** / **NOT READY** — [one sentence verdict; under /fable-it this maps onto the conductor's DoD table rather than standing alone]
Proceed without asking:
Stop and confirm before:
DROP TABLE, DELETE FROM without a WHERE, or other destructive DB commands that aren't part of an explicit seed/reset step in the test planpkill (exception: killing a service you just started for a resilience test)Maximum autonomy: Fix bugs without asking. Re-run tests without asking. Restart services without asking. Only escalate when you've genuinely tried 3 different approaches and are stuck, or when the fix requires a product decision.
# DB query
docker exec supabase_db_supabase psql -U postgres -c "SELECT ..."
# Apply migration
docker exec -i supabase_db_supabase psql -U postgres < migration.sql
# Auth token
curl -s -X POST "http://127.0.0.1:54321/auth/v1/token?grant_type=password" \
-H "apikey: <ANON_KEY>" -H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"password"}'
# Build check
cd <project> && npm run build 2>&1 | tail -20
# Type check
npx tsc --noEmit
# Logs (if running via pm2 or similar)
pm2 logs <app-name> --lines 50
# Health
curl -s http://localhost:PORT/health
# Logs
tail -50 <output-dir>/engine.log
# Health
curl -s http://127.0.0.1:PORT/health
# Start if down
cd <project> && python3 -m uvicorn main:app --host 127.0.0.1 --port PORT &
# Django: python manage.py check; Rails: bin/rails db:migrate:status; Laravel: php artisan migrate:status
The canonical action template lives in ../references/cdp-core.md §4 — use it as-is.
Authored by DevOtts.
npx claudepluginhub devotts/fable-it --plugin fable-itHelps plan, write, review, execute, and maintain manual test cases with reproducible artifacts traceable to design documents.
Generates E2E tests from specs or Gherkin scenarios, executes them in isolated subagents, and auto-fixes application bugs when tests fail. Use after implementation to verify end-to-end behavior.