qaa-agent 1.7.4 → 1.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +1 -1
- package/agents/qa-pipeline-orchestrator.md +47 -0
- package/agents/qaa-analyzer.md +41 -0
- package/agents/qaa-bug-detective.md +95 -0
- package/agents/qaa-codebase-mapper.md +3 -0
- package/agents/qaa-e2e-runner.md +86 -0
- package/agents/qaa-executor.md +98 -0
- package/agents/qaa-planner.md +41 -0
- package/agents/qaa-testid-injector.md +68 -0
- package/agents/qaa-validator.md +47 -0
- package/commands/qa-audit.md +7 -0
- package/commands/qa-create-test.md +30 -0
- package/commands/qa-fix.md +4 -0
- package/commands/qa-map.md +2 -0
- package/package.json +1 -1
- package/bin/install.cjs +0 -212
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,31 @@
|
|
|
3
3
|
|
|
4
4
|
All notable changes to QAA (QA Automation Agent) are documented here.
|
|
5
5
|
|
|
6
|
+
## [1.8.0] - 2026-04-13
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **Active verification checklist in every agent** — all 8 pipeline agents now end their body with a `## Before completing any task, verify each item actively:` section that forces the agent to run real `ls` + `cat` + `grep` commands against `.qa-output/` artifacts, the Locator Registry, codebase map documents, and `MY_PREFERENCES.md` before closing the task. The output of those commands lands in the subagent's context (recency effect), so the model cannot skip reading inputs or leave outputs unwritten without the verification failing.
|
|
11
|
+
- **`skills:` declared in YAML frontmatter for every agent** — `qaa-analyzer`, `qaa-planner`, `qaa-executor`, `qaa-validator`, `qaa-e2e-runner`, `qaa-bug-detective`, `qaa-testid-injector`, `qaa-codebase-mapper`, `qa-pipeline-orchestrator`. Claude Code now injects the matching SKILL.md content at the start of the subagent's context when the Task tool spawns it. Previously subagents spawned with empty context and ignored the skill entirely.
|
|
12
|
+
- **Non-negotiable rules section in `qaa-bug-detective`** — explicit rules for Locator Registry persistence and MY_PREFERENCES.md updates, placed mid-body as redundant reinforcement between the frontmatter (start) and the active checklist (end).
|
|
13
|
+
- **`MY_PREFERENCES.md` reads propagated across slash commands** — `qa-create-test`, `qa-fix`, `qa-audit`, `qa-map` now pass `~/.claude/qaa/MY_PREFERENCES.md` to every spawned agent via `files_to_read`.
|
|
14
|
+
- **Locator Registry reads propagated** — `qa-fix` and `qa-audit` now pass `.qa-output/locators/` to bug-detective, e2e-runner, and validator subagents.
|
|
15
|
+
- **Playwright MCP usage is now non-negotiable in 4 agents** — `qaa-e2e-runner`, `qaa-testid-injector`, `qaa-bug-detective`, `qaa-executor` now hardcode Non-negotiable rules in their body that make live browser interaction via Playwright MCP **mandatory** (not optional) under the appropriate conditions. Previously agents sometimes skipped MCP calls even when the skill described them, because the description was advisory rather than enforced.
|
|
16
|
+
- **MCP evidence files** at `.qa-output/mcp-evidence/{agent-name}-session.md` — every MCP-using agent now writes a structured evidence file per session logging `session_start`, `session_end`, URLs navigated, snapshots/screenshots taken, interactions performed, and `browser_closed: true`. The active verification checklist at the end of each agent runs `ls` + `grep` on this evidence file; missing or empty file = invalid run = hard failure.
|
|
17
|
+
- **Skip-reason tracking** — when MCP is legitimately skipped (no `app_url`, non-E2E failure, MCP not connected), agents must document the skip reason in their primary report (TESTID_AUDIT_REPORT.md / FAILURE_CLASSIFICATION_REPORT.md). Silent skips are no longer permitted.
|
|
18
|
+
- **Locator resolution priority chain — invention is forbidden** — `qaa-executor`, `qaa-e2e-runner`, and `qaa-bug-detective` now enforce a strict priority order when writing any locator: (1) Locator Registry first, (2) frontend source code `grep` second, (3) Playwright MCP live DOM snapshot third, (4) HALT if nothing resolvable. Agents MUST NOT invent `data-testid` values or guess CSS selectors. Every locator written to a generated file requires `source: registry | codebase | mcp` attribution in the MCP evidence file — anything else triggers file deletion or revert.
|
|
19
|
+
- **Priority hit counts logged** — MCP evidence files now track `priority1_hits` (registry reuse), `priority2_hits` (source extraction), `priority3_hits` (MCP discovery), and `priority4_halts` (unresolvable elements), giving a full audit trail of where every locator came from.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- **Agent reliability pattern: triple reinforcement** — every critical rule is now reinforced three times: (1) `skills:` frontmatter injection at the start of context, (2) `required_reading` + mid-body non-negotiable rules, (3) active `ls`/`cat`/`grep` verification at the end. This closes the "lost in the middle" attention gap documented in long-context LLM research.
|
|
24
|
+
- **`qaa-bug-detective`, `qaa-executor`, `qaa-e2e-runner`, `qaa-validator`** — existing active checklists extended with `.qa-output/` specific items (generation plan, test inventory, codebase map, validation layers, failure classification evidence).
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **Subagent skill loss** — when a parent agent spawned a subagent via `Task()`, the subagent ran with fresh context and ignored the skill entirely (it had no way to know a skill existed). Declaring `skills:` in the YAML frontmatter fixes this at the Claude Code loader level.
|
|
29
|
+
- **Artifact-read drift** — agents would sometimes reference `.qa-output/` artifacts in their reasoning without actually reading them. The active `grep` on specific content (e.g. "RISK_MAP HIGH items", "VALIDATION_REPORT confidence level") forces real consumption.
|
|
30
|
+
|
|
6
31
|
## [1.7.0] - 2026-04-02
|
|
7
32
|
|
|
8
33
|
### Added
|
package/README.md
CHANGED
|
@@ -43,7 +43,7 @@ npx qaa-agent
|
|
|
43
43
|
The interactive installer:
|
|
44
44
|
|
|
45
45
|
1. Copies agents, commands, skills, templates, and workflows into your runtime directory
|
|
46
|
-
2. Configures the [Playwright MCP](https://
|
|
46
|
+
2. Configures the [Playwright MCP](https://www.npmjs.com/package/@playwright/mcp) server in your user-scope config (`~/.claude.json`) so it's available in **all projects**
|
|
47
47
|
3. Merges required permissions into `settings.json`
|
|
48
48
|
|
|
49
49
|
**Supported runtimes:** Claude Code, OpenCode
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qa-pipeline-orchestrator
|
|
3
|
+
description: Single orchestrator for the QA automation pipeline
|
|
4
|
+
skills:
|
|
5
|
+
- qa-workflow-documenter
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
<purpose>
|
|
2
9
|
Single orchestrator for the QA automation pipeline. Coordinates all 7 agent types (scanner, analyzer, planner, executor, validator, bug-detective, testid-injector) across 3 workflow options. Owns all pipeline state transitions -- agents never update state directly. The orchestrator sets stage status to 'running' before spawning an agent and 'complete' or 'failed' after the agent returns.
|
|
3
10
|
|
|
@@ -1376,3 +1383,43 @@ Before this orchestrator is considered complete, verify:
|
|
|
1376
1383
|
4. Checkpoints pause when appropriate and auto-approve when safe
|
|
1377
1384
|
5. Failure in any stage stops the pipeline cleanly with actionable error message
|
|
1378
1385
|
</success_criteria>
|
|
1386
|
+
|
|
1387
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
1388
|
+
|
|
1389
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
1390
|
+
|
|
1391
|
+
```bash
|
|
1392
|
+
echo "=== PIPELINE ORCHESTRATOR CHECKLIST START ==="
|
|
1393
|
+
echo "1. Pipeline state file:"
|
|
1394
|
+
ls .planning/STATE.md 2>/dev/null || echo "STATE_FILE_NOT_FOUND"
|
|
1395
|
+
echo "2. Stage status fields:"
|
|
1396
|
+
grep -E "scan_status|analyze_status|generate_status|validate_status|deliver_status" .planning/STATE.md 2>/dev/null || echo "NO_STATUS_FIELDS"
|
|
1397
|
+
echo "3. All .qa-output/ artifacts:"
|
|
1398
|
+
ls .qa-output/ 2>/dev/null || echo "QA_OUTPUT_EMPTY"
|
|
1399
|
+
echo "4. SCAN_MANIFEST.md (always required):"
|
|
1400
|
+
ls .qa-output/SCAN_MANIFEST.md 2>/dev/null || echo "NO_SCAN_MANIFEST"
|
|
1401
|
+
echo "5. Codebase map document count:"
|
|
1402
|
+
ls .qa-output/codebase/ 2>/dev/null | wc -l || echo "NO_CODEBASE_MAP"
|
|
1403
|
+
echo "6. Analyzer artifacts:"
|
|
1404
|
+
ls .qa-output/QA_ANALYSIS.md .qa-output/TEST_INVENTORY.md 2>/dev/null || echo "NO_ANALYZER_ARTIFACTS"
|
|
1405
|
+
echo "7. TestID audit report:"
|
|
1406
|
+
ls .qa-output/TESTID_AUDIT_REPORT.md 2>/dev/null || echo "NO_TESTID_REPORT"
|
|
1407
|
+
echo "8. Generation plan:"
|
|
1408
|
+
ls .qa-output/GENERATION_PLAN.md 2>/dev/null || echo "NO_GENERATION_PLAN"
|
|
1409
|
+
echo "9. Validation report:"
|
|
1410
|
+
ls .qa-output/VALIDATION_REPORT.md 2>/dev/null || echo "NO_VALIDATION_REPORT"
|
|
1411
|
+
echo "10. E2E + bug-detective reports:"
|
|
1412
|
+
ls .qa-output/E2E_RUN_REPORT.md .qa-output/FAILURE_CLASSIFICATION_REPORT.md 2>/dev/null || echo "NO_E2E_REPORTS"
|
|
1413
|
+
echo "11. State transitions with timestamps:"
|
|
1414
|
+
grep -cE "^- |^[0-9]+\." .planning/STATE.md 2>/dev/null || echo "NO_STATE_TRANSITIONS"
|
|
1415
|
+
echo "12. MY_PREFERENCES.md:"
|
|
1416
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
1417
|
+
echo "=== PIPELINE ORCHESTRATOR CHECKLIST END ==="
|
|
1418
|
+
```
|
|
1419
|
+
|
|
1420
|
+
**Rules:**
|
|
1421
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
1422
|
+
- If any output shows a problem (STATE_FILE_NOT_FOUND, NO_SCAN_MANIFEST), fix it before returning.
|
|
1423
|
+
- If output shows expected "not found" results (e.g., NO_TESTID_REPORT when no frontend was detected), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
1424
|
+
- Do NOT return control to the user until the block has been executed and you have read every line of output.
|
|
1425
|
+
|
package/agents/qaa-analyzer.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qaa-analyzer
|
|
3
|
+
description: Analyzes scanned repo to produce QA analysis and test inventory
|
|
4
|
+
skills:
|
|
5
|
+
- qa-repo-analyzer
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
<purpose>
|
|
2
9
|
Analyze a scanned repository to produce QA_ANALYSIS.md and TEST_INVENTORY.md -- the two primary analysis artifacts that drive all downstream test planning and generation. Consumes SCAN_MANIFEST.md (produced by the scanner agent) and CLAUDE.md (QA standards) to produce a comprehensive testability report with architecture overview, risk assessment, top 10 unit test targets, API contract targets, and a testing pyramid distribution tailored to the specific repository. Produces a pyramid-based test case inventory where every test case has a unique ID, specific target, concrete inputs, explicit expected outcome with exact values, and priority. Optionally produces QA_REPO_BLUEPRINT.md for Option 1 (dev-only) workflows when no existing QA repository exists. Spawned by the orchestrator after the scanner completes successfully via Task(subagent_type='qaa-analyzer').
|
|
3
10
|
</purpose>
|
|
@@ -537,3 +544,37 @@ The analyzer agent has completed successfully when:
|
|
|
537
544
|
5. All artifacts are committed via `node bin/qaa-tools.cjs commit`
|
|
538
545
|
6. Return to orchestrator: file paths, total test count, pyramid breakdown (unit/integration/api/e2e counts), risk count (high/medium/low)
|
|
539
546
|
</success_criteria>
|
|
547
|
+
|
|
548
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
549
|
+
|
|
550
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
551
|
+
|
|
552
|
+
```bash
|
|
553
|
+
echo "=== ANALYZER CHECKLIST START ==="
|
|
554
|
+
echo "1. SCAN_MANIFEST.md (input):"
|
|
555
|
+
ls .qa-output/SCAN_MANIFEST.md 2>/dev/null || echo "SCAN_MANIFEST_NOT_FOUND"
|
|
556
|
+
echo "2. SCAN_MANIFEST content preview:"
|
|
557
|
+
head -50 .qa-output/SCAN_MANIFEST.md 2>/dev/null || echo "SCAN_MANIFEST_EMPTY"
|
|
558
|
+
echo "3. Codebase map documents:"
|
|
559
|
+
ls .qa-output/codebase/ 2>/dev/null || echo "NO_CODEBASE_MAP"
|
|
560
|
+
echo "4. RISK_MAP.md risks:"
|
|
561
|
+
grep -E "^## |HIGH|MEDIUM|LOW" .qa-output/codebase/RISK_MAP.md 2>/dev/null | head -20 || echo "NO_RISK_MAP"
|
|
562
|
+
echo "5. CRITICAL_PATHS.md flows:"
|
|
563
|
+
grep -c "^- \|^[0-9]\+\." .qa-output/codebase/CRITICAL_PATHS.md 2>/dev/null || echo "NO_CRITICAL_PATHS"
|
|
564
|
+
echo "6. TEST_SURFACE.md entry points:"
|
|
565
|
+
grep -E "function|class|method" .qa-output/codebase/TEST_SURFACE.md 2>/dev/null | head -10 || echo "NO_TEST_SURFACE"
|
|
566
|
+
echo "7. Locator Registry:"
|
|
567
|
+
ls .qa-output/locators/ 2>/dev/null || echo "NO_LOCATORS_FOUND"
|
|
568
|
+
echo "8. Output artifacts:"
|
|
569
|
+
ls .qa-output/QA_ANALYSIS.md .qa-output/TEST_INVENTORY.md 2>/dev/null || echo "OUTPUTS_NOT_WRITTEN"
|
|
570
|
+
echo "9. MY_PREFERENCES.md:"
|
|
571
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
572
|
+
echo "=== ANALYZER CHECKLIST END ==="
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
**Rules:**
|
|
576
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
577
|
+
- If any output shows a problem (SCAN_MANIFEST_NOT_FOUND, OUTPUTS_NOT_WRITTEN), fix it before returning.
|
|
578
|
+
- If output shows expected "not found" results (e.g., NO_CODEBASE_MAP when mapper hasn't run yet), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
579
|
+
- Do NOT return control to the parent agent until the block has been executed and you have read every line of output.
|
|
580
|
+
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qaa-bug-detective
|
|
3
|
+
description: Classifies failures and fixes test code errors
|
|
4
|
+
skills:
|
|
5
|
+
- qa-bug-detective
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
<purpose>
|
|
2
9
|
Run generated tests against the actual application and classify every failure into one of four actionable categories: APPLICATION BUG, TEST CODE ERROR, ENVIRONMENT ISSUE, or INCONCLUSIVE. Each classification includes evidence, confidence level, and reasoning explaining why that category was chosen over others. Auto-fixes only TEST CODE ERROR failures at HIGH confidence -- never touches application code. Reads test source files, CLAUDE.md classification rules, and the failure-classification template. Produces FAILURE_CLASSIFICATION_REPORT.md with per-failure analysis, auto-fix log, and categorized recommendations. Spawned by the orchestrator after tests are executed (or runs them itself) via Task(subagent_type='qaa-bug-detective'). This agent actually RUNS the test suite -- it is not static analysis. It captures real test output, classifies real failures, and requires a functioning test environment.
|
|
3
10
|
</purpose>
|
|
@@ -309,6 +316,54 @@ Attempt auto-fixes for eligible failures. Strict eligibility rules apply.
|
|
|
309
316
|
**Track all auto-fix attempts** for the Auto-Fix Log section of the report.
|
|
310
317
|
</step>
|
|
311
318
|
|
|
319
|
+
## Non-negotiable rules
|
|
320
|
+
|
|
321
|
+
These rules are hardcoded in the agent body because they MUST NOT be skipped under any circumstance, regardless of whether the skill is loaded or not.
|
|
322
|
+
|
|
323
|
+
### Locator Registry persistence
|
|
324
|
+
|
|
325
|
+
After every fix loop iteration where the test **PASSES**:
|
|
326
|
+
|
|
327
|
+
1. **Save all verified locators** to `.qa-output/locators/` — write a per-feature file `.qa-output/locators/{feature}.locators.md` and update `.qa-output/locators/LOCATOR_REGISTRY.md`.
|
|
328
|
+
2. **Only save locators that were confirmed working** by a passing test. Do NOT save locators from failing tests — they may be incorrect and would contaminate the registry.
|
|
329
|
+
3. **Locator format in registry:** Each entry must include: the `data-testid` or selector value, the tier (1-4), the page/component context, and the date verified.
|
|
330
|
+
|
|
331
|
+
### MY_PREFERENCES.md persistence
|
|
332
|
+
|
|
333
|
+
After every fix where a correction contradicts CLAUDE.md defaults or reveals a user-specific pattern:
|
|
334
|
+
|
|
335
|
+
1. **Read `~/.claude/qaa/MY_PREFERENCES.md`** if it exists, before producing any output (this is also in `<required_reading>` but repeated here for emphasis).
|
|
336
|
+
2. **Save new corrections** to `~/.claude/qaa/MY_PREFERENCES.md` so future agent instances inherit the learning.
|
|
337
|
+
3. Preferences override CLAUDE.md when there is a conflict.
|
|
338
|
+
|
|
339
|
+
### Playwright MCP reproduction is mandatory for E2E failures
|
|
340
|
+
|
|
341
|
+
When an E2E test fails **and** Playwright MCP server is connected **and** an `app_url` is available, browser reproduction is **required, not optional** — classifying an E2E failure without reproducing it in the live browser produces unreliable APPLICATION BUG vs TEST CODE ERROR classifications.
|
|
342
|
+
|
|
343
|
+
1. **For each E2E failure in the test run:** call at minimum `mcp__playwright__browser_navigate` (to the failing route), `mcp__playwright__browser_snapshot` (to inspect the real DOM), and `mcp__playwright__browser_take_screenshot` (visual evidence attached to the classification).
|
|
344
|
+
2. **Skip is only permitted when:** the failure is a unit/API test (not E2E), OR no `app_url` is available, OR Playwright MCP is not connected. The skip MUST be recorded in FAILURE_CLASSIFICATION_REPORT.md under the failure's evidence section with reason (e.g., "MCP unavailable" or "no app_url").
|
|
345
|
+
3. **Persist evidence of MCP usage** to `.qa-output/mcp-evidence/qaa-bug-detective-session.md` with:
|
|
346
|
+
- `session_start: {ISO timestamp}` and `session_end: {ISO timestamp}`
|
|
347
|
+
- `failures_reproduced:` list of `{test_id, route, classification}`
|
|
348
|
+
- `snapshots_taken:` count + route
|
|
349
|
+
- `screenshots_taken:` list of screenshot paths (evidence for classifications)
|
|
350
|
+
- `browser_closed: true`
|
|
351
|
+
4. **If E2E failures exist and the evidence file is missing or empty, classifications for those failures are INVALID** — mark them INCONCLUSIVE with reason "MCP reproduction skipped" rather than making up an APPLICATION BUG / TEST CODE ERROR classification.
|
|
352
|
+
|
|
353
|
+
### Locator resolution priority when auto-fixing TEST CODE ERRORS — invention is forbidden
|
|
354
|
+
|
|
355
|
+
When a failure is classified as `TEST CODE ERROR` (wrong locator) and the agent auto-fixes the test file, the corrected locator MUST come from one of the following sources, in this exact priority order. **The agent MUST NOT invent a new `data-testid` or guess a CSS selector.**
|
|
356
|
+
|
|
357
|
+
**Priority 1 — Locator Registry:** Check `.qa-output/locators/LOCATOR_REGISTRY.md` + `.qa-output/locators/{feature}.locators.md` for the target element.
|
|
358
|
+
|
|
359
|
+
**Priority 2 — Codebase source:** `grep -rE "data-testid=|aria-label=|id=\""` the frontend source for the page where the failure occurred.
|
|
360
|
+
|
|
361
|
+
**Priority 3 — Live DOM via Playwright MCP:** Use `mcp__playwright__browser_snapshot()` on the failing route to extract the real locator. Persist to registry with tier classification.
|
|
362
|
+
|
|
363
|
+
**Priority 4 — HALT:** If nothing is resolvable, do NOT auto-fix. Re-classify the failure as `INCONCLUSIVE` with reason `locator unresolvable from registry/source/MCP`. The fix remains for the developer to address.
|
|
364
|
+
|
|
365
|
+
Every locator written during auto-fix MUST have a source attribution in the MCP evidence file: `source: registry | codebase | mcp`. A locator without attribution is invented and the auto-fix is invalid (revert it).
|
|
366
|
+
|
|
312
367
|
<step name="produce_report">
|
|
313
368
|
Write FAILURE_CLASSIFICATION_REPORT.md matching templates/failure-classification.md exactly (4 required sections).
|
|
314
369
|
|
|
@@ -477,3 +532,43 @@ The bug detective agent has completed successfully when:
|
|
|
477
532
|
8. Return values provided to orchestrator: report_path, total_failures, classification_breakdown, auto_fixes_applied, auto_fixes_verified, commit_hash
|
|
478
533
|
9. All quality gate checks pass (8 template items + 4 detective-specific items)
|
|
479
534
|
</success_criteria>
|
|
535
|
+
|
|
536
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
537
|
+
|
|
538
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
539
|
+
|
|
540
|
+
```bash
|
|
541
|
+
echo "=== BUG-DETECTIVE CHECKLIST START ==="
|
|
542
|
+
echo "1. Locator Registry:"
|
|
543
|
+
ls .qa-output/locators/ 2>/dev/null || echo "NO_LOCATORS_FOUND"
|
|
544
|
+
echo "2. MY_PREFERENCES.md:"
|
|
545
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
546
|
+
echo "3. FAILURE_CLASSIFICATION_REPORT.md:"
|
|
547
|
+
ls .qa-output/FAILURE_CLASSIFICATION_REPORT.md 2>/dev/null || echo "REPORT_NOT_WRITTEN"
|
|
548
|
+
echo "4. Classifications in report:"
|
|
549
|
+
grep -E "APPLICATION BUG|TEST CODE ERROR|ENVIRONMENT ISSUE|INCONCLUSIVE" .qa-output/FAILURE_CLASSIFICATION_REPORT.md 2>/dev/null || echo "NO_CLASSIFICATIONS_FOUND"
|
|
550
|
+
echo "5. Confidence levels:"
|
|
551
|
+
grep -E "HIGH|MEDIUM-HIGH|MEDIUM|LOW" .qa-output/FAILURE_CLASSIFICATION_REPORT.md 2>/dev/null | head -10 || echo "NO_CONFIDENCE_LEVELS"
|
|
552
|
+
echo "6. Evidence and reasoning count:"
|
|
553
|
+
grep -cE "^### |Evidence:|Reasoning:" .qa-output/FAILURE_CLASSIFICATION_REPORT.md 2>/dev/null || echo "NO_EVIDENCE_SECTIONS"
|
|
554
|
+
echo "7. Upstream reports:"
|
|
555
|
+
ls .qa-output/E2E_RUN_REPORT.md 2>/dev/null || echo "NO_E2E_RUN_REPORT"
|
|
556
|
+
ls .qa-output/VALIDATION_REPORT.md 2>/dev/null || echo "NO_VALIDATION_REPORT"
|
|
557
|
+
echo "8. MCP reproduction evidence:"
|
|
558
|
+
ls .qa-output/mcp-evidence/qaa-bug-detective-session.md 2>/dev/null || echo "NO_MCP_EVIDENCE"
|
|
559
|
+
grep -cE "failures_reproduced:|snapshots_taken:|screenshots_taken:" .qa-output/mcp-evidence/qaa-bug-detective-session.md 2>/dev/null || echo "NO_MCP_REPRODUCTION_DATA"
|
|
560
|
+
echo "9. MCP skip reasons (if any):"
|
|
561
|
+
grep -E "MCP unavailable|no app_url|MCP reproduction skipped" .qa-output/FAILURE_CLASSIFICATION_REPORT.md 2>/dev/null || echo "NO_MCP_SKIP_DOCUMENTED"
|
|
562
|
+
echo "10. Locator source attribution:"
|
|
563
|
+
grep -cE "source: registry|source: codebase|source: mcp" .qa-output/mcp-evidence/qaa-bug-detective-session.md 2>/dev/null || echo "NO_SOURCE_ATTRIBUTION"
|
|
564
|
+
echo "11. Priority 4 halts:"
|
|
565
|
+
grep -E "locator unresolvable from registry/source/MCP" .qa-output/FAILURE_CLASSIFICATION_REPORT.md 2>/dev/null || echo "NO_PRIORITY4_HALTS"
|
|
566
|
+
echo "=== BUG-DETECTIVE CHECKLIST END ==="
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
**Rules:**
|
|
570
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
571
|
+
- If any output shows a problem (REPORT_NOT_WRITTEN, NO_CLASSIFICATIONS_FOUND), fix it before returning.
|
|
572
|
+
- If output shows expected "not found" results (e.g., NO_MCP_EVIDENCE when no E2E failures existed), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
573
|
+
- Do NOT return control to the parent agent until the block has been executed and you have read every line of output.
|
|
574
|
+
|
|
@@ -3,6 +3,8 @@ name: qaa-codebase-mapper
|
|
|
3
3
|
description: Explores codebase and writes QA-focused analysis documents. Spawned by /qa-analyze or qa-start pipeline. Produces testing-oriented architecture, conventions, and risk documents.
|
|
4
4
|
tools: Read, Bash, Grep, Glob, Write
|
|
5
5
|
color: cyan
|
|
6
|
+
skills:
|
|
7
|
+
- qa-repo-analyzer
|
|
6
8
|
---
|
|
7
9
|
|
|
8
10
|
<role>
|
|
@@ -933,3 +935,4 @@ Test the highest-risk gaps first:
|
|
|
933
935
|
- [ ] No secrets or forbidden file contents leaked
|
|
934
936
|
- [ ] Confirmation returned (not document contents)
|
|
935
937
|
</success_criteria>
|
|
938
|
+
|
package/agents/qaa-e2e-runner.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qaa-e2e-runner
|
|
3
|
+
description: Runs E2E tests against live app, fixes locator mismatches
|
|
4
|
+
skills:
|
|
5
|
+
- qa-bug-detective
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
<purpose>
|
|
2
9
|
Run generated E2E test files against a live application using the Playwright browser tools. Navigate pages, capture real locators from the accessibility snapshot, compare them against the locators in generated test files, fix mismatches, and loop until tests pass or failures are classified as application bugs. This agent bridges the gap between "tests exist on disk" and "tests actually pass against the real app."
|
|
3
10
|
|
|
@@ -400,6 +407,39 @@ E2E_RUNNER_COMPLETE:
|
|
|
400
407
|
| Test runner not found | No playwright/cypress installed | Report as ENVIRONMENT ISSUE with install instructions |
|
|
401
408
|
</error_handling>
|
|
402
409
|
|
|
410
|
+
## Non-negotiable rules
|
|
411
|
+
|
|
412
|
+
These rules are hardcoded in the agent body because they MUST NOT be skipped under any circumstance, regardless of whether the skill is loaded or not.
|
|
413
|
+
|
|
414
|
+
### Playwright MCP usage is mandatory (NOT optional)
|
|
415
|
+
|
|
416
|
+
This agent's core job is to run tests against a **live browser**. That requires the Playwright MCP server. The agent MUST NOT classify a test run as complete based on static analysis, log inspection, or dry-run output alone.
|
|
417
|
+
|
|
418
|
+
1. **Every E2E test execution MUST go through Playwright MCP tools** — `mcp__playwright__browser_navigate`, `mcp__playwright__browser_snapshot`, `mcp__playwright__browser_click`, `mcp__playwright__browser_fill_form`, `mcp__playwright__browser_take_screenshot`, `mcp__playwright__browser_close`. If these tools are not available, halt and return `ENVIRONMENT_ISSUE: Playwright MCP not connected` instead of faking execution.
|
|
419
|
+
2. **Minimum required MCP operations per run:** at least one `browser_navigate` (to the app URL), at least one `browser_snapshot` (for DOM inspection), at least one `browser_take_screenshot` (for visual evidence), and exactly one `browser_close` at the end of the session.
|
|
420
|
+
3. **Persist evidence of MCP usage** to `.qa-output/mcp-evidence/qaa-e2e-runner-session.md`. The file MUST contain:
|
|
421
|
+
- `session_start: {ISO timestamp}` and `session_end: {ISO timestamp}`
|
|
422
|
+
- `urls_navigated:` list of every URL passed to `browser_navigate`
|
|
423
|
+
- `snapshots_taken:` count of `browser_snapshot` calls with route per snapshot
|
|
424
|
+
- `screenshots_taken:` list of screenshot file paths (also written to `.qa-output/screenshots/`)
|
|
425
|
+
- `interactions:` list of clicks/fills with the element identifier
|
|
426
|
+
- `browser_closed: true` confirming `browser_close` was called
|
|
427
|
+
4. **If the evidence file is missing, empty, or lists zero `browser_navigate` calls, the run is INVALID** — do not write E2E_RUN_REPORT.md and return a hard failure instead.
|
|
428
|
+
|
|
429
|
+
### Locator resolution priority when fixing failing tests — invention is forbidden
|
|
430
|
+
|
|
431
|
+
When a test fails due to a locator mismatch and the fix loop needs to update the POM or test file with a corrected locator, the runner MUST follow this priority chain. **Never invent a `data-testid` or selector that does not exist in one of the sources below.**
|
|
432
|
+
|
|
433
|
+
**Priority 1 — Locator Registry:** Check `.qa-output/locators/LOCATOR_REGISTRY.md` and `.qa-output/locators/{feature}.locators.md` for the target element. If present, use it verbatim.
|
|
434
|
+
|
|
435
|
+
**Priority 2 — Codebase source:** If not in registry, `grep -rE "data-testid=|aria-label=|id=\"" <frontend_source_dir>` for the page under test. If found, use verbatim and persist to registry.
|
|
436
|
+
|
|
437
|
+
**Priority 3 — Live DOM via Playwright MCP:** If not in registry AND not in source, call `mcp__playwright__browser_snapshot()` on the failing route and extract the real locator from the snapshot. Persist to registry with `tier` classification.
|
|
438
|
+
|
|
439
|
+
**Priority 4 — HALT (never invent):** If nothing is resolvable, mark the test as `BLOCKED: locator unresolvable` in E2E_RUN_REPORT.md with the unresolved element name. Do NOT fabricate a locator to "make the test pass". Do NOT replace the failing locator with a random guess.
|
|
440
|
+
|
|
441
|
+
Every locator written to a POM/test during fix loops MUST have a source attribution in the MCP evidence file: `source: registry | codebase | mcp`. Anything else is invention and the fix is invalid.
|
|
442
|
+
|
|
403
443
|
<success_criteria>
|
|
404
444
|
E2E runner is complete when:
|
|
405
445
|
|
|
@@ -414,3 +454,49 @@ E2E runner is complete when:
|
|
|
414
454
|
- [ ] Locator registry updated with all real locators discovered during execution (`.qa-output/locators/`)
|
|
415
455
|
- [ ] Browser session was closed
|
|
416
456
|
</success_criteria>
|
|
457
|
+
|
|
458
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
459
|
+
|
|
460
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
echo "=== E2E-RUNNER CHECKLIST START ==="
|
|
464
|
+
echo "1. E2E Run Report:"
|
|
465
|
+
ls .qa-output/E2E_RUN_REPORT.md 2>/dev/null || echo "REPORT_NOT_WRITTEN"
|
|
466
|
+
echo "2. Locator Registry:"
|
|
467
|
+
ls .qa-output/locators/ 2>/dev/null || echo "NO_LOCATORS_FOUND"
|
|
468
|
+
echo "3. Screenshots:"
|
|
469
|
+
ls .qa-output/screenshots/ 2>/dev/null || echo "NO_SCREENSHOTS"
|
|
470
|
+
echo "4. Modified POMs/tests in working tree:"
|
|
471
|
+
git status 2>/dev/null | grep -E "modified:.*(pages/|tests/)" || echo "NO_MODIFIED_FILES"
|
|
472
|
+
echo "5. MY_PREFERENCES.md:"
|
|
473
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
474
|
+
echo "6. MCP evidence file:"
|
|
475
|
+
ls .qa-output/mcp-evidence/qaa-e2e-runner-session.md 2>/dev/null || echo "NO_MCP_EVIDENCE"
|
|
476
|
+
echo "7. MCP session boundaries:"
|
|
477
|
+
grep -E "session_start:|session_end:|browser_closed: true" .qa-output/mcp-evidence/qaa-e2e-runner-session.md 2>/dev/null || echo "NO_MCP_SESSION"
|
|
478
|
+
echo "8. URLs navigated via MCP:"
|
|
479
|
+
grep -cE "^ - http|^ - /" .qa-output/mcp-evidence/qaa-e2e-runner-session.md 2>/dev/null || echo "NO_URLS_NAVIGATED"
|
|
480
|
+
echo "9. Snapshot + screenshot operations:"
|
|
481
|
+
grep -cE "browser_snapshot|browser_take_screenshot" .qa-output/mcp-evidence/qaa-e2e-runner-session.md 2>/dev/null || echo "NO_SNAPSHOT_OPS"
|
|
482
|
+
echo "10. Locator source attribution:"
|
|
483
|
+
grep -cE "source: registry|source: codebase|source: mcp" .qa-output/mcp-evidence/qaa-e2e-runner-session.md 2>/dev/null || echo "NO_SOURCE_ATTRIBUTION"
|
|
484
|
+
echo "11. Unresolvable locator blocks:"
|
|
485
|
+
grep -E "BLOCKED: locator unresolvable" .qa-output/E2E_RUN_REPORT.md 2>/dev/null || echo "NO_BLOCKED_LOCATORS"
|
|
486
|
+
echo "12. Pass/fail counts in report:"
|
|
487
|
+
grep -E "PASS|FAIL|Tests run|[0-9]+ passed|[0-9]+ failed" .qa-output/E2E_RUN_REPORT.md 2>/dev/null | head -5 || echo "NO_PASS_FAIL_COUNTS"
|
|
488
|
+
echo "13. Locator Registry entries:"
|
|
489
|
+
grep -cE "^- |^\* " .qa-output/locators/LOCATOR_REGISTRY.md 2>/dev/null || echo "NO_REGISTRY_ENTRIES"
|
|
490
|
+
echo "14. Locator tier classification:"
|
|
491
|
+
grep -E "tier: 1|tier: 2|tier: 3|tier: 4" .qa-output/locators/*.md 2>/dev/null | head -10 || echo "NO_TIER_CLASSIFICATION"
|
|
492
|
+
echo "15. Validator report (input):"
|
|
493
|
+
ls .qa-output/VALIDATION_REPORT.md 2>/dev/null || echo "NO_VALIDATION_REPORT"
|
|
494
|
+
echo "=== E2E-RUNNER CHECKLIST END ==="
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
**Rules:**
|
|
498
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
499
|
+
- If any output shows a problem (REPORT_NOT_WRITTEN, NO_MCP_EVIDENCE when browser was used), fix it before returning.
|
|
500
|
+
- If output shows expected "not found" results (e.g., NO_SCREENSHOTS when tests all passed first try), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
501
|
+
- Do NOT return control to the parent agent until the block has been executed and you have read every line of output.
|
|
502
|
+
|
package/agents/qaa-executor.md
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qaa-executor
|
|
3
|
+
description: Generates test files, POMs, fixtures and configs
|
|
4
|
+
skills:
|
|
5
|
+
- qa-template-engine
|
|
6
|
+
- qa-self-validator
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
<purpose>
|
|
2
10
|
Read the generation plan (produced by qaa-planner), TEST_INVENTORY.md, and CLAUDE.md to produce actual test files, page object models, fixtures, and configuration files. This is the most complex agent in the pipeline -- it handles framework detection, BasePage scaffolding, POM generation following strict rules, test spec writing with concrete assertions, and per-file atomic commits for maximum traceability. The executor does not decide WHAT to test (that is the planner's job) -- it decides HOW to write each test file following CLAUDE.md standards and qa-template-engine patterns.
|
|
3
11
|
|
|
@@ -593,6 +601,48 @@ EXECUTOR_COMPLETE:
|
|
|
593
601
|
```
|
|
594
602
|
</output>
|
|
595
603
|
|
|
604
|
+
## Non-negotiable rules
|
|
605
|
+
|
|
606
|
+
These rules are hardcoded in the agent body because they MUST NOT be skipped under any circumstance, regardless of whether the skill is loaded or not.
|
|
607
|
+
|
|
608
|
+
### Locator resolution priority — locator invention is forbidden
|
|
609
|
+
|
|
610
|
+
**Before writing any locator (Tier 1 `data-testid`, Tier 2 role/label, Tier 3 CSS) in a POM or E2E test, the executor MUST follow this exact priority chain. Proposing a value that exists in none of the sources below is a critical failure.**
|
|
611
|
+
|
|
612
|
+
**Priority 1 — Locator Registry (first check):**
|
|
613
|
+
- Run `ls .qa-output/locators/LOCATOR_REGISTRY.md` and `ls .qa-output/locators/{feature}.locators.md`.
|
|
614
|
+
- `grep` the target element (by page + semantic description) in those files.
|
|
615
|
+
- If a locator exists → USE IT VERBATIM. Do not modify, do not propose an alternative.
|
|
616
|
+
|
|
617
|
+
**Priority 2 — Codebase source (second check, only if not in registry):**
|
|
618
|
+
- `grep -rE "data-testid=|aria-label=|id=\"" <frontend_source_dir>` for the target page/component file.
|
|
619
|
+
- If `data-testid`, stable `id`, or semantic `aria-label` is found in source → USE IT VERBATIM. Persist to registry so future runs hit Priority 1.
|
|
620
|
+
|
|
621
|
+
**Priority 3 — Playwright MCP live DOM (third check, only if not in registry AND not in source):**
|
|
622
|
+
- Call `mcp__playwright__browser_navigate({ url: "{app_url}/{route}" })` then `mcp__playwright__browser_snapshot()` to read the rendered DOM.
|
|
623
|
+
- Extract the real locator from the snapshot (Tier 1 > Tier 2 > Tier 3 priority per CLAUDE.md).
|
|
624
|
+
- Persist discovered locator to `.qa-output/locators/{feature}.locators.md` and update `LOCATOR_REGISTRY.md` so the next run hits Priority 1.
|
|
625
|
+
|
|
626
|
+
**Priority 4 — HALT (never invent):**
|
|
627
|
+
- If registry has no entry, source has no stable attribute, AND (MCP is unavailable OR `app_url` is missing), the agent MUST HALT for that element.
|
|
628
|
+
- Return `BLOCKED: locator unresolvable for {page}:{element} — registry empty, source has no testid/aria, MCP unavailable. Options: (a) run qa-testid to inject, (b) provide app_url, (c) connect Playwright MCP.`
|
|
629
|
+
- Do NOT invent a `data-testid` value. Do NOT propose a CSS selector based on a guess. Do NOT write the POM/test file with placeholder locators.
|
|
630
|
+
|
|
631
|
+
### Playwright MCP evidence file (mandatory when MCP is used)
|
|
632
|
+
|
|
633
|
+
When Priority 3 is invoked (MCP lookup), persist evidence to `.qa-output/mcp-evidence/qaa-executor-session.md` with:
|
|
634
|
+
- `session_start: {ISO timestamp}` and `session_end: {ISO timestamp}`
|
|
635
|
+
- `pages_validated:` list of `{page_name, url, locators_discovered_count, source: registry|codebase|mcp}`
|
|
636
|
+
- `snapshots_taken:` count + route
|
|
637
|
+
- `locators_discovered_via_mcp:` list of locators found via MCP (these MUST also appear in `.qa-output/locators/`)
|
|
638
|
+
- `priority1_hits:` count (reused from registry)
|
|
639
|
+
- `priority2_hits:` count (extracted from source)
|
|
640
|
+
- `priority3_hits:` count (discovered via MCP)
|
|
641
|
+
- `priority4_halts:` list of unresolvable elements (if any)
|
|
642
|
+
- `browser_closed: true`
|
|
643
|
+
|
|
644
|
+
**If E2E/POM files were generated AND the evidence file shows `priority3_hits > 0` but the registry was not updated, the generation is INVALID** — delete files and re-run. Every MCP-discovered locator MUST be persisted.
|
|
645
|
+
|
|
596
646
|
<quality_gate>
|
|
597
647
|
Before considering the executor's work complete, verify ALL of the following.
|
|
598
648
|
|
|
@@ -649,3 +699,51 @@ The executor agent has completed successfully when:
|
|
|
649
699
|
8. All quality gate checks pass
|
|
650
700
|
9. Return values provided to orchestrator: files_created, total_files, commit_count, features_covered, test_case_count
|
|
651
701
|
</success_criteria>
|
|
702
|
+
|
|
703
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
704
|
+
|
|
705
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
706
|
+
|
|
707
|
+
```bash
|
|
708
|
+
echo "=== EXECUTOR CHECKLIST START ==="
|
|
709
|
+
echo "1. Generated test files, POMs, fixtures:"
|
|
710
|
+
ls tests/ pages/ fixtures/ 2>/dev/null || echo "NO_TEST_FILES_FOUND"
|
|
711
|
+
echo "2. BasePage inheritance:"
|
|
712
|
+
grep -rE "class BasePage|extends BasePage" pages/ 2>/dev/null || echo "NO_BASEPAGE_FOUND"
|
|
713
|
+
echo "3. Test framework config:"
|
|
714
|
+
ls *.config.* 2>/dev/null || echo "NO_CONFIG_FOUND"
|
|
715
|
+
echo "4. MY_PREFERENCES.md:"
|
|
716
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
717
|
+
echo "5. Locator Registry:"
|
|
718
|
+
ls .qa-output/locators/ 2>/dev/null || echo "NO_LOCATORS_FOUND"
|
|
719
|
+
echo "6. Generation plan and test inventory inputs:"
|
|
720
|
+
ls .qa-output/GENERATION_PLAN.md .qa-output/TEST_INVENTORY.md 2>/dev/null || echo "INPUTS_NOT_FOUND"
|
|
721
|
+
echo "7. Test case count from inventory:"
|
|
722
|
+
grep -cE "^\| (UT|INT|API|E2E)-" .qa-output/TEST_INVENTORY.md 2>/dev/null || echo "NO_TEST_CASES_COUNTED"
|
|
723
|
+
echo "8. Generation plan tasks consumed:"
|
|
724
|
+
grep -E "task_id|files_to_create" .qa-output/GENERATION_PLAN.md 2>/dev/null | head -20 || echo "NO_PLAN_TASKS"
|
|
725
|
+
echo "9. Codebase map documents:"
|
|
726
|
+
ls .qa-output/codebase/ 2>/dev/null || echo "NO_CODEBASE_MAP"
|
|
727
|
+
echo "10. CODE_PATTERNS.md patterns:"
|
|
728
|
+
grep -E "pattern|convention|style" .qa-output/codebase/CODE_PATTERNS.md 2>/dev/null | head -5 || echo "NO_CODE_PATTERNS"
|
|
729
|
+
echo "11. Tier 1 locator usage in generated code:"
|
|
730
|
+
grep -cE "data-testid|getByTestId|getByRole|findByRole" tests/ pages/ -r 2>/dev/null || echo "NO_TIER1_LOCATORS"
|
|
731
|
+
echo "12. MCP evidence file:"
|
|
732
|
+
ls .qa-output/mcp-evidence/qaa-executor-session.md 2>/dev/null || echo "NO_MCP_EVIDENCE"
|
|
733
|
+
echo "13. Locator priority chain hits:"
|
|
734
|
+
grep -E "priority1_hits:|priority2_hits:|priority3_hits:|priority4_halts:" .qa-output/mcp-evidence/qaa-executor-session.md 2>/dev/null || echo "NO_PRIORITY_HITS"
|
|
735
|
+
echo "14. Locator source attribution:"
|
|
736
|
+
grep -cE "source: registry|source: codebase|source: mcp" .qa-output/mcp-evidence/qaa-executor-session.md 2>/dev/null || echo "NO_SOURCE_ATTRIBUTION"
|
|
737
|
+
echo "15. MCP session boundaries:"
|
|
738
|
+
grep -E "session_start:|browser_closed: true" .qa-output/mcp-evidence/qaa-executor-session.md 2>/dev/null || echo "NO_MCP_SESSION"
|
|
739
|
+
echo "16. Priority 4 halts (unresolvable locators):"
|
|
740
|
+
grep -E "BLOCKED: locator unresolvable" .qa-output/mcp-evidence/qaa-executor-session.md 2>/dev/null || echo "NO_PRIORITY4_HALTS"
|
|
741
|
+
echo "=== EXECUTOR CHECKLIST END ==="
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
**Rules:**
|
|
745
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
746
|
+
- If any output shows a problem (NO_TEST_FILES_FOUND after generation, INPUTS_NOT_FOUND), fix it before returning.
|
|
747
|
+
- If output shows expected "not found" results (e.g., NO_MCP_EVIDENCE when no app_url was provided), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
748
|
+
- Do NOT return control to the parent agent until the block has been executed and you have read every line of output.
|
|
749
|
+
|
package/agents/qaa-planner.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qaa-planner
|
|
3
|
+
description: Produces structured generation plan from test inventory
|
|
4
|
+
skills:
|
|
5
|
+
- qa-template-engine
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
<purpose>
|
|
2
9
|
Read TEST_INVENTORY.md and QA_ANALYSIS.md to produce a structured generation plan that maps every test case to an output file, grouped by feature domain with explicit task dependencies. This agent is the bridge between "what tests are needed" (from the analyzer) and "tests exist on disk" (from the executor). It is spawned by the orchestrator after the analyzer completes successfully via Task(subagent_type='qaa-planner'). The planner does NOT produce test files -- it produces a plan that the executor consumes. The generation plan is an internal artifact with no template; the planner defines its own output format documented in the <output> section below.
|
|
3
10
|
</purpose>
|
|
@@ -403,3 +410,37 @@ The planner agent has completed successfully when:
|
|
|
403
410
|
8. Return values provided to orchestrator: file_path, total_tasks, total_files, feature_count, dependency_depth, test_case_count, commit_hash
|
|
404
411
|
9. All quality gate checks pass
|
|
405
412
|
</success_criteria>
|
|
413
|
+
|
|
414
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
415
|
+
|
|
416
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
417
|
+
|
|
418
|
+
```bash
|
|
419
|
+
echo "=== PLANNER CHECKLIST START ==="
|
|
420
|
+
echo "1. Primary inputs:"
|
|
421
|
+
ls .qa-output/TEST_INVENTORY.md .qa-output/QA_ANALYSIS.md 2>/dev/null || echo "INPUTS_NOT_FOUND"
|
|
422
|
+
echo "2. Test case count from inventory:"
|
|
423
|
+
grep -cE "^\| (UT|INT|API|E2E)-" .qa-output/TEST_INVENTORY.md 2>/dev/null || echo "NO_TEST_CASES_COUNTED"
|
|
424
|
+
echo "3. Architecture overview from QA_ANALYSIS:"
|
|
425
|
+
grep -E "^### |system_type|framework|language" .qa-output/QA_ANALYSIS.md 2>/dev/null | head -15 || echo "NO_ARCHITECTURE_OVERVIEW"
|
|
426
|
+
echo "4. Pyramid percentages:"
|
|
427
|
+
grep -E "Unit [0-9]+%|Integration [0-9]+%|API [0-9]+%|E2E [0-9]+%" .qa-output/QA_ANALYSIS.md 2>/dev/null || echo "NO_PYRAMID_PERCENTAGES"
|
|
428
|
+
echo "5. Codebase map documents:"
|
|
429
|
+
ls .qa-output/codebase/ 2>/dev/null || echo "NO_CODEBASE_MAP"
|
|
430
|
+
echo "6. TESTABILITY.md mock complexity:"
|
|
431
|
+
grep -E "pure function|stateful" .qa-output/codebase/TESTABILITY.md 2>/dev/null | head -10 || echo "NO_TESTABILITY"
|
|
432
|
+
echo "7. Locator Registry:"
|
|
433
|
+
ls .qa-output/locators/ 2>/dev/null || echo "NO_LOCATORS_FOUND"
|
|
434
|
+
echo "8. Generation plan output:"
|
|
435
|
+
ls .qa-output/GENERATION_PLAN.md 2>/dev/null || echo "PLAN_NOT_WRITTEN"
|
|
436
|
+
echo "9. MY_PREFERENCES.md:"
|
|
437
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
438
|
+
echo "=== PLANNER CHECKLIST END ==="
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
**Rules:**
|
|
442
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
443
|
+
- If any output shows a problem (INPUTS_NOT_FOUND, PLAN_NOT_WRITTEN), fix it before returning.
|
|
444
|
+
- If output shows expected "not found" results (e.g., NO_CODEBASE_MAP when mapper hasn't run), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
445
|
+
- Do NOT return control to the parent agent until the block has been executed and you have read every line of output.
|
|
446
|
+
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qaa-testid-injector
|
|
3
|
+
description: Scans and injects data-testid attributes in frontend components
|
|
4
|
+
skills:
|
|
5
|
+
- qa-testid-injector
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
<purpose>
|
|
2
9
|
Scan frontend component files in a developer repository, audit every interactive UI element for `data-testid` coverage, and inject missing `data-testid` attributes following the `{context}-{description}-{element-type}` naming convention. Reads SCAN_MANIFEST.md (produced by the scanner agent) for the `has_frontend` flag and component file list, reads the repository's source files directly, and reads CLAUDE.md for the data-testid Convention section. Produces TESTID_AUDIT_REPORT.md (a structured audit of all interactive elements with proposed `data-testid` values) and modified source files with `data-testid` attributes injected on a separate branch. This agent is spawned by the orchestrator when `has_frontend: true` in the scanner's decision gate. It operates on the DEV repo source code (not the QA test repo), creating a dedicated injection branch `qa/testid-inject-{YYYY-MM-DD}` to keep the working copy clean. The user merges the injection branch if approved.
|
|
3
10
|
</purpose>
|
|
@@ -601,6 +608,25 @@ INJECTOR_SKIPPED:
|
|
|
601
608
|
```
|
|
602
609
|
</output>
|
|
603
610
|
|
|
611
|
+
## Non-negotiable rules
|
|
612
|
+
|
|
613
|
+
These rules are hardcoded in the agent body because they MUST NOT be skipped under any circumstance, regardless of whether the skill is loaded or not.
|
|
614
|
+
|
|
615
|
+
### Playwright MCP usage is mandatory when app_url is provided
|
|
616
|
+
|
|
617
|
+
When an `app_url` is available in the orchestrator prompt (or provided via `--app-url` flag), live DOM verification via Playwright MCP is **required, not optional**. Source-only scans miss dynamically rendered elements, conditionally shown components, and third-party injections.
|
|
618
|
+
|
|
619
|
+
1. **If `app_url` is available, the agent MUST call Playwright MCP tools** — at minimum `mcp__playwright__browser_navigate` (once per unique route from SCAN_MANIFEST.md) and `mcp__playwright__browser_snapshot` (once per navigated route). If MCP tools are unavailable, halt with `ENVIRONMENT_ISSUE: Playwright MCP not connected` instead of falling back to source-only.
|
|
620
|
+
2. **Skipping MCP verification is only permitted when `app_url` is not provided**, and this skip MUST be explicitly recorded in TESTID_AUDIT_REPORT.md under a "Live DOM Verification" section with reason "no app_url provided".
|
|
621
|
+
3. **Persist evidence of MCP usage** to `.qa-output/mcp-evidence/qaa-testid-injector-session.md` with:
|
|
622
|
+
- `session_start: {ISO timestamp}` and `session_end: {ISO timestamp}`
|
|
623
|
+
- `app_url:` base URL provided
|
|
624
|
+
- `routes_navigated:` list of every route passed to `browser_navigate`
|
|
625
|
+
- `snapshots_taken:` count + route per snapshot
|
|
626
|
+
- `dynamic_elements_found:` count of elements present in DOM but absent from source scan (these trigger extra injections)
|
|
627
|
+
- `browser_closed: true`
|
|
628
|
+
4. **If app_url is provided but the evidence file is missing or lists zero navigations, the audit is INVALID** — TESTID_AUDIT_REPORT.md must not be produced and the agent must return a hard failure.
|
|
629
|
+
|
|
604
630
|
<quality_gate>
|
|
605
631
|
Before considering this agent's work complete, verify ALL of the following.
|
|
606
632
|
|
|
@@ -641,3 +667,45 @@ The testid-injector agent has completed successfully when:
|
|
|
641
667
|
9. Structured return values provided to orchestrator: report_path, changelog_path, branch name, coverage scores (before/after), element counts, validation status, commit hash
|
|
642
668
|
10. All quality gate checks pass (8 template items + 6 injector-specific items)
|
|
643
669
|
</success_criteria>
|
|
670
|
+
|
|
671
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
672
|
+
|
|
673
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
674
|
+
|
|
675
|
+
```bash
|
|
676
|
+
echo "=== TESTID-INJECTOR CHECKLIST START ==="
|
|
677
|
+
echo "1. SCAN_MANIFEST.md (input):"
|
|
678
|
+
ls .qa-output/SCAN_MANIFEST.md 2>/dev/null || echo "SCAN_MANIFEST_NOT_FOUND"
|
|
679
|
+
echo "2. Frontend detection in manifest:"
|
|
680
|
+
grep -E "has_frontend|component_patterns|frontend" .qa-output/SCAN_MANIFEST.md 2>/dev/null | head -10 || echo "NO_FRONTEND_DETECTION"
|
|
681
|
+
echo "3. Component file count:"
|
|
682
|
+
grep -cE "\.(tsx|jsx|vue|svelte|html)$" .qa-output/SCAN_MANIFEST.md 2>/dev/null || echo "NO_COMPONENT_FILES"
|
|
683
|
+
echo "4. Codebase map documents:"
|
|
684
|
+
ls .qa-output/codebase/ 2>/dev/null || echo "NO_CODEBASE_MAP"
|
|
685
|
+
echo "5. CODE_PATTERNS.md interactive elements:"
|
|
686
|
+
grep -E "interactive|button|input|form" .qa-output/codebase/CODE_PATTERNS.md 2>/dev/null | head -10 || echo "NO_CODE_PATTERNS"
|
|
687
|
+
echo "6. Locator Registry:"
|
|
688
|
+
ls .qa-output/locators/ 2>/dev/null || echo "NO_LOCATORS_FOUND"
|
|
689
|
+
echo "7. Output artifacts:"
|
|
690
|
+
ls .qa-output/TESTID_AUDIT_REPORT.md .qa-output/INJECTION_CHANGELOG.md 2>/dev/null || echo "OUTPUTS_NOT_WRITTEN"
|
|
691
|
+
echo "8. Coverage score in report:"
|
|
692
|
+
grep -E "Coverage Score|[0-9]+/[0-9]+" .qa-output/TESTID_AUDIT_REPORT.md 2>/dev/null | head -5 || echo "NO_COVERAGE_SCORE"
|
|
693
|
+
echo "9. MY_PREFERENCES.md:"
|
|
694
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
695
|
+
echo "10. MCP evidence file:"
|
|
696
|
+
ls .qa-output/mcp-evidence/qaa-testid-injector-session.md 2>/dev/null || echo "NO_MCP_EVIDENCE"
|
|
697
|
+
echo "11. MCP session boundaries:"
|
|
698
|
+
grep -E "session_start:|routes_navigated:|browser_closed: true" .qa-output/mcp-evidence/qaa-testid-injector-session.md 2>/dev/null || echo "NO_MCP_SESSION"
|
|
699
|
+
echo "12. Routes navigated via MCP:"
|
|
700
|
+
grep -cE "^ - http|^ - /" .qa-output/mcp-evidence/qaa-testid-injector-session.md 2>/dev/null || echo "NO_ROUTES_NAVIGATED"
|
|
701
|
+
echo "13. MCP skip documentation:"
|
|
702
|
+
grep -E "Live DOM Verification|no app_url" .qa-output/TESTID_AUDIT_REPORT.md 2>/dev/null || echo "NO_MCP_SKIP_DOCUMENTED"
|
|
703
|
+
echo "=== TESTID-INJECTOR CHECKLIST END ==="
|
|
704
|
+
```
|
|
705
|
+
|
|
706
|
+
**Rules:**
|
|
707
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
708
|
+
- If any output shows a problem (SCAN_MANIFEST_NOT_FOUND, OUTPUTS_NOT_WRITTEN), fix it before returning.
|
|
709
|
+
- If output shows expected "not found" results (e.g., NO_MCP_EVIDENCE when no app_url was provided), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
710
|
+
- Do NOT return control to the parent agent until the block has been executed and you have read every line of output.
|
|
711
|
+
|
package/agents/qaa-validator.md
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: qaa-validator
|
|
3
|
+
description: Validates generated test code across 4 layers with fix loops
|
|
4
|
+
skills:
|
|
5
|
+
- qa-self-validator
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
<purpose>
|
|
2
9
|
Validate generated test code across 4 layers (Syntax, Structure, Dependencies, Logic) and auto-fix issues with a closed-loop fix protocol. Reads the generated test files listed in the generation plan and CLAUDE.md quality standards. Produces VALIDATION_REPORT.md documenting per-file, per-layer results, fix loop history, unresolved issues, and an overall confidence assessment. Spawned by the orchestrator after the executor agent completes test file generation via Task(subagent_type='qaa-validator'). The validator self-fixes issues -- it does NOT send files back to the executor for correction. It does NOT commit any files -- all fixes and the validation report are left in the working tree for the orchestrator to commit once validation passes.
|
|
3
10
|
</purpose>
|
|
@@ -488,3 +495,43 @@ The validator agent has completed successfully when:
|
|
|
488
495
|
6. Return values provided to orchestrator: report_path, overall_status, confidence, layers_summary, fix_loops_used, issues_found, issues_fixed, unresolved_count
|
|
489
496
|
7. All quality gate checks pass (7 template items + 6 validator-specific items)
|
|
490
497
|
</success_criteria>
|
|
498
|
+
|
|
499
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
500
|
+
|
|
501
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
echo "=== VALIDATOR CHECKLIST START ==="
|
|
505
|
+
echo "1. Validation report:"
|
|
506
|
+
ls .qa-output/VALIDATION_REPORT.md 2>/dev/null || echo "REPORT_NOT_WRITTEN"
|
|
507
|
+
echo "2. Required sections in report:"
|
|
508
|
+
grep -E "^## " .qa-output/VALIDATION_REPORT.md 2>/dev/null || echo "NO_SECTIONS_FOUND"
|
|
509
|
+
echo "3. Confidence level:"
|
|
510
|
+
grep -E "HIGH|MEDIUM|LOW" .qa-output/VALIDATION_REPORT.md 2>/dev/null | head -5 || echo "NO_CONFIDENCE_LEVEL"
|
|
511
|
+
echo "4. Last commit (validator must NOT commit):"
|
|
512
|
+
git log --oneline -1 2>/dev/null || echo "NO_GIT_HISTORY"
|
|
513
|
+
echo "5. Modified files in working tree:"
|
|
514
|
+
git status 2>/dev/null | grep "modified:" || echo "NO_MODIFIED_FILES"
|
|
515
|
+
echo "6. MY_PREFERENCES.md:"
|
|
516
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
517
|
+
echo "7. Fix loop iterations:"
|
|
518
|
+
grep -c "Loop" .qa-output/VALIDATION_REPORT.md 2>/dev/null || echo "NO_FIX_LOOPS"
|
|
519
|
+
echo "8. Generation plan (input):"
|
|
520
|
+
ls .qa-output/GENERATION_PLAN.md 2>/dev/null || echo "NO_GENERATION_PLAN"
|
|
521
|
+
echo "9. Plan tasks parsed:"
|
|
522
|
+
grep -cE "files_to_create|task_id" .qa-output/GENERATION_PLAN.md 2>/dev/null || echo "NO_PLAN_TASKS"
|
|
523
|
+
echo "10. Locator Registry:"
|
|
524
|
+
ls .qa-output/locators/ 2>/dev/null || echo "NO_LOCATORS_FOUND"
|
|
525
|
+
echo "11. Four validation layers per file:"
|
|
526
|
+
grep -E "Syntax|Structure|Dependencies|Logic" .qa-output/VALIDATION_REPORT.md 2>/dev/null | head -20 || echo "NO_VALIDATION_LAYERS"
|
|
527
|
+
echo "12. TEST_INVENTORY (input):"
|
|
528
|
+
ls .qa-output/TEST_INVENTORY.md 2>/dev/null || echo "NO_TEST_INVENTORY"
|
|
529
|
+
echo "=== VALIDATOR CHECKLIST END ==="
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Rules:**
|
|
533
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
534
|
+
- If any output shows a problem (REPORT_NOT_WRITTEN, NO_VALIDATION_LAYERS), fix it before returning.
|
|
535
|
+
- If output shows expected "not found" results (e.g., NO_MODIFIED_FILES when no fixes were needed), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
536
|
+
- Do NOT return control to the parent agent until the block has been executed and you have read every line of output.
|
|
537
|
+
|
package/commands/qa-audit.md
CHANGED
|
@@ -42,6 +42,7 @@ else:
|
|
|
42
42
|
Scores across 6 dimensions: Locator Quality (20%), Assertion Specificity (20%), POM Compliance (15%), Test Coverage (20%), Naming Convention (15%), Test Data Management (10%).
|
|
43
43
|
|
|
44
44
|
1. Read `CLAUDE.md` — quality gates, locator tiers, assertion rules, POM rules, naming conventions.
|
|
45
|
+
1b. Read `~/.claude/qaa/MY_PREFERENCES.md` if it exists — user/company preferences override CLAUDE.md defaults.
|
|
45
46
|
2. Invoke validator agent in audit mode:
|
|
46
47
|
|
|
47
48
|
Task(
|
|
@@ -50,6 +51,8 @@ Task(
|
|
|
50
51
|
<execution_context>@agents/qaa-validator.md</execution_context>
|
|
51
52
|
<files_to_read>
|
|
52
53
|
- CLAUDE.md
|
|
54
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
55
|
+
- .qa-output/locators/LOCATOR_REGISTRY.md (if exists)
|
|
53
56
|
</files_to_read>
|
|
54
57
|
<parameters>
|
|
55
58
|
user_input: $ARGUMENTS
|
|
@@ -68,6 +71,7 @@ Task(
|
|
|
68
71
|
Analyze test distribution against the ideal testing pyramid from CLAUDE.md (Unit 60-70%, Integration 10-15%, API 20-25%, E2E 3-5%). Compares actual percentages to targets and produces an action plan.
|
|
69
72
|
|
|
70
73
|
1. Read `CLAUDE.md` — testing pyramid target percentages.
|
|
74
|
+
1b. Read `~/.claude/qaa/MY_PREFERENCES.md` if it exists — user/company preferences override CLAUDE.md defaults.
|
|
71
75
|
2. Invoke analyzer agent for pyramid analysis:
|
|
72
76
|
|
|
73
77
|
Task(
|
|
@@ -76,6 +80,7 @@ Task(
|
|
|
76
80
|
<execution_context>@agents/qaa-analyzer.md</execution_context>
|
|
77
81
|
<files_to_read>
|
|
78
82
|
- CLAUDE.md
|
|
83
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
79
84
|
</files_to_read>
|
|
80
85
|
<parameters>
|
|
81
86
|
user_input: $ARGUMENTS
|
|
@@ -98,6 +103,7 @@ Generate a summary report of current QA status. Adapts detail level to audience.
|
|
|
98
103
|
- `client` — coverage summary, confidence level, test pass rates, risk mitigation status
|
|
99
104
|
|
|
100
105
|
1. Read `CLAUDE.md` — testing pyramid targets, quality gates.
|
|
106
|
+
1b. Read `~/.claude/qaa/MY_PREFERENCES.md` if it exists — user/company preferences override CLAUDE.md defaults.
|
|
101
107
|
2. Invoke analyzer agent for status reporting:
|
|
102
108
|
|
|
103
109
|
Task(
|
|
@@ -106,6 +112,7 @@ Task(
|
|
|
106
112
|
<execution_context>@agents/qaa-analyzer.md</execution_context>
|
|
107
113
|
<files_to_read>
|
|
108
114
|
- CLAUDE.md
|
|
115
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
109
116
|
</files_to_read>
|
|
110
117
|
<parameters>
|
|
111
118
|
user_input: $ARGUMENTS
|
|
@@ -81,6 +81,7 @@ App URL: {url or "auto-detect"}
|
|
|
81
81
|
### FROM CODE MODE
|
|
82
82
|
|
|
83
83
|
1. Read `CLAUDE.md` — POM rules, locator tiers, assertion rules, naming conventions, quality gates.
|
|
84
|
+
1b. Read `~/.claude/qaa/MY_PREFERENCES.md` if it exists — user's personal QA preferences override CLAUDE.md defaults when there is a conflict.
|
|
84
85
|
2. Read existing analysis artifacts if available:
|
|
85
86
|
- `.qa-output/QA_ANALYSIS.md` — architecture context
|
|
86
87
|
- `.qa-output/TEST_INVENTORY.md` — pre-defined test cases for this feature
|
|
@@ -127,6 +128,7 @@ Task(
|
|
|
127
128
|
<execution_context>@agents/qaa-executor.md</execution_context>
|
|
128
129
|
<files_to_read>
|
|
129
130
|
- CLAUDE.md
|
|
131
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
130
132
|
- .qa-output/locators/LOCATOR_REGISTRY.md (if exists)
|
|
131
133
|
- .qa-output/locators/{feature}.locators.md (if exists)
|
|
132
134
|
- .qa-output/codebase/CODE_PATTERNS.md (if exists)
|
|
@@ -151,6 +153,8 @@ Task(
|
|
|
151
153
|
<execution_context>@agents/qaa-e2e-runner.md</execution_context>
|
|
152
154
|
<files_to_read>
|
|
153
155
|
- CLAUDE.md
|
|
156
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
157
|
+
- .qa-output/locators/LOCATOR_REGISTRY.md (if exists)
|
|
154
158
|
- {generated E2E test files from executor return}
|
|
155
159
|
- {generated POM files from executor return}
|
|
156
160
|
</files_to_read>
|
|
@@ -210,6 +214,7 @@ Task(
|
|
|
210
214
|
<execution_context>@agents/qaa-validator.md</execution_context>
|
|
211
215
|
<files_to_read>
|
|
212
216
|
- CLAUDE.md
|
|
217
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
213
218
|
</files_to_read>
|
|
214
219
|
<parameters>
|
|
215
220
|
user_input: $ARGUMENTS
|
|
@@ -228,6 +233,7 @@ Task(
|
|
|
228
233
|
<execution_context>@agents/qaa-executor.md</execution_context>
|
|
229
234
|
<files_to_read>
|
|
230
235
|
- CLAUDE.md
|
|
236
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
231
237
|
- .qa-output/QA_AUDIT_REPORT.md
|
|
232
238
|
- .qa-output/locators/LOCATOR_REGISTRY.md (if exists)
|
|
233
239
|
</files_to_read>
|
|
@@ -262,6 +268,7 @@ Task(
|
|
|
262
268
|
<execution_context>@agents/qaa-executor.md</execution_context>
|
|
263
269
|
<files_to_read>
|
|
264
270
|
- CLAUDE.md
|
|
271
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
265
272
|
- .qa-output/locators/LOCATOR_REGISTRY.md (if exists)
|
|
266
273
|
</files_to_read>
|
|
267
274
|
<parameters>
|
|
@@ -286,3 +293,26 @@ Task(
|
|
|
286
293
|
- Every POM extends BasePage
|
|
287
294
|
|
|
288
295
|
$ARGUMENTS
|
|
296
|
+
|
|
297
|
+
## MANDATORY verification — run ALL commands below, no exceptions, no skipping
|
|
298
|
+
|
|
299
|
+
Before returning control, copy-paste and run this ENTIRE block. Do NOT decide which commands "apply" — run all of them every time. The output confirms what happened; you do not get to assume the answer.
|
|
300
|
+
|
|
301
|
+
```bash
|
|
302
|
+
echo "=== CHECKLIST START ==="
|
|
303
|
+
echo "1. Locator Registry:"
|
|
304
|
+
ls .qa-output/locators/ 2>/dev/null || echo "NO_LOCATORS_FOUND"
|
|
305
|
+
echo "2. MY_PREFERENCES.md:"
|
|
306
|
+
cat ~/.claude/qaa/MY_PREFERENCES.md 2>/dev/null || echo "FILE_NOT_FOUND"
|
|
307
|
+
echo "3. Generated test files:"
|
|
308
|
+
find tests/ pages/ fixtures/ -type f 2>/dev/null | head -20 || echo "NO_TEST_FILES_FOUND"
|
|
309
|
+
echo "4. MCP evidence (if browser was used):"
|
|
310
|
+
ls .qa-output/mcp-evidence/ 2>/dev/null || echo "NO_MCP_EVIDENCE"
|
|
311
|
+
echo "=== CHECKLIST END ==="
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**Rules:**
|
|
315
|
+
- Run the block AS-IS. Do not modify it. Do not split it. Do not skip lines.
|
|
316
|
+
- If any output shows a problem (NO_LOCATORS when MCP was used, NO_TEST_FILES after generation), fix it before returning.
|
|
317
|
+
- If output shows expected "not found" results (e.g., NO_MCP_EVIDENCE when no browser was used), that is fine — the point is you RAN the command instead of assuming the answer.
|
|
318
|
+
- Do NOT mark this task as complete until the block has been executed and you have read every line of output.
|
package/commands/qa-fix.md
CHANGED
|
@@ -335,6 +335,8 @@ Task(
|
|
|
335
335
|
<execution_context>@agents/qaa-e2e-runner.md</execution_context>
|
|
336
336
|
<files_to_read>
|
|
337
337
|
- CLAUDE.md
|
|
338
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
339
|
+
- .qa-output/locators/LOCATOR_REGISTRY.md (if exists)
|
|
338
340
|
- {E2E test files from validated directory}
|
|
339
341
|
- {POM files from validated directory}
|
|
340
342
|
</files_to_read>
|
|
@@ -364,6 +366,8 @@ Task(
|
|
|
364
366
|
<execution_context>@agents/qaa-bug-detective.md</execution_context>
|
|
365
367
|
<files_to_read>
|
|
366
368
|
- CLAUDE.md
|
|
369
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
370
|
+
- .qa-output/locators/LOCATOR_REGISTRY.md (if exists)
|
|
367
371
|
</files_to_read>
|
|
368
372
|
<parameters>
|
|
369
373
|
user_input: $ARGUMENTS
|
package/commands/qa-map.md
CHANGED
|
@@ -99,6 +99,7 @@ Task(
|
|
|
99
99
|
<execution_context>@agents/qaa-scanner.md</execution_context>
|
|
100
100
|
<files_to_read>
|
|
101
101
|
- CLAUDE.md
|
|
102
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
102
103
|
</files_to_read>
|
|
103
104
|
<parameters>
|
|
104
105
|
user_input: $ARGUMENTS
|
|
@@ -114,6 +115,7 @@ Task(
|
|
|
114
115
|
<execution_context>@agents/qaa-analyzer.md</execution_context>
|
|
115
116
|
<files_to_read>
|
|
116
117
|
- CLAUDE.md
|
|
118
|
+
- ~/.claude/qaa/MY_PREFERENCES.md (if exists)
|
|
117
119
|
- .qa-output/SCAN_MANIFEST.md
|
|
118
120
|
- .qa-output/codebase/TESTABILITY.md (if exists)
|
|
119
121
|
- .qa-output/codebase/RISK_MAP.md (if exists)
|
package/package.json
CHANGED
package/bin/install.cjs
DELETED
|
@@ -1,212 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* QAA - QA Automation Agent Installer
|
|
4
|
-
* Run with: npx qaa-agent
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
const fs = require('fs');
|
|
8
|
-
const path = require('path');
|
|
9
|
-
const readline = require('readline');
|
|
10
|
-
|
|
11
|
-
const VERSION = require('../package.json').version;
|
|
12
|
-
const ROOT = path.resolve(__dirname, '..');
|
|
13
|
-
const HOME = process.env.HOME || process.env.USERPROFILE;
|
|
14
|
-
|
|
15
|
-
// Runtime configs
|
|
16
|
-
const RUNTIMES = {
|
|
17
|
-
'1': { name: 'Claude Code', dir: path.join(HOME, '.claude') },
|
|
18
|
-
'2': { name: 'OpenCode', dir: path.join(HOME, '.config', 'opencode') },
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
function ask(question, defaultVal) {
|
|
22
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
23
|
-
return new Promise(resolve => {
|
|
24
|
-
rl.question(question, answer => {
|
|
25
|
-
rl.close();
|
|
26
|
-
resolve(answer.trim() || defaultVal);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function copyDir(src, dest) {
|
|
32
|
-
if (!fs.existsSync(src)) return 0;
|
|
33
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
34
|
-
let count = 0;
|
|
35
|
-
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
36
|
-
const srcPath = path.join(src, entry.name);
|
|
37
|
-
const destPath = path.join(dest, entry.name);
|
|
38
|
-
if (entry.isDirectory()) {
|
|
39
|
-
count += copyDir(srcPath, destPath);
|
|
40
|
-
} else {
|
|
41
|
-
fs.copyFileSync(srcPath, destPath);
|
|
42
|
-
count++;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
return count;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
function copyFile(src, dest) {
|
|
49
|
-
if (!fs.existsSync(src)) return false;
|
|
50
|
-
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
51
|
-
fs.copyFileSync(src, dest);
|
|
52
|
-
return true;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function countEntries(dir, type) {
|
|
56
|
-
if (!fs.existsSync(dir)) return 0;
|
|
57
|
-
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
58
|
-
if (type === 'dirs') return entries.filter(e => e.isDirectory()).length;
|
|
59
|
-
return entries.filter(e => e.isFile()).length;
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function ok(msg) { console.log(` \x1b[32m✓\x1b[0m ${msg}`); }
|
|
63
|
-
function info(msg) { console.log(` ${msg}`); }
|
|
64
|
-
|
|
65
|
-
async function main() {
|
|
66
|
-
console.log('');
|
|
67
|
-
console.log(' \x1b[36m ██████╗ █████╗ █████╗ \x1b[0m');
|
|
68
|
-
console.log(' \x1b[36m██╔═══██╗██╔══██╗██╔══██╗\x1b[0m');
|
|
69
|
-
console.log(' \x1b[36m██║ ██║███████║███████║\x1b[0m');
|
|
70
|
-
console.log(' \x1b[36m██║▄▄ ██║██╔══██║██╔══██║\x1b[0m');
|
|
71
|
-
console.log(' \x1b[36m╚██████╔╝██║ ██║██║ ██║\x1b[0m');
|
|
72
|
-
console.log(' \x1b[36m ╚══▀▀═╝ ╚═╝ ╚═╝╚═╝ ╚═╝\x1b[0m');
|
|
73
|
-
console.log('');
|
|
74
|
-
console.log(` \x1b[1mQA Automation Agent\x1b[0m v${VERSION}`);
|
|
75
|
-
console.log(' Multi-agent QA pipeline for Claude Code.');
|
|
76
|
-
console.log(' Analyzes repos, generates tests, validates, and creates PRs.');
|
|
77
|
-
console.log('');
|
|
78
|
-
|
|
79
|
-
// Ask runtime
|
|
80
|
-
console.log(' Which runtime would you like to install for?');
|
|
81
|
-
console.log('');
|
|
82
|
-
console.log(' 1) Claude Code (~/.claude)');
|
|
83
|
-
console.log(' 2) OpenCode (~/.config/opencode)');
|
|
84
|
-
console.log('');
|
|
85
|
-
const runtimeChoice = await ask(' Choice [1]: ', '1');
|
|
86
|
-
const runtime = RUNTIMES[runtimeChoice] || RUNTIMES['1'];
|
|
87
|
-
|
|
88
|
-
// Ask scope
|
|
89
|
-
console.log('');
|
|
90
|
-
console.log(' Where would you like to install?');
|
|
91
|
-
console.log('');
|
|
92
|
-
console.log(` 1) Global (~/${path.relative(HOME, runtime.dir)}) - available in all projects`);
|
|
93
|
-
console.log(' 2) Local (./.claude) - this project only');
|
|
94
|
-
console.log('');
|
|
95
|
-
const scopeChoice = await ask(' Choice [1]: ', '1');
|
|
96
|
-
const isGlobal = scopeChoice !== '2';
|
|
97
|
-
const baseDir = isGlobal ? runtime.dir : path.join(process.cwd(), '.claude');
|
|
98
|
-
const qaaDir = isGlobal ? path.join(runtime.dir, 'qaa') : path.join(process.cwd(), '.claude', 'qaa');
|
|
99
|
-
|
|
100
|
-
console.log('');
|
|
101
|
-
console.log(` Installing for ${runtime.name} to ${isGlobal ? '~/' + path.relative(HOME, runtime.dir) : './.claude'}`);
|
|
102
|
-
console.log('');
|
|
103
|
-
|
|
104
|
-
// Install commands (from commands/ in package root to ~/.claude/commands/)
|
|
105
|
-
const commandsSrc = path.join(ROOT, 'commands');
|
|
106
|
-
const commandsDest = path.join(baseDir, 'commands');
|
|
107
|
-
const cmdCount = copyDir(commandsSrc, commandsDest);
|
|
108
|
-
ok(`Installed ${cmdCount} slash commands`);
|
|
109
|
-
|
|
110
|
-
// Install skills (from skills/ in package root to ~/.claude/skills/)
|
|
111
|
-
const skillsSrc = path.join(ROOT, 'skills');
|
|
112
|
-
const skillsDest = path.join(baseDir, 'skills');
|
|
113
|
-
const skillCount = copyDir(skillsSrc, skillsDest);
|
|
114
|
-
const skillDirCount = countEntries(skillsSrc, 'dirs');
|
|
115
|
-
ok(`Installed ${skillDirCount} skills (${skillCount} files)`);
|
|
116
|
-
|
|
117
|
-
// Install workflows
|
|
118
|
-
const workflowsSrc = path.join(ROOT, 'workflows');
|
|
119
|
-
const workflowsDest = path.join(qaaDir, 'workflows');
|
|
120
|
-
const wfCount = copyDir(workflowsSrc, workflowsDest);
|
|
121
|
-
ok(`Installed ${wfCount} workflows`);
|
|
122
|
-
|
|
123
|
-
// Install agents
|
|
124
|
-
const agentsSrc = path.join(ROOT, 'agents');
|
|
125
|
-
const agentsDest = path.join(qaaDir, 'agents');
|
|
126
|
-
const agentCount = copyDir(agentsSrc, agentsDest);
|
|
127
|
-
ok(`Installed ${agentCount} agent definitions`);
|
|
128
|
-
|
|
129
|
-
// Install templates
|
|
130
|
-
const templatesSrc = path.join(ROOT, 'templates');
|
|
131
|
-
const templatesDest = path.join(qaaDir, 'templates');
|
|
132
|
-
const templateCount = copyDir(templatesSrc, templatesDest);
|
|
133
|
-
ok(`Installed ${templateCount} templates`);
|
|
134
|
-
|
|
135
|
-
// Install bin
|
|
136
|
-
const binSrc = path.join(ROOT, 'bin');
|
|
137
|
-
const binDest = path.join(qaaDir, 'bin');
|
|
138
|
-
const binCount = copyDir(binSrc, binDest);
|
|
139
|
-
try { fs.unlinkSync(path.join(binDest, 'install.cjs')); } catch {}
|
|
140
|
-
ok(`Installed CLI tooling`);
|
|
141
|
-
|
|
142
|
-
// Install CLAUDE.md
|
|
143
|
-
copyFile(path.join(ROOT, 'CLAUDE.md'), path.join(qaaDir, 'CLAUDE.md'));
|
|
144
|
-
ok('Installed QA standards (CLAUDE.md)');
|
|
145
|
-
|
|
146
|
-
// Install .mcp.json (Playwright MCP server config)
|
|
147
|
-
const mcpSrc = path.join(ROOT, '.mcp.json');
|
|
148
|
-
if (fs.existsSync(mcpSrc)) {
|
|
149
|
-
// Copy to qaa dir for reference
|
|
150
|
-
copyFile(mcpSrc, path.join(qaaDir, '.mcp.json'));
|
|
151
|
-
|
|
152
|
-
// Merge MCP servers into ~/.claude.json (user-scope) so they're available in ALL projects
|
|
153
|
-
// Note: ~/.claude/.mcp.json is project-scope for ~/.claude/ only — NOT global
|
|
154
|
-
const userConfigPath = path.join(HOME, '.claude.json');
|
|
155
|
-
let userConfig = {};
|
|
156
|
-
if (fs.existsSync(userConfigPath)) {
|
|
157
|
-
try { userConfig = JSON.parse(fs.readFileSync(userConfigPath, 'utf8')); } catch {}
|
|
158
|
-
}
|
|
159
|
-
userConfig.mcpServers = userConfig.mcpServers || {};
|
|
160
|
-
const qaaMcp = JSON.parse(fs.readFileSync(mcpSrc, 'utf8'));
|
|
161
|
-
Object.assign(userConfig.mcpServers, qaaMcp.mcpServers);
|
|
162
|
-
fs.writeFileSync(userConfigPath, JSON.stringify(userConfig, null, 2));
|
|
163
|
-
ok('Installed Playwright MCP server config (user-scope — available in all projects)');
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// Write version
|
|
167
|
-
fs.writeFileSync(path.join(qaaDir, 'VERSION'), VERSION);
|
|
168
|
-
ok(`Wrote VERSION (${VERSION})`);
|
|
169
|
-
|
|
170
|
-
// Merge settings (from settings.json in package root)
|
|
171
|
-
const settingsSrc = path.join(ROOT, 'settings.json');
|
|
172
|
-
const settingsDest = path.join(baseDir, 'settings.json');
|
|
173
|
-
if (fs.existsSync(settingsSrc)) {
|
|
174
|
-
let existing = {};
|
|
175
|
-
if (fs.existsSync(settingsDest)) {
|
|
176
|
-
try { existing = JSON.parse(fs.readFileSync(settingsDest, 'utf8')); } catch {}
|
|
177
|
-
}
|
|
178
|
-
const qaaSettings = JSON.parse(fs.readFileSync(settingsSrc, 'utf8'));
|
|
179
|
-
if (qaaSettings.permissions) {
|
|
180
|
-
existing.permissions = existing.permissions || {};
|
|
181
|
-
existing.permissions.allow = [...new Set([
|
|
182
|
-
...(existing.permissions.allow || []),
|
|
183
|
-
...(qaaSettings.permissions.allow || [])
|
|
184
|
-
])];
|
|
185
|
-
}
|
|
186
|
-
fs.writeFileSync(settingsDest, JSON.stringify(existing, null, 2));
|
|
187
|
-
ok('Merged permissions into settings.json');
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
// Done
|
|
191
|
-
const total = cmdCount + skillCount + agentCount + templateCount + wfCount + binCount;
|
|
192
|
-
console.log('');
|
|
193
|
-
console.log(` \x1b[32m✓ Done!\x1b[0m Installed ${total} files.`);
|
|
194
|
-
console.log('');
|
|
195
|
-
console.log(' Open Claude Code in any project and run:');
|
|
196
|
-
console.log('');
|
|
197
|
-
console.log(' \x1b[1m/qa-start\x1b[0m Full QA pipeline (multi-agent)');
|
|
198
|
-
console.log(' \x1b[1m/qa-map\x1b[0m Codebase map + analysis');
|
|
199
|
-
console.log(' \x1b[1m/qa-create-test\x1b[0m Tests for a feature/ticket');
|
|
200
|
-
console.log(' \x1b[1m/qa-audit\x1b[0m Audit existing tests');
|
|
201
|
-
console.log(' \x1b[1m/qa-fix\x1b[0m Fix broken tests');
|
|
202
|
-
console.log(' \x1b[1m/qa-testid\x1b[0m Inject data-testid attributes');
|
|
203
|
-
console.log(' \x1b[1m/qa-pr\x1b[0m Create QA pull request');
|
|
204
|
-
console.log('');
|
|
205
|
-
console.log(` ${cmdCount} commands + ${skillDirCount} skills + ${agentCount} agents ready.`);
|
|
206
|
-
console.log('');
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
main().catch(err => {
|
|
210
|
-
console.error('Installation failed:', err.message);
|
|
211
|
-
process.exit(1);
|
|
212
|
-
});
|