qaa-agent 1.4.0 → 1.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qaa-agent",
3
- "version": "1.4.0",
3
+ "version": "1.6.0",
4
4
  "description": "QA Automation Agent for Claude Code — multi-agent pipeline that analyzes repos, generates tests, validates, and creates PRs",
5
5
  "bin": {
6
6
  "qaa-agent": "./bin/install.cjs"
@@ -21,15 +21,21 @@
21
21
  },
22
22
  "author": "Backhaus7997",
23
23
  "license": "MIT",
24
+ "dependencies": {
25
+ "@playwright/mcp": "latest"
26
+ },
24
27
  "files": [
25
28
  "bin/",
26
29
  "agents/",
27
30
  "workflows/",
28
31
  "templates/",
32
+ "docs/",
29
33
  ".claude/commands/",
30
34
  ".claude/skills/",
31
35
  ".claude/settings.json",
36
+ ".mcp.json",
32
37
  "CLAUDE.md",
38
+ "CHANGELOG.md",
33
39
  "README.md"
34
40
  ]
35
41
  }
@@ -215,8 +215,69 @@ Generating test cases based on ticket content only (no source-level analysis).
215
215
  ```
216
216
  </step>
217
217
 
218
+ <step name="extract_locators_from_app">
219
+ ## Step 5: Check Locator Registry and Extract from Live App (Optional)
220
+
221
+ Check the locator registry for existing locators, and if needed, use Playwright MCP to extract new ones from the live app.
222
+
223
+ **Step 5a: Check existing registry**
224
+
225
+ Read `.qa-output/locators/LOCATOR_REGISTRY.md` if it exists. Check if locators for pages related to this ticket's feature already exist. If they do and no `--app-url` was provided, reuse them and skip browser extraction.
226
+
227
+ **Step 5b: When to extract from browser**
228
+ - Locators for this feature's pages are NOT in the registry, OR
229
+ - An `--app-url` argument was explicitly provided (forces re-extraction)
230
+
231
+ **When to skip entirely:**
232
+ - No app URL available, no dev server detected, AND no registry exists
233
+ - The ticket describes only backend/API functionality with no UI
234
+
235
+ **Extraction process:**
236
+
237
+ 1. Identify relevant pages from the ticket's acceptance criteria and affected components (from Step 3 and Step 4).
238
+
239
+ 2. For each relevant page, navigate and capture:
240
+ ```
241
+ mcp__playwright__browser_navigate({ url: "{app_url}/{page_path}" })
242
+ mcp__playwright__browser_snapshot()
243
+ ```
244
+
245
+ 3. If the ticket describes a user flow (e.g., "user fills form and submits"), walk through the flow:
246
+ ```
247
+ mcp__playwright__browser_fill_form({ ... })
248
+ mcp__playwright__browser_click({ element: "Submit button" })
249
+ mcp__playwright__browser_snapshot() // capture resulting page
250
+ ```
251
+
252
+ 4. From each snapshot, extract:
253
+ - All `data-testid` attributes
254
+ - ARIA roles with accessible names
255
+ - Form labels and placeholders
256
+ - Page structure and navigation elements
257
+
258
+ 5. Write per-feature locator file to `.qa-output/locators/{feature}.locators.md`:
259
+ ```markdown
260
+ # Locators -- {feature}
261
+
262
+ Extracted: {date}
263
+ App URL: {app_url}
264
+
265
+ ## Page: {page_name} ({url})
266
+
267
+ | Element | Locator Type | Locator Value | Tier |
268
+ |---------|-------------|---------------|------|
269
+ | ... | data-testid | ... | 1 |
270
+ | ... | role + name | ... | 1 |
271
+ | ... | label | ... | 2 |
272
+ ```
273
+
274
+ 6. Update the registry `.qa-output/locators/LOCATOR_REGISTRY.md` -- merge new locators into the central index without overwriting locators from other features.
275
+
276
+ If this step is skipped entirely, the executor will propose locators based on source code analysis and CLAUDE.md conventions.
277
+ </step>
278
+
218
279
  <step name="generate_test_cases">
219
- ## Step 5: Generate Test Cases with Traceability Matrix
280
+ ## Step 6: Generate Test Cases with Traceability Matrix
220
281
 
221
282
  Map each acceptance criterion to one or more test cases, following CLAUDE.md test spec rules.
222
283
 
@@ -312,7 +373,7 @@ Write to `{OUTPUT_DIR}/TEST_CASES_FROM_TICKET.md`.
312
373
  </step>
313
374
 
314
375
  <step name="generate_test_files">
315
- ## Step 6: Spawn Executor Agent
376
+ ## Step 7: Spawn Executor Agent
316
377
 
317
378
  Build a synthetic generation plan from the test cases and spawn the executor to write test files.
318
379
 
@@ -361,6 +422,7 @@ Task(
361
422
  <files_to_read>
362
423
  - {OUTPUT_DIR}/GENERATION_PLAN_TICKET.md
363
424
  - {OUTPUT_DIR}/TEST_CASES_FROM_TICKET.md
425
+ - {OUTPUT_DIR}/locators/LOCATOR_REGISTRY.md (if exists -- accumulated real locators)
364
426
  - CLAUDE.md
365
427
  </files_to_read>
366
428
  <parameters>
@@ -376,7 +438,7 @@ Extract: `files_created`, `total_files`, `commit_count`, `test_case_count`.
376
438
  </step>
377
439
 
378
440
  <step name="validate_generated_tests">
379
- ## Step 7: Spawn Validator Agent
441
+ ## Step 8: Spawn Validator Agent
380
442
 
381
443
  Validate the generated test files against CLAUDE.md standards.
382
444
 
@@ -402,7 +464,7 @@ Extract: `overall_status`, `confidence`, `issues_found`, `issues_fixed`, `unreso
402
464
  </step>
403
465
 
404
466
  <step name="print_summary">
405
- ## Step 8: Print Summary
467
+ ## Step 9: Print Summary
406
468
 
407
469
  Print a comprehensive summary showing traceability from ticket to tests.
408
470
 
@@ -0,0 +1,389 @@
1
+ <purpose>
2
+ Create a draft PR from QA artifacts (test files, POMs, fixtures, reports) already on disk. Detects git platform (GitHub, Azure DevOps, GitLab), applies the team's branch naming convention (saved in preferences), stages only test/QA files, and creates a draft PR with a summary. Standalone command -- does not require the full pipeline to have run.
3
+ </purpose>
4
+
5
+ <required_reading>
6
+ - `CLAUDE.md` -- Git workflow section (branch naming, commit conventions, PR template)
7
+ - `~/.claude/qaa/MY_PREFERENCES.md` -- Branch naming convention (if saved)
8
+ - `templates/pr-template.md` -- PR body template
9
+ </required_reading>
10
+
11
+ <process>
12
+
13
+ <step name="parse_arguments">
14
+ ## Step 1: Parse Arguments
15
+
16
+ Parse `$ARGUMENTS` to extract optional flags.
17
+
18
+ **Supported arguments:**
19
+
20
+ | Flag | Example | Description |
21
+ |------|---------|-------------|
22
+ | `--ticket` | `--ticket PROJ-123` | Ticket/issue ID for branch name |
23
+ | `--title` | `--title "login tests"` | Short description for branch and PR title |
24
+ | `--scope` | `--scope unit` | Limit to file type: unit, api, e2e, all (default: all) |
25
+ | `--files` | `--files tests/unit/auth*` | Explicit file glob to include |
26
+ | `--base` | `--base develop` | Target branch for PR (default: auto-detect) |
27
+
28
+ **If no arguments provided:**
29
+
30
+ Scan for QA artifacts to include:
31
+ 1. Check `.qa-output/` for generated test files, POMs, fixtures
32
+ 2. Check current git status for unstaged/untracked test files
33
+ 3. If nothing found, print error and STOP:
34
+ ```
35
+ Error: No QA artifacts found to deliver.
36
+ Run /qa-start, /create-test, or /qa-map first to generate artifacts.
37
+ ```
38
+ </step>
39
+
40
+ <step name="detect_platform">
41
+ ## Step 2: Detect Git Platform
42
+
43
+ ```bash
44
+ REMOTE_URL=$(git remote get-url origin 2>/dev/null || echo "")
45
+ ```
46
+
47
+ **Platform detection from remote URL:**
48
+
49
+ | Pattern | Platform | CLI Tool | PR Command |
50
+ |---------|----------|----------|------------|
51
+ | `github.com` or `gh:` | GitHub | `gh` | `gh pr create` |
52
+ | `dev.azure.com` or `visualstudio.com` or `azure` | Azure DevOps | `az` | `az repos pr create` |
53
+ | `gitlab.com` or `gitlab` | GitLab | `glab` | `glab mr create` |
54
+
55
+ ```bash
56
+ PLATFORM=""
57
+ PR_CLI=""
58
+
59
+ if echo "$REMOTE_URL" | grep -qi "github"; then
60
+ PLATFORM="github"
61
+ PR_CLI="gh"
62
+ elif echo "$REMOTE_URL" | grep -qi "dev.azure.com\|visualstudio.com\|azure"; then
63
+ PLATFORM="azure"
64
+ PR_CLI="az"
65
+ elif echo "$REMOTE_URL" | grep -qi "gitlab"; then
66
+ PLATFORM="gitlab"
67
+ PR_CLI="glab"
68
+ else
69
+ PLATFORM="unknown"
70
+ fi
71
+ ```
72
+
73
+ **If platform is unknown:**
74
+ ```
75
+ CHECKPOINT:
76
+ type: human-action
77
+ blocking: "Cannot detect git platform from remote URL"
78
+ details: "Remote URL: ${REMOTE_URL}"
79
+ awaiting: "Which platform? (github / azure / gitlab)"
80
+ ```
81
+
82
+ **Verify CLI tool is available and authenticated:**
83
+
84
+ For GitHub:
85
+ ```bash
86
+ gh auth status 2>/dev/null
87
+ ```
88
+
89
+ For Azure DevOps:
90
+ ```bash
91
+ az account show 2>/dev/null
92
+ ```
93
+
94
+ For GitLab:
95
+ ```bash
96
+ glab auth status 2>/dev/null
97
+ ```
98
+
99
+ If CLI tool is not installed or not authenticated:
100
+ ```
101
+ Error: ${PR_CLI} CLI not found or not authenticated.
102
+
103
+ GitHub: Install from https://cli.github.com, then run: gh auth login
104
+ Azure: Install from https://aka.ms/azure-cli, then run: az login
105
+ GitLab: Install from https://gitlab.com/gitlab-org/cli, then run: glab auth login
106
+ ```
107
+ </step>
108
+
109
+ <step name="resolve_branch_convention">
110
+ ## Step 3: Resolve Branch Naming Convention
111
+
112
+ **Check saved preferences:**
113
+ ```bash
114
+ BRANCH_PATTERN=""
115
+ if [ -f ~/.claude/qaa/MY_PREFERENCES.md ]; then
116
+ # Look for branch pattern in Workflow section
117
+ BRANCH_PATTERN=$(grep -A1 "branch.*pattern\|branch.*convention\|branch.*naming" ~/.claude/qaa/MY_PREFERENCES.md | tail -1)
118
+ fi
119
+ ```
120
+
121
+ **If no saved convention, ask the user:**
122
+
123
+ ```
124
+ No branch naming convention configured.
125
+ What pattern does your team use?
126
+
127
+ 1) feature/{ticket}-{description}
128
+ 2) test/{ticket}-{description}
129
+ 3) qa/{ticket}-{description}
130
+ 4) {user}/{ticket}-{description}
131
+ 5) feature/QAA-{date}-{description}
132
+ 6) Custom (write your own with placeholders)
133
+
134
+ Placeholders: {ticket}, {date}, {description}, {user}, {scope}
135
+ ```
136
+
137
+ **On user response:**
138
+ - Save the chosen pattern to `~/.claude/qaa/MY_PREFERENCES.md` under `## Workflow` section
139
+ - Format: `- Branch naming convention: {pattern} — (added {date}, context: "user configured branch pattern via /qa-pr")`
140
+
141
+ **Build actual branch name from pattern:**
142
+
143
+ Replace placeholders with real values:
144
+ - `{ticket}` -- from `--ticket` flag, or prompt user if pattern requires it
145
+ - `{date}` -- today's date YYYY-MM-DD
146
+ - `{description}` -- from `--title` flag, sanitized to kebab-case (lowercase, hyphens, no special chars)
147
+ - `{user}` -- from `git config user.name`, sanitized to kebab-case
148
+ - `{scope}` -- from `--scope` flag or "qa"
149
+
150
+ ```bash
151
+ BRANCH_NAME=$(echo "$BRANCH_PATTERN" | sed \
152
+ -e "s/{ticket}/${TICKET}/g" \
153
+ -e "s/{date}/${DATE}/g" \
154
+ -e "s/{description}/${DESCRIPTION}/g" \
155
+ -e "s/{user}/${USER}/g" \
156
+ -e "s/{scope}/${SCOPE}/g")
157
+ ```
158
+
159
+ **If ticket is required by pattern but not provided:**
160
+ ```
161
+ Your branch pattern requires a ticket ID: {pattern}
162
+ Provide ticket ID (e.g., PROJ-123):
163
+ ```
164
+ </step>
165
+
166
+ <step name="collect_files">
167
+ ## Step 4: Collect Files to Include
168
+
169
+ Gather all QA artifacts that should go into the PR.
170
+
171
+ **If `--files` flag provided:** Use that glob directly.
172
+
173
+ **Otherwise, auto-detect:**
174
+
175
+ ```bash
176
+ QA_FILES=()
177
+
178
+ # 1. Generated test files
179
+ find . -path '*/tests/*' -name '*.spec.*' -o -name '*.test.*' -o -name '*.e2e.*' -o -name '*.cy.*' | while read f; do
180
+ QA_FILES+=("$f")
181
+ done
182
+
183
+ # 2. Page Object Models
184
+ find . -path '*/pages/*' -o -path '*/page-objects/*' | grep -E '\.(ts|js|py)$' | while read f; do
185
+ QA_FILES+=("$f")
186
+ done
187
+
188
+ # 3. Fixtures
189
+ find . -path '*/fixtures/*' -name '*-data.*' | while read f; do
190
+ QA_FILES+=("$f")
191
+ done
192
+
193
+ # 4. Config files (test configs only)
194
+ for cfg in playwright.config.* jest.config.* vitest.config.* cypress.config.* pytest.ini conftest.py; do
195
+ [ -f "$cfg" ] && QA_FILES+=("$cfg")
196
+ done
197
+
198
+ # 5. QA output reports
199
+ find .qa-output -name '*.md' 2>/dev/null | while read f; do
200
+ QA_FILES+=("$f")
201
+ done
202
+ ```
203
+
204
+ **Apply scope filter if `--scope` provided:**
205
+ - `unit` -- only `*.unit.spec.*`, `*.test.*` files
206
+ - `api` -- only `*.api.spec.*` files
207
+ - `e2e` -- only `*.e2e.spec.*`, `*.cy.*` files + POMs
208
+ - `all` -- everything (default)
209
+
210
+ **If no files found:** Print error and STOP.
211
+
212
+ **Security check:**
213
+ - Exclude any `.env`, `credentials.*`, `secrets.*`, `*.key`, `*.pem` files
214
+ - Warn if any file contains hardcoded passwords/tokens (grep for common patterns)
215
+ </step>
216
+
217
+ <step name="confirm_with_user">
218
+ ## Step 5: Confirmation Checkpoint
219
+
220
+ Present the plan to the user and wait for confirmation.
221
+
222
+ ```
223
+ ╔══════════════════════════════════════════╗
224
+ ║ /qa-pr — Create QA Pull Request ║
225
+ ╠══════════════════════════════════════════╣
226
+ ║ ║
227
+ ║ Platform: {PLATFORM} ║
228
+ ║ Branch: {BRANCH_NAME} ║
229
+ ║ Target: {DEFAULT_BRANCH} ║
230
+ ║ Type: Draft PR ║
231
+ ║ ║
232
+ ║ Files ({FILE_COUNT}): ║
233
+ ║ {N} test specs ║
234
+ ║ {N} page objects ║
235
+ ║ {N} fixtures ║
236
+ ║ {N} config files ║
237
+ ║ {N} QA reports ║
238
+ ║ ║
239
+ ╚══════════════════════════════════════════╝
240
+
241
+ Proceed? (y/n)
242
+ ```
243
+
244
+ **If user says no:** Print "Cancelled." and STOP.
245
+ </step>
246
+
247
+ <step name="create_branch_and_commit">
248
+ ## Step 6: Create Branch and Commit
249
+
250
+ **Detect default branch:**
251
+ ```bash
252
+ # GitHub
253
+ DEFAULT_BRANCH=$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name' 2>/dev/null)
254
+
255
+ # Azure DevOps
256
+ if [ -z "$DEFAULT_BRANCH" ]; then
257
+ DEFAULT_BRANCH=$(az repos show --query 'defaultBranch' -o tsv 2>/dev/null | sed 's|refs/heads/||')
258
+ fi
259
+
260
+ # GitLab
261
+ if [ -z "$DEFAULT_BRANCH" ]; then
262
+ DEFAULT_BRANCH=$(glab repo view --json default_branch --jq '.default_branch' 2>/dev/null)
263
+ fi
264
+
265
+ # Fallback
266
+ DEFAULT_BRANCH=${DEFAULT_BRANCH:-main}
267
+ ```
268
+
269
+ **Override with `--base` flag if provided.**
270
+
271
+ **Create branch:**
272
+ ```bash
273
+ git checkout -b "$BRANCH_NAME" "origin/$DEFAULT_BRANCH"
274
+ ```
275
+
276
+ **Handle collision:**
277
+ ```bash
278
+ if git rev-parse --verify "$BRANCH_NAME" 2>/dev/null; then
279
+ SUFFIX=2
280
+ while git rev-parse --verify "${BRANCH_NAME}-${SUFFIX}" 2>/dev/null; do
281
+ SUFFIX=$((SUFFIX + 1))
282
+ done
283
+ BRANCH_NAME="${BRANCH_NAME}-${SUFFIX}"
284
+ git checkout -b "$BRANCH_NAME" "origin/$DEFAULT_BRANCH"
285
+ fi
286
+ ```
287
+
288
+ **Stage and commit:**
289
+ ```bash
290
+ git add ${QA_FILES[@]}
291
+ git commit -m "qa(pr): add ${FILE_COUNT} QA artifacts — ${DESCRIPTION}"
292
+ ```
293
+ </step>
294
+
295
+ <step name="push_and_create_pr">
296
+ ## Step 7: Push and Create PR
297
+
298
+ **Push branch:**
299
+ ```bash
300
+ git push -u origin "$BRANCH_NAME"
301
+ ```
302
+
303
+ **Build PR body from template (if available) or minimal summary:**
304
+
305
+ If `templates/pr-template.md` exists and QA reports are available, populate it.
306
+ Otherwise use minimal body:
307
+
308
+ ```markdown
309
+ ## QA Artifacts
310
+
311
+ ${FILE_COUNT} files added:
312
+ - ${test_count} test specs
313
+ - ${pom_count} page objects
314
+ - ${fixture_count} fixtures
315
+
316
+ ${TICKET_REF}
317
+
318
+ ---
319
+ Generated by QAA (QA Automation Agent)
320
+ ```
321
+
322
+ **Create PR by platform:**
323
+
324
+ **GitHub:**
325
+ ```bash
326
+ PR_URL=$(gh pr create \
327
+ --draft \
328
+ --title "qa: ${DESCRIPTION}" \
329
+ --body "${PR_BODY}")
330
+ ```
331
+
332
+ **Azure DevOps:**
333
+ ```bash
334
+ PR_URL=$(az repos pr create \
335
+ --draft \
336
+ --title "qa: ${DESCRIPTION}" \
337
+ --description "${PR_BODY}" \
338
+ --source-branch "$BRANCH_NAME" \
339
+ --target-branch "$DEFAULT_BRANCH" \
340
+ --query 'url' -o tsv)
341
+ ```
342
+
343
+ **GitLab:**
344
+ ```bash
345
+ PR_URL=$(glab mr create \
346
+ --draft \
347
+ --title "qa: ${DESCRIPTION}" \
348
+ --description "${PR_BODY}" \
349
+ --source-branch "$BRANCH_NAME" \
350
+ --target-branch "$DEFAULT_BRANCH" \
351
+ --yes)
352
+ ```
353
+
354
+ **On failure:** Print error with branch name so user can create PR manually.
355
+ </step>
356
+
357
+ <step name="print_result">
358
+ ## Step 8: Print Result
359
+
360
+ ```
361
+ ╔══════════════════════════════════════════╗
362
+ ║ PR Created ✓ ║
363
+ ╠══════════════════════════════════════════╣
364
+ ║ ║
365
+ ║ ${PR_URL} ║
366
+ ║ ║
367
+ ║ Branch: ${BRANCH_NAME} ║
368
+ ║ Target: ${DEFAULT_BRANCH} ║
369
+ ║ Files: ${FILE_COUNT} ║
370
+ ║ Status: Draft ║
371
+ ║ ║
372
+ ╚══════════════════════════════════════════╝
373
+ ```
374
+ </step>
375
+
376
+ </process>
377
+
378
+ <error_handling>
379
+ | Error | Cause | Action |
380
+ |-------|-------|--------|
381
+ | No QA artifacts found | Nothing generated yet | Print error, suggest /qa-start or /create-test |
382
+ | Platform not detected | Unusual remote URL | Ask user to specify platform |
383
+ | CLI not installed | gh/az/glab missing | Print install instructions for detected platform |
384
+ | CLI not authenticated | Not logged in | Print auth command for detected platform |
385
+ | Branch already exists | Name collision | Auto-append numeric suffix |
386
+ | Push fails | Permission or network | Print error, keep local commits |
387
+ | PR creation fails | API error | Print error with branch name for manual PR creation |
388
+ | Ticket required but missing | Pattern uses {ticket} | Prompt user for ticket ID |
389
+ </error_handling>
@@ -1,21 +0,0 @@
1
- # QA Repository Analysis
2
-
3
- Analysis-only mode. Scans a repository, detects framework and stack, and produces QA assessment documents. No test generation. No PR creation.
4
-
5
- ## Usage
6
-
7
- /qa-analyze [--dev-repo <path>] [--qa-repo <path>]
8
-
9
- - No arguments: analyzes current directory
10
- - --dev-repo: explicit path to developer repository
11
- - --qa-repo: path to existing QA repository (produces gap analysis instead of blueprint)
12
-
13
- ## Instructions
14
-
15
- 1. Read `CLAUDE.md` -- all QA standards.
16
- 2. Execute the workflow:
17
-
18
- Follow the workflow defined in `@workflows/qa-analyze.md` end-to-end.
19
- Preserve all workflow gates (scan verification, artifact checks).
20
-
21
- $ARGUMENTS