@roopesh.yadava/qa-pack 1.4.0 → 1.5.1
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/README.md +15 -1
- package/claude/skills/SKILLS_CONTEXT.md +72 -5
- package/claude/skills/automation/SKILL.md +53 -6
- package/claude/skills/bug-reporting/SKILL.md +38 -0
- package/claude/skills/manual-testing/SKILL.md +159 -21
- package/claude/skills/manual-testing/TEST_DESIGN_GUIDE.md +200 -0
- package/claude/skills/mobile-automation/BDD_TEMPLATES.md +221 -0
- package/claude/skills/mobile-automation/LOCATOR_PATTERNS.md +205 -0
- package/claude/skills/mobile-automation/MOBILE_MCP_REFERENCE.md +234 -0
- package/claude/skills/mobile-automation/SKILL.md +593 -0
- package/claude/skills/qa-agent/SKILL.md +30 -0
- package/claude/skills/qa-agent/product_context/README.md +16 -0
- package/claude/skills/qa-agent/toolkit/qa-toolkit.cjs +758 -0
- package/claude/skills/qa-insights/SKILL.md +55 -0
- package/claude/skills/roam-testing/SKILL.md +187 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -92,12 +92,26 @@ and `/write-acceptance-criteria`, which are also available as explicit slash com
|
|
|
92
92
|
| `/write-acceptance-criteria PROJ-123` | write-acceptance-criteria | Generates AC, appends to the Jira card description |
|
|
93
93
|
| `/impacted-tests` / `which tests are impacted by this pull` | impacted-tests | After pulling dev changes into a test branch, reports which Cucumber feature files are at risk — report-only, no card needed |
|
|
94
94
|
| `set up k6` / `scaffold performance tests` | k6-framework-scaffold | Scaffolds a `k6-performance-tests/` framework (Grafana Cloud, protocol + optional browser layers) with commented templates to fill in — no card needed |
|
|
95
|
+
| `roam mode` / `explore the app` | roam-testing | Card-free exploratory testing — capped breadth-first crawl, report + optional bug filing + charter |
|
|
96
|
+
| `qa dashboard` / `weekly digest` / `token roi` | qa-insights | Cross-product health dashboard, weekly digest, or token-spend/ROI view — 100% script-generated, no card needed |
|
|
97
|
+
|
|
98
|
+
## The toolkit — why these features stay cheap
|
|
99
|
+
|
|
100
|
+
Several features above (self-improving locator memory, DOM fingerprint caching, duplicate-bug
|
|
101
|
+
detection, PII/secrets scanning, risk-based test ordering, the trust ratchet, and every
|
|
102
|
+
`qa-insights` report) are powered by one dependency-free script:
|
|
103
|
+
`.claude/skills/qa-agent/toolkit/qa-toolkit.cjs`. Skills shell out to it and read back a
|
|
104
|
+
single line — parsing markdown tables, hashing DOM snapshots, scoring bug-title similarity,
|
|
105
|
+
and aggregating every product's history are pure computation, so none of it costs a model
|
|
106
|
+
token beyond the one line of output. This is also why `qa-insights` (dashboard/digest/ROI
|
|
107
|
+
across every product you've ever tested) costs about the same whether you have 2 products or
|
|
108
|
+
200 — the script does the aggregation, not the model.
|
|
95
109
|
|
|
96
110
|
## What postinstall does
|
|
97
111
|
|
|
98
112
|
| File | Behaviour |
|
|
99
113
|
|---|---|
|
|
100
|
-
| `.claude/skills/*/SKILL.md` + companion `.md` files | Always overwritten (versioned logic) |
|
|
114
|
+
| `.claude/skills/*/SKILL.md` + companion `.md`/`.cjs`/`.sh` files (e.g. the toolkit script) | Always overwritten (versioned logic) |
|
|
101
115
|
| `.claude/skills/SKILLS_CONTEXT.md` | Always overwritten + stamped with the installed pack version |
|
|
102
116
|
| `.claude/commands/*.md` | Always overwritten |
|
|
103
117
|
| `.claude/skills/qa-agent/product_context/**` | **Never touched** after first seed |
|
|
@@ -50,6 +50,8 @@ A 10-test run with `browser_snapshot()` per test = ~100k wasted tokens.
|
|
|
50
50
|
| `BDD_TEMPLATES.md` | Once at Phase 1 start | Never reload in the same run |
|
|
51
51
|
| `LOCATOR_PATTERNS.md` | Once at Phase 1 start | Never reload in Phase 2 or 3 |
|
|
52
52
|
| `WCAG_CHECKS.md` | Once at skill start | Never reload |
|
|
53
|
+
| `manual-testing/TEST_DESIGN_GUIDE.md` | Once at Phase 1c (manual-testing) | Never reload — reference sections by number (§1–§9) |
|
|
54
|
+
| `mobile-automation/MOBILE_MCP_REFERENCE.md`, `BDD_TEMPLATES.md`, `LOCATOR_PATTERNS.md` | Once at Phase 2 start (mobile-automation) | Never reload in Phase 3 or 4 |
|
|
53
55
|
| `test-charter.md` | Once when charter starts | Never reload |
|
|
54
56
|
| `context.md` | Once at qa-agent Step 0 | Never reload |
|
|
55
57
|
|
|
@@ -70,6 +72,45 @@ Structure every skill invocation in this order so the stable prefix can be cache
|
|
|
70
72
|
The stable block qualifies for Anthropic prompt caching when it exceeds 1024 tokens.
|
|
71
73
|
Cache TTL is 5 minutes. Keep the stable block identical across runs for the same product.
|
|
72
74
|
|
|
75
|
+
### The Toolkit — the low-token path for anything product_context-shaped
|
|
76
|
+
|
|
77
|
+
`.claude/skills/qa-agent/toolkit/qa-toolkit.cjs` is a dependency-free Node script, not a
|
|
78
|
+
skill. It exists because parsing a markdown table, hashing a DOM snapshot, scoring string
|
|
79
|
+
similarity, or aggregating dozens of products' history is pure computation — routing it
|
|
80
|
+
through the model (Read the file → reason over it → maybe Edit it back) burns tokens on work
|
|
81
|
+
that doesn't need a model at all. **Any skill needing one of the things below calls the
|
|
82
|
+
toolkit and reads only its one-line result — never Read a whole context.md for this.**
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs <command> [--flags]
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
| Command | Used by | Purpose |
|
|
89
|
+
|---------|---------|---------|
|
|
90
|
+
| `get-bugs` / `get-runs` / `get-selectors` --product P | any skill | Cheap reads of one context.md table, pipe-delimited rows |
|
|
91
|
+
| `fingerprint` --product P --url U --testids "a,b" | manual-testing, automation, mobile-automation, roam-testing | DOM/screen fingerprint cache — `UNCHANGED` means skip re-discovery. Mobile uses a synthetic `mobile:{bundleId}/{Screen}` string as `--url` and resource-id/accessibility-id values as `--testids` — the command itself is platform-agnostic |
|
|
92
|
+
| `pii-scan` (stdin or `--file`) | bug-reporting, manual-testing, roam-testing | Flags emails/keys/tokens before anything is posted to Jira |
|
|
93
|
+
| `dup-bug` --product P --summary S | bug-reporting, manual-testing, roam-testing | Fuzzy-matches a new bug against Known Bugs, no LLM comparison needed |
|
|
94
|
+
| `cost-estimate` --product P [--phase N] | qa-agent | One-line run-cost estimate from Runs Log history |
|
|
95
|
+
| `risk-score` --product P --modules "a,b" | manual-testing | Orders tests by git churn + past bug density, not AC order |
|
|
96
|
+
| `trust-record` / `trust-status` --product P [--namespace N] | automation, mobile-automation (`--namespace mobile` — routes to a separate `trust.mobile.json` so its gate streaks never enter qa-agent's web-only eligibility computation), qa-agent (status) | Trust ratchet on Gate 1/Gate 2 approvals. `--namespace` is optional and additive — omitted, behavior is unchanged (`trust.json`); `trust-status` takes `min(streak)` across every gate in whichever file it reads, so gates from two automation surfaces must never share one file |
|
|
97
|
+
| `locator-record` / `locator-query` --product P --page U | automation, mobile-automation (page keys prefixed `mobile:` to avoid colliding with web page URLs) | Self-improving locator memory across self-heal fixes |
|
|
98
|
+
| `dashboard` / `digest [--days N]` / `roi` | qa-insights | Cross-product reports — 100% script-generated, zero synthesis. Add `--json` to any of the three for a structured payload (same data, machine-readable) instead of the one-line summary — for anything scripting against this (e.g. an external dashboard app) rather than chatting with it. |
|
|
99
|
+
|
|
100
|
+
This file is versioned logic (always overwritten on `npm update`, like every other skill
|
|
101
|
+
file) — never store product data inside it. Its outputs live under
|
|
102
|
+
`product_context/{PRODUCT}/` (`dom-fingerprints.json`, `trust.json`,
|
|
103
|
+
`locator-learnings.md` — all new, all gitignored the same way `context.md` already is) or
|
|
104
|
+
`outputs/` (`dashboard.html`, `qa-weekly-digest-*.md`, `roi-report.md`).
|
|
105
|
+
|
|
106
|
+
**Never inline arbitrary text into a toolkit shell call.** Bug descriptions, locator
|
|
107
|
+
strings, and anything else that isn't a short agent-controlled token (a card ID, a product
|
|
108
|
+
folder name, a URL) can contain quotes, `` ` ``, `$(...)`, or `|` — inlined into a bash
|
|
109
|
+
argument, that is a command-injection bug, not just an escaping nuisance. Write the text to
|
|
110
|
+
a file with the Write tool first and pass the path: `pii-scan --file`, `dup-bug
|
|
111
|
+
--summary-file`, `locator-record --file <json>`. Only short, structurally-constrained values
|
|
112
|
+
(URLs, card IDs, product folder names) are safe to inline directly.
|
|
113
|
+
|
|
73
114
|
---
|
|
74
115
|
|
|
75
116
|
## Pipeline Overview
|
|
@@ -105,25 +146,38 @@ test-charter │
|
|
|
105
146
|
End-to-End Testing complete
|
|
106
147
|
```
|
|
107
148
|
|
|
149
|
+
`roam-testing` (card-free exploratory) and `qa-insights` (dashboard/digest/roi) sit outside
|
|
150
|
+
this diagram — they don't take a Jira card, and qa-insights doesn't touch Playwright at all.
|
|
151
|
+
Both are driven by the toolkit rather than by each other.
|
|
152
|
+
|
|
153
|
+
`mobile-automation` also sits outside this diagram — it's a standalone, directly-triggered
|
|
154
|
+
skill (same status as `roam-testing`/`k6-framework-scaffold`), not wired into qa-agent's
|
|
155
|
+
Phase 2 dispatch, which remains web/Playwright-only via `automation`. Trigger it by name
|
|
156
|
+
("automate mobile PROJ-123", "mobile test PROJ-123") rather than through the qa-agent phase menu.
|
|
157
|
+
|
|
108
158
|
## Skills — One-Line Summary
|
|
109
159
|
|
|
110
160
|
| Skill | Input | Output | MCP Needed |
|
|
111
161
|
|-------|-------|--------|------------|
|
|
112
162
|
| `qa-agent` | Jira card ID or menu choice | Dispatches to correct skill | Atlassian |
|
|
113
163
|
| `automation` | Jira card ID | Reuse audit + Gherkin + Step Defs + POM + real run (reuse % reported) | Atlassian, Playwright |
|
|
164
|
+
| `mobile-automation` | Jira card ID | Reuse audit + mobile Gherkin + Step Defs + Screen POM + real device run (reuse % reported) | Atlassian, Mobile MCP, MobileWright/mobilecli |
|
|
114
165
|
| `manual-testing` | Jira card ID + app URL | Execution report + bugs + charter | Atlassian, Playwright |
|
|
115
166
|
| `ui-test-figma` | Figma URL + app URL | UI mismatch report, Jira comment | Playwright (CLI+MCP), Figma (optional) |
|
|
116
167
|
| `accessibility-testing` | Full page URL + Jira card (optional) | WCAG 2.1 A/AA report + Jira bugs | Playwright (CLI+MCP), Atlassian |
|
|
117
168
|
| `bug-reporting` | Bug description | Bug filed on Jira card | Atlassian |
|
|
118
169
|
| `test-charter` | Execution report MD file | Charter MD + published to API | Playwright (login) |
|
|
170
|
+
| `roam-testing` | App URL, no card required | Roam report + optional bugs + charter | Playwright, Atlassian (optional) |
|
|
171
|
+
| `qa-insights` | Nothing (reads all products) | Dashboard HTML / digest MD / ROI MD | None — pure toolkit |
|
|
119
172
|
|
|
120
173
|
## God Nodes (highest connectivity — touch these carefully)
|
|
121
174
|
|
|
122
|
-
1. `automation` —
|
|
123
|
-
2. `manual-testing` —
|
|
124
|
-
3. `qa-
|
|
125
|
-
4. `
|
|
126
|
-
5. `
|
|
175
|
+
1. `automation` — 15 edges (Gherkin→StepDefs→POM chain, token tracking, Playwright MCP, locator memory, trust ratchet)
|
|
176
|
+
2. `manual-testing` — 15 edges (orchestrates ui-test-figma, bug-reporting, test-charter, risk-score, fingerprint, dup-bug)
|
|
177
|
+
3. `qa-toolkit.cjs` — 6 skills call into it (qa-agent, automation, manual-testing, bug-reporting, roam-testing, qa-insights) — not a skill itself, but the single highest-fan-in file in the pack
|
|
178
|
+
4. `qa-agent` — 9 edges (dispatches all paths, owns the Phase 3 pipeline, cost estimate + trust status)
|
|
179
|
+
5. `test-charter` — 7 edges (reads execution report, publishes to Decision Record API; also used by roam-testing)
|
|
180
|
+
6. `ui-test-figma` — 6 edges (Figma MCP preferred, Playwright CLI fallback)
|
|
127
181
|
|
|
128
182
|
## Dispatch Map (qa-agent routes)
|
|
129
183
|
|
|
@@ -135,6 +189,8 @@ Phase 3 / "full QA" → manual-testing THEN automation (hints file reused
|
|
|
135
189
|
"accessibility test" → accessibility-testing (standalone, URL + optional Jira card)
|
|
136
190
|
"file bug" → bug-reporting (standalone)
|
|
137
191
|
"charter" → test-charter (standalone)
|
|
192
|
+
"roam mode" / "explore" → roam-testing (standalone, no card — routed outside qa-agent)
|
|
193
|
+
"dashboard"/"digest"/"roi" → qa-insights (standalone, no card — routed outside qa-agent)
|
|
138
194
|
```
|
|
139
195
|
|
|
140
196
|
**Input collection happens ONCE in qa-agent.** Sub-skills receive their parameters in the
|
|
@@ -196,6 +252,7 @@ python3 $PROJECT/track_tokens.py session
|
|
|
196
252
|
|
|
197
253
|
**Phase names by skill:**
|
|
198
254
|
- automation: `start` → `jira_fetch` → `reuse_audit` → `gherkin_generation` → `step_definitions` → `pom_generation` → `test_run` → `end`
|
|
255
|
+
- mobile-automation: `start` → `jira_fetch` → `reuse_audit` → `gherkin_generation` → `step_definitions` → `pom_generation` → `test_run` → `end`
|
|
199
256
|
- manual-testing: `start` → `jira_fetch` → `ui_testing` → `test_execution` → `end`
|
|
200
257
|
- ui-test-figma: `start` → `login` → `comparison` → `end`
|
|
201
258
|
- accessibility-testing: `start` → `login` → `a11y_checks` → `end`
|
|
@@ -232,7 +289,17 @@ First run will always be 0% (cold cache). Second and subsequent runs should cach
|
|
|
232
289
|
| Auth session | `.playwright-session.json` (gitignored) |
|
|
233
290
|
| Secrets / environment | `.env` at repo root (gitignored) |
|
|
234
291
|
| Step catalog (reuse audit) | `.claude/skills/qa-agent/product_context/[PRODUCT]/step-catalog.md` |
|
|
292
|
+
| Mobile step catalog (reuse audit) | `.claude/skills/qa-agent/product_context/[PRODUCT]/mobile-step-catalog.md` |
|
|
235
293
|
| Automation hints | `outputs/automation-hints-[CARD]-[date].md` |
|
|
236
294
|
| Token analytics | `~/.claude/token_analytics.png` |
|
|
237
295
|
| Knowledge graph | `graphify-out/graph.html` (open in browser) |
|
|
238
296
|
| Product QA context | `.claude/skills/qa-agent/product_context/[PRODUCT]/context.md` |
|
|
297
|
+
| DOM fingerprint cache | `.claude/skills/qa-agent/product_context/[PRODUCT]/dom-fingerprints.json` |
|
|
298
|
+
| Trust ratchet state | `.claude/skills/qa-agent/product_context/[PRODUCT]/trust.json` |
|
|
299
|
+
| Locator learnings | `.claude/skills/qa-agent/product_context/[PRODUCT]/locator-learnings.md` |
|
|
300
|
+
| Roam session report | `outputs/roam-report-[timestamp].md` |
|
|
301
|
+
| Product health dashboard | `outputs/dashboard.html` |
|
|
302
|
+
| QA weekly digest | `outputs/qa-weekly-digest-[date].md` |
|
|
303
|
+
| Token-spend / ROI view | `outputs/roi-report.md` |
|
|
304
|
+
| Shared toolkit CLI | `.claude/skills/qa-agent/toolkit/qa-toolkit.cjs` |
|
|
305
|
+
| Manual-testing coverage/scenario reference | `.claude/skills/manual-testing/TEST_DESIGN_GUIDE.md` |
|
|
@@ -269,14 +269,21 @@ Present Gherkin + reuse report and ask:
|
|
|
269
269
|
>
|
|
270
270
|
> **Type "looks good" or "confirmed" to proceed to step definitions.**
|
|
271
271
|
|
|
272
|
-
Do not write any `.cjs` files until confirmed. Iterate until approved.
|
|
272
|
+
Do not write any `.cjs` files until confirmed. Iterate until approved. Once approved, record
|
|
273
|
+
the trust ratchet — `clean` if the user approved on first presentation with no revision
|
|
274
|
+
requests this gate, `edited` if they asked for any change before approving:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs trust-record --product {PRODUCT_FOLDER} --gate gate1 --result clean|edited
|
|
278
|
+
```
|
|
273
279
|
|
|
274
280
|
**If AUTO_APPROVE = true (called from qa-agent full pipeline):**
|
|
275
281
|
|
|
276
282
|
Display the reuse report + a compact summary — do NOT wait:
|
|
277
283
|
> "Gherkin generated for [CARD-ID]: {N} Rules, {N} scenarios, {X}% step reuse. Auto-approved — proceeding to step definitions."
|
|
278
284
|
|
|
279
|
-
Immediately move to Phase 2 without waiting for any input.
|
|
285
|
+
Immediately move to Phase 2 without waiting for any input. Do not call `trust-record` here —
|
|
286
|
+
there was no human review to score.
|
|
280
287
|
|
|
281
288
|
After either path: run `gherkin_generation` token checkpoint, then move to Phase 2.
|
|
282
289
|
|
|
@@ -329,14 +336,19 @@ Present step definitions and ask:
|
|
|
329
336
|
>
|
|
330
337
|
> **Type "looks good" or "confirmed" to proceed to the POM.**
|
|
331
338
|
|
|
332
|
-
Do not write the POM until confirmed.
|
|
339
|
+
Do not write the POM until confirmed. Once approved, record the trust ratchet the same way
|
|
340
|
+
as Gate 1:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs trust-record --product {PRODUCT_FOLDER} --gate gate2 --result clean|edited
|
|
344
|
+
```
|
|
333
345
|
|
|
334
346
|
**If AUTO_APPROVE = true (called from qa-agent full pipeline):**
|
|
335
347
|
|
|
336
348
|
Display a compact summary only — do NOT wait:
|
|
337
349
|
> "Step definitions generated for [CARD-ID]: {N} steps across {N} files. Auto-approved — proceeding to POM."
|
|
338
350
|
|
|
339
|
-
Immediately move to Phase 3 without waiting for any input.
|
|
351
|
+
Immediately move to Phase 3 without waiting for any input. Do not call `trust-record` here.
|
|
340
352
|
|
|
341
353
|
After either path: run `step_definitions` token checkpoint, then move to Phase 3.
|
|
342
354
|
|
|
@@ -356,7 +368,31 @@ class. Only create a new POM class for a page that has none.
|
|
|
356
368
|
Use the POM class template from BDD_TEMPLATES.md for new classes; match the existing
|
|
357
369
|
class's style when extending.
|
|
358
370
|
|
|
359
|
-
|
|
371
|
+
**Locator memory check — once per page, before opening Playwright MCP for it:**
|
|
372
|
+
```bash
|
|
373
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs locator-query --product {PRODUCT_FOLDER} --page "PAGE_URL"
|
|
374
|
+
```
|
|
375
|
+
`NONE` → nothing learned yet for this page, proceed as usual. Rows returned → for each
|
|
376
|
+
listed element, avoid its recorded **Failed Locator** even if it looks like the obvious
|
|
377
|
+
choice; that pattern already broke a real test on this page. Prefer its recorded **Working
|
|
378
|
+
Locator** if the element matches.
|
|
379
|
+
|
|
380
|
+
**DOM fingerprint check — once per distinct page URL this run:**
|
|
381
|
+
```javascript
|
|
382
|
+
browser_evaluate({ expression: `
|
|
383
|
+
Array.from(document.querySelectorAll('[data-testid]')).map(el => el.getAttribute('data-testid')).join(',')
|
|
384
|
+
` })
|
|
385
|
+
```
|
|
386
|
+
```bash
|
|
387
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs fingerprint --product {PRODUCT_FOLDER} --url "PAGE_URL" --testids "RESULT_FROM_ABOVE"
|
|
388
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs get-selectors --product {PRODUCT_FOLDER} --url "PAGE_URL"
|
|
389
|
+
```
|
|
390
|
+
If fingerprint says `UNCHANGED` and `get-selectors` returns rows covering the elements this
|
|
391
|
+
Rule needs, write the POM locators straight from those rows — skip the per-element DOM
|
|
392
|
+
inspection below entirely for this page. Otherwise (`NEW`/`CHANGED`, or a needed element is
|
|
393
|
+
missing from `get-selectors`) fall through to the full inspection:
|
|
394
|
+
|
|
395
|
+
For every locator not already resolved above:
|
|
360
396
|
1. Navigate to the real page in the live app via Playwright MCP
|
|
361
397
|
2. Inspect the target element in the DOM
|
|
362
398
|
3. Check if `data-testid` already exists
|
|
@@ -420,7 +456,18 @@ On failure, diagnose and fix — **never hand off a silently failing test**:
|
|
|
420
456
|
|
|
421
457
|
1. Read the failure: locator timeout? assertion mismatch? navigation/auth issue?
|
|
422
458
|
2. Locator failures → re-inspect that element via Playwright MCP, fix the POM locator
|
|
423
|
-
(respect the locator priority table).
|
|
459
|
+
(respect the locator priority table). Once the fix passes, record it so no future run on
|
|
460
|
+
this product repeats the same wrong guess. Locator strings routinely contain quotes and
|
|
461
|
+
`|` (xpath unions) — never inline them into a shell command; write a small JSON file
|
|
462
|
+
instead (Write tool) and pass its path:
|
|
463
|
+
```
|
|
464
|
+
Write outputs/.locator-tmp.json containing:
|
|
465
|
+
{"product": "{PRODUCT_FOLDER}", "page": "PAGE_URL", "element": "ELEMENT_LABEL",
|
|
466
|
+
"failed": "OLD_LOCATOR", "fixed": "NEW_LOCATOR", "reason": "ONE_LINE_WHY", "card": "{CARD_ID}"}
|
|
467
|
+
```
|
|
468
|
+
```bash
|
|
469
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs locator-record --file outputs/.locator-tmp.json
|
|
470
|
+
```
|
|
424
471
|
3. Assertion failures → check whether expected text/behavior on the card matches the app.
|
|
425
472
|
If the app appears genuinely wrong, this is a **bug, not a test fix** — stop healing
|
|
426
473
|
that scenario, mark it failing, and note it as a bug candidate in the hand-off.
|
|
@@ -27,6 +27,12 @@ Display the list and ask:
|
|
|
27
27
|
|
|
28
28
|
Wait for the user to select a project by number or board key. Save the selected project key for the rest of the flow.
|
|
29
29
|
|
|
30
|
+
**Resolve `PRODUCT_FOLDER` (best-effort — only used by the duplicate check in Step 2a):**
|
|
31
|
+
check whether `.claude/skills/qa-agent/product_context/{KEY}/context.md` exists, or any
|
|
32
|
+
folder under `product_context/` starts with `{KEY}`. Found → store as `PRODUCT_FOLDER`.
|
|
33
|
+
Not found → leave `PRODUCT_FOLDER` unset and skip the duplicate half of Step 2a silently;
|
|
34
|
+
this is not an error, most exploratory-bug filing has no prior product context yet.
|
|
35
|
+
|
|
30
36
|
---
|
|
31
37
|
|
|
32
38
|
## Step 1A/1B — Ask card type
|
|
@@ -110,6 +116,38 @@ Do NOT ask the user for any missing fields. Use what was given and proceed.
|
|
|
110
116
|
|
|
111
117
|
---
|
|
112
118
|
|
|
119
|
+
## Step 2a — Duplicate + PII/secrets check (script calls, no extra questions unless flagged)
|
|
120
|
+
|
|
121
|
+
The user typed this text freely — it can contain quotes, `$`, backticks, anything. **Never**
|
|
122
|
+
interpolate it directly into a shell command; write it to a file with the Write tool first
|
|
123
|
+
and pass the file path instead.
|
|
124
|
+
|
|
125
|
+
**Duplicate check — only if `PRODUCT_FOLDER` was resolved in Step 1:**
|
|
126
|
+
```
|
|
127
|
+
Write outputs/.dupcheck-tmp.txt containing: {Bug Title}
|
|
128
|
+
```
|
|
129
|
+
```bash
|
|
130
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs dup-bug --product {PRODUCT_FOLDER} --summary-file outputs/.dupcheck-tmp.txt
|
|
131
|
+
```
|
|
132
|
+
`NO_DUPLICATE_FOUND` → proceed silently. `POSSIBLE_DUPLICATE: {BUG-ID} (...) — "{title}"` →
|
|
133
|
+
mention it once above the formatted report in Step 3: `"Heads up — this looks similar to
|
|
134
|
+
{BUG-ID}: \"{title}\" ({status}). File as a new bug anyway, or add to that one instead?"`
|
|
135
|
+
Follow whichever the user picks.
|
|
136
|
+
|
|
137
|
+
**PII/secrets scan — always, regardless of PRODUCT_FOLDER:**
|
|
138
|
+
```
|
|
139
|
+
Write outputs/.piicheck-tmp.txt containing: {Bug Title}\n{Expected Outcome}\n{Actual Outcome}\n{Steps to Reproduce}
|
|
140
|
+
```
|
|
141
|
+
```bash
|
|
142
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs pii-scan --file outputs/.piicheck-tmp.txt
|
|
143
|
+
```
|
|
144
|
+
Delete both temp files once this bug is posted (Step 6). `CLEAN` → proceed silently.
|
|
145
|
+
`FLAGGED: ...` → show the flagged pattern types (never the raw
|
|
146
|
+
match) and ask once: `"This bug report may contain real {types}. Redact before posting, or
|
|
147
|
+
file as-is? (redact / as-is)"`. Apply the choice, then continue to Step 3.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
113
151
|
## Step 3 — Display the formatted bug report
|
|
114
152
|
|
|
115
153
|
Show the bug report in this exact format before posting:
|
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
name: manual-testing
|
|
3
3
|
description: >
|
|
4
4
|
Manual Testing branch orchestrator. Follows the flowchart:
|
|
5
|
-
Jira Card Input → UI Testing (Figma MCP, optional) →
|
|
6
|
-
→ Bug Reporting (Atlassian MCP) → Test Charter →
|
|
5
|
+
Jira Card Input → Requirement Gap Analysis → UI Testing (Figma MCP, optional) →
|
|
6
|
+
Manual Testing (Playwright MCP) → Bug Reporting (Atlassian MCP) → Test Charter →
|
|
7
|
+
Automation Agent (optional handoff).
|
|
8
|
+
Test planning is risk-scoped and coverage-dimension-driven (see TEST_DESIGN_GUIDE.md) —
|
|
9
|
+
not just "1-3 tests per AC line" — so a payment/auth card gets materially deeper coverage
|
|
10
|
+
than a copy-change card.
|
|
7
11
|
Captures element selectors and interaction data during execution and saves them to an
|
|
8
12
|
automation-hints file for the automation skill to reuse — skipping DOM re-discovery.
|
|
9
13
|
Uses Playwright CLI for zero-token screenshots. Token tracking enabled.
|
|
@@ -95,6 +99,17 @@ Use `getJiraIssue` to fetch `CARD_ID`. Extract and store:
|
|
|
95
99
|
- `FIGMA_URL_FROM_CARD` — any Figma link found in description or comments
|
|
96
100
|
- `PROJECT_KEY` — for bug filing later
|
|
97
101
|
|
|
102
|
+
Derive `PRODUCT_FOLDER` now (uppercase `PROJECT_KEY`'s product name, spaces → `_` — same
|
|
103
|
+
normalisation qa-agent Step 6a uses) so Phases 3 and 4 below can call the toolkit without
|
|
104
|
+
re-deriving it. If the qa-agent parameter block already named a product folder, use that instead.
|
|
105
|
+
|
|
106
|
+
If a product folder was resolved, pull known bugs cheaply for the retest check used in 3a/§9
|
|
107
|
+
— one script call, not a `context.md` read:
|
|
108
|
+
```bash
|
|
109
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs get-bugs --product {PRODUCT_FOLDER}
|
|
110
|
+
```
|
|
111
|
+
Store non-`Closed`/`Done` rows as `OPEN_KNOWN_BUGS`. `NO_CONTEXT_FILE`/`NO_BUGS` → `OPEN_KNOWN_BUGS = []`, first run for this product.
|
|
112
|
+
|
|
98
113
|
Run token tracking `jira_fetch` checkpoint.
|
|
99
114
|
|
|
100
115
|
### 1b — Truncate Jira data if card is verbose
|
|
@@ -108,14 +123,33 @@ After fetching, check `CARD_DESCRIPTION` length:
|
|
|
108
123
|
|
|
109
124
|
Do NOT tell the user the description was truncated. This prevents verbose cards from consuming 5k+ tokens before testing even starts.
|
|
110
125
|
|
|
111
|
-
If no AC found (and qa-agent didn't already resolve this):
|
|
112
|
-
> "No Acceptance Criteria found on this card. What should be tested?"
|
|
113
|
-
Wait for user response before continuing.
|
|
114
|
-
|
|
115
126
|
Set from Phase 0 values (all input was collected there — do not re-ask):
|
|
116
127
|
- `RUN_UI_TEST` — true when a Figma URL is available (from parameter block, card, or user)
|
|
117
128
|
- `FIGMA_URL`, `APP_URL`, `USERNAME`, `PASSWORD`, `OTP_CODE`
|
|
118
129
|
|
|
130
|
+
### 1c — Load Test Design Guide (once)
|
|
131
|
+
|
|
132
|
+
Read `.claude/skills/manual-testing/TEST_DESIGN_GUIDE.md` now. Per the Static File Load
|
|
133
|
+
Rules in `SKILLS_CONTEXT.md`, load it once here and never reload it later in this run —
|
|
134
|
+
reference its sections by number (e.g. "per §4 High risk") for the rest of the pipeline.
|
|
135
|
+
|
|
136
|
+
### 1d — Requirement Gap Analysis
|
|
137
|
+
|
|
138
|
+
Run the checklist in `TEST_DESIGN_GUIDE.md` §1 against `CARD_TITLE` + `ACCEPTANCE_CRITERIA`.
|
|
139
|
+
This **replaces** the old bare "no AC found" check — the missing-AC row is §1's first row and
|
|
140
|
+
is the most severe: if it fires, skip evaluating the rest of the table and ask only that.
|
|
141
|
+
|
|
142
|
+
Fold every gap that actually applies into **one** consolidated question — the same message as
|
|
143
|
+
any unresolved Phase 0 gaps, not a second round:
|
|
144
|
+
> "No Acceptance Criteria found on this card. What should be tested?" (only if AC is entirely
|
|
145
|
+
> missing), or, when AC exists but has gaps: one line per applicable §1 row, e.g. "AC mentions
|
|
146
|
+
> a 'reference code' but doesn't state its length/format — what's the exact rule?"
|
|
147
|
+
|
|
148
|
+
Skip this step's question entirely if the AC is already precise and complete on every §1
|
|
149
|
+
row — do not manufacture questions to fill the message.
|
|
150
|
+
|
|
151
|
+
Wait for the response before proceeding to Phase 2.
|
|
152
|
+
|
|
119
153
|
---
|
|
120
154
|
|
|
121
155
|
## Phase 2 — UI Testing (optional)
|
|
@@ -158,21 +192,58 @@ HINTS = {
|
|
|
158
192
|
}
|
|
159
193
|
```
|
|
160
194
|
|
|
161
|
-
### 3a — Generate Test Plan
|
|
195
|
+
### 3a — Generate Test Plan (risk-scoped, coverage-dimension-driven)
|
|
162
196
|
|
|
163
197
|
Before drafting test ideas, check each AC item for a stated entry point (menu path, URL,
|
|
164
198
|
button/link name). Per the **Test Data & Entity Selection Rules** above, do not scan `src/`
|
|
165
199
|
to infer a missing one — collect a single navigation question per missing entry point and
|
|
166
200
|
fold it into the confirmation prompt below instead of guessing.
|
|
167
201
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
202
|
+
**Step 1 — Classify risk tier and select dimensions.** Using `TEST_DESIGN_GUIDE.md` §2 (Feature
|
|
203
|
+
Signal → Coverage Dimension Trigger Table), scan `CARD_TITLE` + `ACCEPTANCE_CRITERIA` for
|
|
204
|
+
signal keywords and turn on the matched dimensions. No signal matched → default set only
|
|
205
|
+
(Functional Positive/Negative + UI/UX States + one Boundary check). Then classify the card's
|
|
206
|
+
risk tier per §4 (High/Medium/Low) from the same signals — this sets how many tests each
|
|
207
|
+
triggered dimension gets, not just which dimensions run.
|
|
208
|
+
|
|
209
|
+
**Step 2 — Draft numbered test ideas per dimension.** Walk the §5 Test Scenario Identification
|
|
210
|
+
Framework (the 10 "what can/can't/who/what happens" questions) once, and for each dimension
|
|
211
|
+
turned on in Step 1, draft the number of tests §4's tier calls for. Concretely, for a Medium-risk
|
|
212
|
+
card this typically looks like: 1–2 Functional Positive, 1–2 Functional Negative, one Boundary
|
|
213
|
+
or Equivalence set per §6 if the AC states or implies a limit, one UI/UX States pass (§8) on the
|
|
214
|
+
card's key screen, plus one test per other triggered dimension (Permissions, API, Database,
|
|
215
|
+
State/Workflow, etc.). High-risk cards double the per-dimension count and add Security-oriented
|
|
216
|
+
+ Database checks unconditionally per §4. Low-risk cards (copy/label-only) skip straight to
|
|
217
|
+
Functional (positive + one negative) plus one regression spot-check — do not force the other
|
|
218
|
+
dimensions onto a low-risk card.
|
|
219
|
+
|
|
220
|
+
Cap exploratory ideas (§5 Q10) at one per plan, clearly tagged `[exploratory]`, so they don't
|
|
221
|
+
inflate the "planned" test count used for the Exit Criteria check later (§9).
|
|
222
|
+
|
|
223
|
+
If `OPEN_KNOWN_BUGS` (from Phase 1) contains a row whose Title overlaps this card's module/page
|
|
224
|
+
keywords, add one retest test tagged `[retest: {BUG-ID}]` — this is what §9's retest check
|
|
225
|
+
verifies actually happened.
|
|
226
|
+
|
|
227
|
+
Do not draft dedicated regression tests here — that's qa-agent Step 5's job (Covered Flows
|
|
228
|
+
overlap), triggered automatically after this skill returns. §5 Q9 exists only to flag *that*
|
|
229
|
+
regression may apply, not to author it now.
|
|
230
|
+
|
|
231
|
+
**Risk-based execution ordering** — pull 2–5 module/page keywords straight out of the AC/card
|
|
232
|
+
title you already read (e.g. "login", "checkout"; no extra fetching), then run one script call:
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs risk-score --product {PRODUCT_FOLDER} --modules "kw1,kw2,kw3"
|
|
236
|
+
```
|
|
172
237
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
238
|
+
Order the T-01, T-02... list so tests touching the highest-risk module come first. On a
|
|
239
|
+
product's first run (no git history / no known bugs yet) every module scores 0 — keep the
|
|
240
|
+
natural drafting order in that case, no need to mention it. (This reorders the tests drafted in
|
|
241
|
+
Step 2 — it doesn't decide how many exist; that's §4's job, run once, not repeated per module.)
|
|
242
|
+
|
|
243
|
+
Show as a compact table (T-01, T-02 ... with name, dimension tag, and expected outcome),
|
|
244
|
+
risk-ordered. Ask: `"Ready to run these tests? (yes / no or edit)"` — include any missing
|
|
245
|
+
navigation questions from above in this same message (§1 gap questions were already asked
|
|
246
|
+
and resolved in Phase 1d — don't re-ask them here).
|
|
176
247
|
Proceed on confirmation.
|
|
177
248
|
|
|
178
249
|
### 3b — Setup Browser + Capture Login Selectors
|
|
@@ -241,6 +312,21 @@ For each test T-01, T-02, ...:
|
|
|
241
312
|
1. Navigate to the feature area via Playwright MCP (preserves session)
|
|
242
313
|
2. Add current URL to `HINTS.pages` if not already present
|
|
243
314
|
|
|
315
|
+
2a. **DOM fingerprint check — once per distinct URL, the first time you land on it this run:**
|
|
316
|
+
```javascript
|
|
317
|
+
browser_evaluate({ expression: `
|
|
318
|
+
Array.from(document.querySelectorAll('[data-testid]')).map(el => el.getAttribute('data-testid')).join(',')
|
|
319
|
+
` })
|
|
320
|
+
```
|
|
321
|
+
```bash
|
|
322
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs fingerprint --product {PRODUCT_FOLDER} --url "CURRENT_URL" --testids "RESULT_FROM_ABOVE"
|
|
323
|
+
```
|
|
324
|
+
- `UNCHANGED` → this page's selectors haven't moved since a prior run. Skip step 3's
|
|
325
|
+
per-interaction element capture for this page entirely (still perform the actual test
|
|
326
|
+
interactions and assertions — only the *hint-recording* is skipped). Add one line to
|
|
327
|
+
`HINTS.notes`: `"Elements on {url}: unchanged — reused prior fingerprint, capture skipped."`
|
|
328
|
+
- `NEW` or `CHANGED` → proceed with full per-interaction capture in step 3 below, same as always.
|
|
329
|
+
|
|
244
330
|
3. For each browser interaction (`browser_fill`, `browser_click`, `browser_select_option`):
|
|
245
331
|
- Execute the interaction
|
|
246
332
|
- Immediately run element capture (zero-token, targeted JS):
|
|
@@ -275,10 +361,13 @@ For each test T-01, T-02, ...:
|
|
|
275
361
|
outputs/screenshots/T-[N]-[pass|fail|observation].png
|
|
276
362
|
```
|
|
277
363
|
|
|
278
|
-
5. Assert expected result via targeted `browser_evaluate` on specific selectors
|
|
364
|
+
5. Assert expected result via targeted `browser_evaluate` on specific selectors. If this
|
|
365
|
+
test's dimension tag (from 3a) is UI/UX States, note which of the `TEST_DESIGN_GUIDE.md`
|
|
366
|
+
§8 states (Initial/Loading/Empty/Success/Error/Disabled) were actually observed and their
|
|
367
|
+
result — skip states genuinely unreachable in this test, don't force them.
|
|
279
368
|
|
|
280
369
|
6. Log test result (to file only, not chat):
|
|
281
|
-
`T-N | title | status | expected | actual | screenshot path`
|
|
370
|
+
`T-N | title | dimension | status | expected | actual | screenshot path`
|
|
282
371
|
|
|
283
372
|
7. Append to `HINTS.testCases`:
|
|
284
373
|
```
|
|
@@ -346,7 +435,7 @@ Run token tracking `test_execution` checkpoint.
|
|
|
346
435
|
|
|
347
436
|
After saving the automation hints file, silently update the product context.
|
|
348
437
|
|
|
349
|
-
|
|
438
|
+
`PRODUCT_FOLDER` was already derived in Phase 1 — reuse it, don't re-derive.
|
|
350
439
|
|
|
351
440
|
```
|
|
352
441
|
CONTEXT_FILE = .claude/skills/qa-agent/product_context/{PRODUCT_FOLDER}/context.md
|
|
@@ -377,15 +466,56 @@ this keeps context contiguous and avoids a second skill invocation.
|
|
|
377
466
|
|
|
378
467
|
**Step 4a — Build bug payload for each ❌ FAIL and ⚠️ OBSERVATION**
|
|
379
468
|
|
|
380
|
-
Derive all fields from test execution data — no user input needed
|
|
469
|
+
Derive all fields from test execution data — no user input needed. Fields follow
|
|
470
|
+
`TEST_DESIGN_GUIDE.md` §7:
|
|
381
471
|
|
|
382
472
|
| Field | Source |
|
|
383
473
|
|-------|--------|
|
|
384
474
|
| Summary | `"T-{N}: {test name} — {actual outcome in one line}"` |
|
|
385
|
-
|
|
|
475
|
+
| Environment | `APP_URL` + environment name from product context (staging/dev/prod) |
|
|
476
|
+
| Preconditions | Login state + any setup steps from the test case (e.g. role, prior state) |
|
|
477
|
+
| Description (Steps/Expected/Actual) | Steps from test case + expected vs actual from execution log |
|
|
386
478
|
| Severity | AC explicitly failed → High · Assertion failed → Medium · Observation → Low |
|
|
479
|
+
| Priority | High-risk dimension (§4) failing → High · otherwise matches Severity |
|
|
480
|
+
| Test data used | The specific values/entities used for this test (never credentials) |
|
|
481
|
+
| Build/version | `CARD_ID` + run date (stands in for a separate build number) |
|
|
387
482
|
| Screenshot | Match `outputs/screenshots/T-{N}-*.png` by test ID — use exact filename |
|
|
388
483
|
|
|
484
|
+
**Step 4a.1 — Duplicate check (one script call per failure, no user input needed)**
|
|
485
|
+
|
|
486
|
+
Test names are derived from the AC, not typed by a person, but AC text copied from Jira can
|
|
487
|
+
still contain quotes or symbols — never inline free text into a shell command. Write it with
|
|
488
|
+
the Write tool first, then reference the file:
|
|
489
|
+
|
|
490
|
+
```
|
|
491
|
+
Write outputs/.dupcheck-tmp.txt containing: T-{N}: {test name}
|
|
492
|
+
```
|
|
493
|
+
```bash
|
|
494
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs dup-bug --product {PRODUCT_FOLDER} --summary-file outputs/.dupcheck-tmp.txt
|
|
495
|
+
```
|
|
496
|
+
|
|
497
|
+
`NO_DUPLICATE_FOUND` → proceed normally. `POSSIBLE_DUPLICATE: {BUG-ID} (...) — "{title}"` →
|
|
498
|
+
still file the bug (a regression is a real, separately-trackable failure) but prepend one
|
|
499
|
+
line to the Description: `"⚠ Possibly related to {BUG-ID}: {title}"` for the triager.
|
|
500
|
+
|
|
501
|
+
**Step 4a.2 — PII / secrets scan (one script call per bug, before it leaves the machine)**
|
|
502
|
+
|
|
503
|
+
Same rule — the Description includes live-app text (error messages, field values) that can
|
|
504
|
+
contain anything. Write it to a file, never interpolate it into the command:
|
|
505
|
+
|
|
506
|
+
```
|
|
507
|
+
Write outputs/.piicheck-tmp.txt containing the composed Summary + Description text
|
|
508
|
+
```
|
|
509
|
+
```bash
|
|
510
|
+
node .claude/skills/qa-agent/toolkit/qa-toolkit.cjs pii-scan --file outputs/.piicheck-tmp.txt
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
`CLEAN` → proceed silently. `FLAGGED: ...` → this is rare (test data occasionally captures a
|
|
514
|
+
real value) — pause only this one bug, show the flagged pattern types (never the raw match),
|
|
515
|
+
and ask once: `"This bug's description may contain real {types}. Redact and continue, or file as-is? (redact / as-is)"`.
|
|
516
|
+
Apply the user's choice, then continue to the next failure — do not stop the whole batch.
|
|
517
|
+
Delete both `outputs/.dupcheck-tmp.txt` and `outputs/.piicheck-tmp.txt` once the batch is done.
|
|
518
|
+
|
|
389
519
|
**Step 4b — File each bug via Atlassian MCP (parallelise where possible)**
|
|
390
520
|
|
|
391
521
|
For each failure:
|
|
@@ -431,14 +561,22 @@ Run token tracking `end + report + session` close-out after charter publishes.
|
|
|
431
561
|
|
|
432
562
|
## Phase 6 — Automation Handoff
|
|
433
563
|
|
|
434
|
-
After charter completes,
|
|
564
|
+
After charter completes, run the `TEST_DESIGN_GUIDE.md` §9 Exit Criteria Quick Check:
|
|
565
|
+
confirm every planned test executed (BLOCKED is fine, silently-skipped is not), check whether
|
|
566
|
+
any bug just filed is High severity on a High-risk dimension (§4) and if so flag it as the
|
|
567
|
+
first line of the summary below, and — only if `OPEN_KNOWN_BUGS` (Phase 1) was non-empty and
|
|
568
|
+
overlapped this card — confirm the `[retest: {BUG-ID}]` test from 3a actually ran and note its
|
|
569
|
+
outcome. This does not block or gate anything — it only makes sure nothing gets buried in the
|
|
570
|
+
summary.
|
|
571
|
+
|
|
572
|
+
Show the final summary:
|
|
435
573
|
|
|
436
574
|
```
|
|
437
575
|
Manual Testing Complete — [CARD_ID]
|
|
438
576
|
|
|
439
577
|
UI Testing (Figma) : [completed / skipped]
|
|
440
578
|
Manual Testing : X Pass | X Fail | X Observation | X Blocked
|
|
441
|
-
Bug Reporting : [N] bug(s) filed — [keys]
|
|
579
|
+
Bug Reporting : [N] bug(s) filed — [keys] [+ "⚠ High-severity on {dimension}" if applicable]
|
|
442
580
|
Test Charter : [published URL or "saved locally"]
|
|
443
581
|
Automation hints : outputs/automation-hints-[CARD_ID]-[YYYYMMDD].md
|
|
444
582
|
```
|