qaa-agent 1.9.5 → 1.9.7

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.
@@ -1,404 +1,486 @@
1
- # QA Create Test — Azure DevOps
2
-
3
- Retrieve an Azure DevOps work item, analyze its content, and generate well-structured Test Cases directly in Azure DevOps using the ADO MCP tools. Each test case is tagged for test plan membership (Smoke, Regression, Critical) and linked back to the source work item for full traceability. Integrates with the QAA pipeline: reads codebase map, locator registry, and user preferences for context-aware test case generation.
4
-
5
- ## Usage
6
-
7
- ```
8
- /qa-create-test-ado <work-item-id> [--area-path=<path>] [--iteration-path=<path>] [--skip-map] [--skip-dedup] [--app-url <url>]
9
- ```
10
-
11
- ### Arguments
12
-
13
- | Parameter | Purpose | Default |
14
- |-----------|---------|---------|
15
- | `<work-item-id>` | Azure DevOps work item ID to generate test cases from | Required |
16
- | `--area-path=<path>` | Override area path for all created test artifacts | Source work item's area path |
17
- | `--iteration-path=<path>` | Override iteration path for all created test artifacts | Source work item's iteration path |
18
- | `--skip-map` | Skip codebase map check and proceed without project context | false |
19
- | `--skip-dedup` | Skip deduplication check against existing linked test cases | false |
20
- | `--app-url <url>` | URL of running application for locator extraction via Playwright MCP | auto-detect |
21
-
22
- ## What It Produces
23
-
24
- - Test Cases created directly in Azure DevOps (via `testplan_create_test_case`)
25
- - Test Cases linked to source work item via *Tested By* relationship
26
- - Tags applied: `Smoke`, `Regression`, `Critical`, `AutomationCandidate`, `NeedsReview`
27
- - `ai-tasks/ticket-{id}/test-cases.md` structured report
28
- - Report attached to work item (if `ADO_MCP_AUTH_TOKEN` is set) or written to `Custom.QATestCasesReport` field (fallback)
29
-
30
- ---
31
-
32
- ## Process
33
-
34
- ### Phase 1: Read Pipeline Context
35
-
36
- Before retrieving the work item, read QAA pipeline artifacts for context-aware generation.
37
-
38
- 1. **Read `CLAUDE.md`** — POM rules, locator tiers, assertion rules, naming conventions, quality gates, test spec rules.
39
-
40
- 2. **Read user preferences** — `~/.claude/qaa/MY_PREFERENCES.md` (if exists). User overrides win over defaults.
41
-
42
- 3. **Check for codebase map** (`.qa-output/codebase/`):
43
- - Look for: `CODE_PATTERNS.md`, `API_CONTRACTS.md`, `TEST_SURFACE.md`, `TESTABILITY.md`, `RISK_MAP.md`, `CRITICAL_PATHS.md`
44
- - If at least 2 exist: read them all for project context (naming conventions, API shapes, testable surfaces, risk areas).
45
- - If NONE exist and `--skip-map` not passed: warn the user that test cases will lack project context, suggest running `/qa-map` first. Continue anyway (ADO test cases are higher-level than code-level tests).
46
-
47
- 4. **Check locator registry** — `.qa-output/locators/LOCATOR_REGISTRY.md` (if exists):
48
- - If locators exist for pages related to the work item's feature: reference them in test step expected results (e.g., "Verify element `[data-testid='login-submit-btn']` is visible").
49
- - If `--app-url` provided and locators missing: use Playwright MCP to extract locators from the live app before designing test steps:
50
- ```
51
- mcp__playwright__browser_navigate({ url: "{app_url}/{feature_path}" })
52
- mcp__playwright__browser_snapshot()
53
- ```
54
- - Write extracted locators to `.qa-output/locators/{feature}.locators.md` and update the registry.
55
-
56
- ---
57
-
58
- ### Phase 2: Retrieve the Work Item
59
-
60
- Use `wit_get_work_item` with `expand: "relations"` to fetch the full work item:
61
-
62
- - Capture: **title**, **type** (`Bug`, `User Story`, `Ticket`), **state**, **assigned-to**, **area path**, **iteration path**
63
- - Capture all relevant content fields based on type (see Phase 3)
64
- - Note the project for all subsequent calls
65
-
66
- **Also retrieve comments** using `wit_list_work_item_comments`:
67
-
68
- - Read all comments in chronological order
69
- - Look for: acceptance criteria added in comments, QA notes, scope clarifications, tester feedback, or any conditions of satisfaction mentioned informally
70
- - These often contain implied test cases not captured in the formal fields
71
-
72
- **Also check attachments** from the relations list (entries where `rel` equals `AttachedFile`):
73
-
74
- - Filter to `.csv` and `.txt` files (case-insensitive) by inspecting `attributes.name`
75
- - If found, download via:
76
- ```bash
77
- curl -s --user ":{AZURE_DEVOPS_PAT}" "{attachment-url}"
78
- ```
79
- - Read content for test data, expected values, error logs, or sample datasets that define expected behavior
80
-
81
- ---
82
-
83
- ### Phase 2b: Deduplication Check — Query Existing Test Cases
84
-
85
- Before generating any new test cases, check whether the source work item already has linked test cases to prevent duplicates.
86
-
87
- 1. Inspect the relations returned in Phase 2 — filter for link type `"Microsoft.VSTS.Common.TestedBy-Forward"` (i.e., *Tested By* links).
88
- 2. For each linked test case ID found, call `wit_get_work_item` to retrieve its **title** and **state**.
89
- 3. Build an **existing TC registry** — a list of `{ id, title, state }` for all currently linked test cases.
90
- 4. In Phase 5, before calling `testplan_create_test_case` for each planned TC, compare its title (normalized: lowercase, trimmed) against every title in the registry.
91
- - **If match found** and existing TC is in state `Design`, `Ready`, or `Closed`: skip creation, log `"Skipped — duplicate of TC #{id}"`.
92
- - **If match found** but existing TC is in state `Removed`: create the new TC anyway (the old one was intentionally discarded).
93
- - **If no match**: proceed with creation.
94
- 5. Include a **Dedup Summary** section in the output report.
95
-
96
- Skip this check with `--skip-dedup`.
97
-
98
- ---
99
-
100
- ### Phase 3: Identify Work Item Type and Extract Test Source Content
101
-
102
- Apply the correct extraction strategy based on work item type:
103
-
104
- #### If type is `Bug` or `Ticket`:
105
-
106
- Primary source **Repro Steps** (`Microsoft.VSTS.TCM.ReproSteps`):
107
- - Each distinct action sequence is a candidate test case
108
- - The repro steps define the *negative path* (what triggers the bug)
109
- - Derive the *positive/fix-verification path* by inverting the expected outcome
110
- - Also read: **System Info** (`Microsoft.VSTS.TCM.SystemInfo`), **Description**, **QA Notes** (`CIIScrum.QANotes`)
111
- - Check `Custom.Whatisexpectedtohappen` and `Custom.Whatisactuallyhappening` to anchor pass/fail assertions
112
-
113
- Secondary sources:
114
- - Comments for tester observations or specific scenarios to cover
115
- - Attachments for error data or sample inputs
116
-
117
- #### If type is `User Story`:
118
-
119
- Primary source — **Acceptance Criteria** (`Microsoft.VSTS.Common.AcceptanceCriteria`):
120
- - Each acceptance criterion (Given/When/Then or checklist) maps to one or more test cases
121
- - Also read: **Description** for context and implied behaviors
122
-
123
- Secondary sources:
124
- - Comments for clarifications, edge cases raised in refinement, or stakeholder scenarios
125
- - Attachments for wireframes described in text, sample data, or business rules documents
126
-
127
- #### If type is unrecognized or fields are empty:
128
-
129
- Fall back to **Description** as the primary source. Extract any stated behaviors, expected outcomes, or constraints. Note the fallback in the output.
130
-
131
- **Cross-reference with codebase map** (if available):
132
- - Match mentioned components/features against `TEST_SURFACE.md` entry points
133
- - Check `RISK_MAP.md` for risk level of affected areas
134
- - Use `API_CONTRACTS.md` for exact endpoint shapes if the work item mentions API behavior
135
- - Use `CODE_PATTERNS.md` to align test step language with project conventions
136
-
137
- ---
138
-
139
- ### Phase 4: Analyze and Design Test Cases
140
-
141
- Before creating anything in Azure DevOps, plan out all test cases:
142
-
143
- **For each distinct scenario identified, determine:**
144
-
145
- 1. **Test Case Title** concise action-oriented name (e.g., "Verify guest pass entry counter resets at midnight")
146
- 2. **Steps** formatted as `{step action} | {expected result}` per step, using `|` as the delimiter
147
- 3. **Priority** — 1 (Critical), 2 (High), 3 (Medium), 4 (Low)
148
- 4. **Tags** one or more of: `Smoke`, `Regression`, `Critical`, `AutomationCandidate`, `NeedsReview`
149
- 5. **Preconditions** — required setup before executing the test
150
- 6. **Confidence** `Specified` or `Draft`
151
-
152
- **Minimum test case coverage per work item type:**
153
-
154
- | Scenario Type | Bug/Ticket | User Story |
155
- |---------------|-----------|------------|
156
- | Happy path (fix verified / AC met) | Required | Required per AC item |
157
- | Negative / error path | Required (original repro) | Where AC implies failure states |
158
- | Boundary / edge cases | If data-driven | If AC contains limits or conditions |
159
- | Boundary value triplets (n-1, n, n+1) | If limits detected | If AC contains limits/ranges |
160
- | Regression guard (related area) | Required | Required |
161
-
162
- #### Boundary Value Detection
163
-
164
- Scan all source content for **boundary keyword triggers**:
165
-
166
- > `max`, `min`, `limit`, `threshold`, `cap`, `ceiling`, `floor`, `range`, `between`, `up to`, `at most`, `at least`, `no more than`, `no fewer than`, `maximum`, `minimum`, `exactly`, `exceeds`, `boundary`
167
-
168
- When a trigger is found alongside a numeric value **N**:
169
-
170
- 1. **Generate three test cases** (the boundary triplet):
171
- - **N - 1** — just below the boundary
172
- - **N** exactly at the boundary
173
- - **N + 1** — just above the boundary
174
- 2. Title them clearly: e.g., `"Verify entry limit at 99 (below threshold)"`, `"...at 100 (at threshold)"`, `"...at 101 (above threshold)"`.
175
- 3. Tag all three with `Regression`.
176
- 4. If the boundary is on a critical-path field (per `CRITICAL_PATHS.md` or keyword detection), also tag `Critical`.
177
-
178
- If the source mentions a range, generate boundary triplets for **both** ends.
179
-
180
- #### Tagging Rules
181
-
182
- | Tag | Assign when... |
183
- |-----|---------------|
184
- | `Smoke` | Verifies core, user-facing functionality that must work for the app to be usable at all. Limit to the most essential 1-2 cases per work item. |
185
- | `Regression` | Guards against the specific bug or behavior being re-introduced. Every fix-verification test for a Bug/Ticket should be tagged. For User Stories, tag tests covering AC that touches shared or high-traffic code paths. |
186
- | `Critical` | Covers functionality whose failure would directly impact revenue, security, data integrity, or legal compliance. **Also apply when critical keywords are detected** (see Keyword-Based Critical Tagging below). Apply conservatively. |
187
- | `AutomationCandidate` | Test has: (a) deterministic steps with no subjective judgment, (b) assertions based on concrete data/state, (c) no manual-only prerequisites. Advisory only — QA confirms. |
188
-
189
- **Do not assign Smoke to every test case.** Smoke tests are a small, fast-running set.
190
-
191
- #### Keyword-Based Critical Tagging
192
-
193
- Automatically tag as `Critical` when any of the following keywords appear in the source content:
194
-
195
- > `auth`, `authentication`, `login`, `password`, `OAuth`, `SSO`, `payment`, `billing`, `charge`, `invoice`, `PII`, `personal data`, `SSN`, `date of birth`, `security`, `encryption`, `token`, `certificate`, `data integrity`, `transaction`, `rollback`, `compliance`, `HIPAA`, `GDPR`, `SOC`, `audit`, `permission`, `role-based`, `access control`
196
-
197
- Cross-reference with `RISK_MAP.md` (if available) for additional risk-based tagging.
198
-
199
- #### Confidence Scoring
200
-
201
- | Confidence | Criteria | Behavior |
202
- |------------|----------|----------|
203
- | **Specified** | Source content explicitly describes the scenario, expected outcome, and data. | Create the TC normally. |
204
- | **Draft** | Scenario is implied or partially described — inferred from context or sparse source. | Prefix TC title with `[DRAFT]`. Add `NeedsReview` tag. Add final step: `"Review — this test case was auto-generated from sparse source material and requires QA validation before execution." | "QA has reviewed and confirmed or updated the steps."` |
205
-
206
- **Threshold**: If more than 50% of the source content fields are empty or contain fewer than 20 words, default all inferred TCs to Draft.
207
-
208
- #### Preconditions Block
209
-
210
- Every test case documents preconditions:
211
-
212
- | Field | Description | Example |
213
- |-------|-------------|--------|
214
- | **Required Role(s)** | User role(s) or permission level(s) needed | `Admin`, `Property Manager`, `Resident` |
215
- | **Application State** | System/feature state that must be true before step 1 | `User is logged in`, `Feature flag X is enabled` |
216
- | **Test Data** | Specific data that must exist or be created | `Resident account with active lease` |
217
- | **Environment** | Environment-specific requirements | `Staging`, `API key configured` |
218
-
219
- Prepend preconditions to the TC description field in Azure DevOps:
220
-
221
- ```
222
- **Preconditions**
223
- - Role(s): {roles}
224
- - State: {state}
225
- - Test Data: {data}
226
- - Environment: {env}
227
- ```
228
-
229
- If locator registry data is available, include relevant locator references in test steps for E2E-related scenarios.
230
-
231
- ---
232
-
233
- ### Phase 5: Create Test Cases in Azure DevOps
234
-
235
- **Dedup gate**: Before creating each TC, check against the registry from Phase 2b.
236
-
237
- For each planned test case, call `testplan_create_test_case` with:
238
-
239
- - `project`: the work item's project
240
- - `title`: the test case title prefixed with `[DRAFT]` if confidence is Draft
241
- - `steps`: formatted as `1. {action}|{expected result}\n2. {action}|{expected result}` use `|` as delimiter. **Never pass XML or pre-formatted `<steps>` markup** — the tool generates XML from plain-text format.
242
- - `priority`: numeric priority (1-4)
243
- - `iterationPath`: use `--iteration-path` override if provided, otherwise source work item's iteration path
244
- - `areaPath`: use `--area-path` override if provided, otherwise source work item's area path
245
-
246
- **After creating each test case:**
247
-
248
- 1. Call `wit_add_artifact_link` or `wit_work_items_link` to link the new TC to the source work item using link type `"tested by"`:
249
- ```
250
- source work item --[Tested By]--> test case
251
- ```
252
-
253
- 2. Call `wit_update_work_item` on the new TC to set `System.Tags` to semicolon-separated tags (e.g., `"Regression; Critical; AutomationCandidate"`).
254
- - Draft TCs always include `NeedsReview`.
255
-
256
- Create all test cases sequentially capture each new TC ID before proceeding.
257
-
258
- ---
259
-
260
- ### Phase 6: Synthesize the Output Report
261
-
262
- Save the report to `ai-tasks/ticket-$ARGUMENTS/test-cases.md`.
263
-
264
- **Required document structure:**
265
-
266
- ```markdown
267
- # Test Cases: {work-item-id} {Work Item Title}
268
-
269
- **Generated**: {current date}
270
- **Work Item**: [{work-item-id}]({azure-devops-url}) — {type} | {state}
271
- **Assigned To**: {assigned-to}
272
- **Area Path**: {area path}
273
- **Iteration**: {iteration path}
274
- **Test Source**: {Repro Steps / Acceptance Criteria / Description (fallback)}
275
- **Pipeline Context**: Codebase map: {yes/no}, Locator registry: {yes/no}, Preferences: {yes/no}
276
-
277
- ---
278
-
279
- ## Source Analysis
280
-
281
- ### Work Item Summary
282
- {2-3 sentences describing the work item and what behavior needed to be tested.}
283
-
284
- ### Key Scenarios Identified
285
- {Bulleted list of distinct testable scenarios extracted before designing test cases.}
286
-
287
- ### Source Content Notes
288
- {Observations about quality/completeness of source material. Were repro steps/AC clear? Did comments add scenarios?}
289
-
290
- ### Codebase Context Used
291
- {If codebase map was available: list which documents were read and what context they provided. If not available: note that test cases were generated without codebase context.}
292
-
293
- ---
294
-
295
- ## Test Cases Created
296
-
297
- ### TC-{azure-devops-id}: {title}
298
-
299
- **Confidence**: `Specified` or `[DRAFT] — NeedsReview`
300
- **Tags**: `{Smoke}` · `{Regression}` · `{Critical}` · `{AutomationCandidate}` · `{NeedsReview}` *(show only tags that apply)*
301
- **Priority**: {1 Critical / 2 High / 3 – Medium / 4 – Low}
302
- **Linked To**: Work Item #{work-item-id} via *Tested By*
303
- **Azure DevOps ID**: {test-case-id}
304
-
305
- **Preconditions:**
306
- - **Role(s)**: {required roles or N/A}
307
- - **State**: {required application state or N/A}
308
- - **Test Data**: {required data or N/A}
309
- - **Environment**: {environment requirements or N/A}
310
-
311
- **Test Steps:**
312
-
313
- | # | Action | Expected Result |
314
- |---|--------|-----------------|
315
- | 1 | {action} | {expected result} |
316
- | 2 | {action} | {expected result} |
317
-
318
- {Repeat for each test case.}
319
-
320
- ---
321
-
322
- ## Tag Summary
323
-
324
- | Tag | Count | Test Case IDs |
325
- |-----|-------|---------------|
326
- | Smoke | {n} | {comma-separated IDs} |
327
- | Regression | {n} | {comma-separated IDs} |
328
- | Critical | {n} | {comma-separated IDs} |
329
- | AutomationCandidate | {n} | {comma-separated IDs} |
330
- | NeedsReview | {n} | {comma-separated IDs} |
331
-
332
- ---
333
-
334
- ## Dedup Summary
335
-
336
- | Planned Title | Skipped Reason | Existing TC |
337
- |---------------|---------------|-------------|
338
- | {title} | Duplicate of TC #{id} | #{id} {state} |
339
-
340
- {If no duplicates: "No duplicates detected — all test cases were created."}
341
-
342
- ---
343
-
344
- ## Traceability
345
-
346
- All test cases linked to work item **#{work-item-id}** via *Tested By*.
347
-
348
- **Path Overrides Applied**: {If --area-path or --iteration-path provided, state them. Otherwise: "None — used source work item paths."}
349
- **Confidence Breakdown**: {n} Specified, {n} Draft (NeedsReview)
350
- **Boundary Triplets Generated**: {n} (from {n} detected boundaries)
351
- ```
352
-
353
- ---
354
-
355
- ### Phase 7: Attach Report to Source Work Item
356
-
357
- **If `ADO_MCP_AUTH_TOKEN` is set:**
358
-
359
- Upload `test-cases.md` as an attachment:
360
-
361
- ```bash
362
- # Step 1: Upload file
363
- ATTACHMENT_URL=$(curl -s \
364
- --header "Authorization: Basic $(echo -n :${ADO_MCP_AUTH_TOKEN} | base64)" \
365
- --header "Content-Type: application/octet-stream" \
366
- --request POST \
367
- --data-binary "@ai-tasks/ticket-$ARGUMENTS/test-cases.md" \
368
- "https://dev.azure.com/{org}/{project}/_apis/wit/attachments?fileName=test-cases.md&api-version=7.1" \
369
- | python3 -c "import sys,json; print(json.load(sys.stdin)['url'])")
370
-
371
- # Step 2: Link attachment to work item
372
- curl -s \
373
- --header "Authorization: Basic $(echo -n :${ADO_MCP_AUTH_TOKEN} | base64)" \
374
- --header "Content-Type: application/json-patch+json" \
375
- --request PATCH \
376
- --data "[{\"op\":\"add\",\"path\":\"/relations/-\",\"value\":{\"rel\":\"AttachedFile\",\"url\":\"${ATTACHMENT_URL}\",\"attributes\":{\"comment\":\"Generated test cases report\"}}}]" \
377
- "https://dev.azure.com/{org}/{project}/_apis/wit/workItems/$ARGUMENTS?api-version=7.1"
378
- ```
379
-
380
- **If `ADO_MCP_AUTH_TOKEN` is NOT set (fallback):**
381
-
382
- Write the full report as HTML to the work item's `Custom.QATestCasesReport` field via `wit_update_work_item`. Include all sections converted to HTML.
383
-
384
- Note in the final report which method was used.
385
-
386
- ---
387
-
388
- ## Final Report to User
389
-
390
- After completing all phases, provide:
391
-
392
- 1. Brief inline summary (2-3 sentences) of scenarios covered
393
- 2. Full path to generated file: `ai-tasks/ticket-{id}/test-cases.md`
394
- 3. Table of every created TC: ID, title, tags, confidence
395
- 4. Counts by tag: Smoke, Regression, Critical, AutomationCandidate, NeedsReview
396
- 5. Dedup summary: how many planned TCs were skipped
397
- 6. Confidence summary: Specified vs Draft counts
398
- 7. Boundary summary: how many boundary triplets generated
399
- 8. Pipeline context: which codebase map documents and locator registry data were used
400
- 9. Gaps or assumptions made
401
- 10. Path override confirmation (if used)
402
- 11. Report delivery confirmation (attached as file or written to custom field)
403
-
404
- $ARGUMENTS
1
+ # QA Create Test — Azure DevOps
2
+
3
+ Retrieve an Azure DevOps work item, analyze its content, and generate well-structured Test Cases directly in Azure DevOps using the ADO MCP tools. Each test case is tagged for test plan membership (Smoke, Regression, Critical) and linked back to the source work item for full traceability. Integrates with the QAA pipeline: reads codebase map, locator registry, and user preferences for context-aware test case generation.
4
+
5
+ ## ⚠ MANDATORY: How to Execute This Command
6
+
7
+ Execute these steps IN ORDER. Every step is mandatory. Do NOT improvise,
8
+ reorder, skip, or invent steps. This command talks to Azure DevOps via the ADO
9
+ MCP tools; it spawns no sub-agents.
10
+
11
+ 1. Resolve the work item ID from `$ARGUMENTS` — it is REQUIRED. If missing, ask
12
+ the user before doing anything else.
13
+ 2. PHASE 1 Read pipeline context: `CLAUDE.md`, `~/.claude/qaa/MY_PREFERENCES.md`
14
+ (if it exists), the codebase map (`.qa-output/codebase/`), and the locator
15
+ registry. If no codebase map and `--skip-map` was not passed, warn and continue.
16
+ 3. PHASE 2 Retrieve the work item (`wit_get_work_item` with relations), its
17
+ comments, and its attachments.
18
+ 4. PHASE 2b Deduplication check: build the registry of already-linked test
19
+ cases (unless `--skip-dedup`). This gate is mandatory before creating anything.
20
+ 5. PHASE 3-4 Identify the work item type, extract test-source content, and
21
+ design ALL test cases (titles, steps, priority, tags, preconditions,
22
+ confidence) BEFORE creating anything in ADO.
23
+ 6. PHASE 5 — Create the test cases in ADO: apply the dedup gate before each one,
24
+ link every new TC to the source work item via *Tested By*, and set its tags.
25
+ Pass steps as plain text with `|` delimiters NEVER XML / `<steps>` markup.
26
+ 7. PHASE 6-7 Synthesize the report to `ai-tasks/ticket-{id}/test-cases.md`,
27
+ attach it to the work item (or write to `Custom.QATestCasesReport` as a
28
+ fallback), then give the final summary to the user.
29
+
30
+ ### DO NOT
31
+ - Create any test case before the deduplication check (unless `--skip-dedup`)
32
+ - Skip linking each new TC via *Tested By*, or skip setting its tags
33
+ - Pass pre-formatted XML / `<steps>` to `testplan_create_test_case` (plain text + `|`)
34
+ - Overwrite unrelated work-item fields
35
+ - Invent steps not in this command, or reorder the phases
36
+
37
+ If you find yourself creating test cases before dedup, skipping the *Tested By*
38
+ links, or passing XML steps STOP and restart from step 1.
39
+
40
+ ## Usage
41
+
42
+ ```
43
+ /qa-create-test-ado <work-item-id> [--area-path=<path>] [--iteration-path=<path>] [--skip-map] [--skip-dedup] [--app-url <url>]
44
+ ```
45
+
46
+ ### Arguments
47
+
48
+ | Parameter | Purpose | Default |
49
+ |-----------|---------|---------|
50
+ | `<work-item-id>` | Azure DevOps work item ID to generate test cases from | Required |
51
+ | `--area-path=<path>` | Override area path for all created test artifacts | Source work item's area path |
52
+ | `--iteration-path=<path>` | Override iteration path for all created test artifacts | Source work item's iteration path |
53
+ | `--skip-map` | Skip codebase map check and proceed without project context | false |
54
+ | `--skip-dedup` | Skip deduplication check against existing linked test cases | false |
55
+ | `--app-url <url>` | URL of running application for locator extraction via Playwright MCP | auto-detect |
56
+
57
+ ## What It Produces
58
+
59
+ - Test Cases created directly in Azure DevOps (via `testplan_create_test_case`)
60
+ - Test Cases linked to source work item via *Tested By* relationship
61
+ - Tags applied: `Smoke`, `Regression`, `Critical`, `AutomationCandidate`, `NeedsReview`
62
+ - `ai-tasks/ticket-{id}/test-cases.md` structured report
63
+ - Report attached to work item (if `ADO_MCP_AUTH_TOKEN` is set) or written to `Custom.QATestCasesReport` field (fallback)
64
+
65
+ ---
66
+
67
+ ## Pre-flight checks
68
+
69
+ Run these BEFORE the main flow. If a **[STOP]** check fails, print the error EXACTLY as shown (fill in the `{...}` placeholders) and STOP.
70
+
71
+ ### Azure DevOps MCP not connected [STOP]
72
+ If the ADO MCP tools (`wit_get_work_item`, `testplan_create_test_case`) are unavailable:
73
+ ```
74
+ Azure DevOps MCP is not connected this command can't reach ADO.
75
+
76
+ /qa-create-test-ado reads a work item and creates Test Cases directly in Azure
77
+ DevOps via the ADO MCP tools. They aren't available in this session.
78
+
79
+ Options:
80
+ 1. Connect the Azure DevOps MCP server, then re-run
81
+ 2. Verify it's configured in your Claude Code MCP settings
82
+ 3. If you only need local test files (not ADO Test Cases), use /qa-create-test instead
83
+
84
+ Try: /mcp (to see connected MCP servers)
85
+ ```
86
+
87
+ ### Work item ID missing or not found [STOP]
88
+ - If NO work item ID was provided, print:
89
+ ```
90
+ No work item ID provided.
91
+
92
+ /qa-create-test-ado needs an Azure DevOps work item ID (Bug, User Story, or
93
+ Ticket) to read from.
94
+
95
+ Options:
96
+ 1. Pass one: /qa-create-test-ado <work-item-id>
97
+ 2. Copy the numeric ID from the work item's ADO URL
98
+ 3. If you only need local test files (not ADO Test Cases), use /qa-create-test instead
99
+
100
+ Try: /qa-create-test-ado 85508 (example)
101
+ ```
102
+ - If an ID WAS provided but `wit_get_work_item` returns nothing for it, print:
103
+ ```
104
+ Work item not found: {id}
105
+
106
+ The ID you gave doesn't resolve to a work item you can access.
107
+
108
+ Options:
109
+ 1. Double-check the numeric ID from the work item's ADO URL
110
+ 2. Confirm you have access to that work item's project
111
+ 3. Re-run with the correct ID: /qa-create-test-ado <work-item-id>
112
+ ```
113
+
114
+ ## Process
115
+
116
+ ### Phase 1: Read Pipeline Context
117
+
118
+ Before retrieving the work item, read QAA pipeline artifacts for context-aware generation.
119
+
120
+ 1. **Read `CLAUDE.md`** POM rules, locator tiers, assertion rules, naming conventions, quality gates, test spec rules.
121
+
122
+ 2. **Read user preferences** — `~/.claude/qaa/MY_PREFERENCES.md` (if exists). User overrides win over defaults.
123
+
124
+ 3. **Check for codebase map** (`.qa-output/codebase/`):
125
+ - Look for: `CODE_PATTERNS.md`, `API_CONTRACTS.md`, `TEST_SURFACE.md`, `TESTABILITY.md`, `RISK_MAP.md`, `CRITICAL_PATHS.md`
126
+ - If at least 2 exist: read them all for project context (naming conventions, API shapes, testable surfaces, risk areas).
127
+ - If NONE exist and `--skip-map` not passed: warn the user that test cases will lack project context, suggest running `/qa-map` first. Continue anyway (ADO test cases are higher-level than code-level tests).
128
+
129
+ 4. **Check locator registry** `.qa-output/locators/LOCATOR_REGISTRY.md` (if exists):
130
+ - If locators exist for pages related to the work item's feature: reference them in test step expected results (e.g., "Verify element `[data-testid='login-submit-btn']` is visible").
131
+ - If `--app-url` provided and locators missing: use Playwright MCP to extract locators from the live app before designing test steps:
132
+ ```
133
+ mcp__playwright__browser_navigate({ url: "{app_url}/{feature_path}" })
134
+ mcp__playwright__browser_snapshot()
135
+ ```
136
+ - Write extracted locators to `.qa-output/locators/{feature}.locators.md` and update the registry.
137
+
138
+ ---
139
+
140
+ ### Phase 2: Retrieve the Work Item
141
+
142
+ Use `wit_get_work_item` with `expand: "relations"` to fetch the full work item:
143
+
144
+ - Capture: **title**, **type** (`Bug`, `User Story`, `Ticket`), **state**, **assigned-to**, **area path**, **iteration path**
145
+ - Capture all relevant content fields based on type (see Phase 3)
146
+ - Note the project for all subsequent calls
147
+
148
+ **Also retrieve comments** using `wit_list_work_item_comments`:
149
+
150
+ - Read all comments in chronological order
151
+ - Look for: acceptance criteria added in comments, QA notes, scope clarifications, tester feedback, or any conditions of satisfaction mentioned informally
152
+ - These often contain implied test cases not captured in the formal fields
153
+
154
+ **Also check attachments** from the relations list (entries where `rel` equals `AttachedFile`):
155
+
156
+ - Filter to `.csv` and `.txt` files (case-insensitive) by inspecting `attributes.name`
157
+ - If found, download via:
158
+ ```bash
159
+ curl -s --user ":{AZURE_DEVOPS_PAT}" "{attachment-url}"
160
+ ```
161
+ - Read content for test data, expected values, error logs, or sample datasets that define expected behavior
162
+
163
+ ---
164
+
165
+ ### Phase 2b: Deduplication Check — Query Existing Test Cases
166
+
167
+ Before generating any new test cases, check whether the source work item already has linked test cases to prevent duplicates.
168
+
169
+ 1. Inspect the relations returned in Phase 2 — filter for link type `"Microsoft.VSTS.Common.TestedBy-Forward"` (i.e., *Tested By* links).
170
+ 2. For each linked test case ID found, call `wit_get_work_item` to retrieve its **title** and **state**.
171
+ 3. Build an **existing TC registry** — a list of `{ id, title, state }` for all currently linked test cases.
172
+ 4. In Phase 5, before calling `testplan_create_test_case` for each planned TC, compare its title (normalized: lowercase, trimmed) against every title in the registry.
173
+ - **If match found** and existing TC is in state `Design`, `Ready`, or `Closed`: skip creation, log `"Skipped duplicate of TC #{id}"`.
174
+ - **If match found** but existing TC is in state `Removed`: create the new TC anyway (the old one was intentionally discarded).
175
+ - **If no match**: proceed with creation.
176
+ 5. Include a **Dedup Summary** section in the output report.
177
+
178
+ Skip this check with `--skip-dedup`.
179
+
180
+ ---
181
+
182
+ ### Phase 3: Identify Work Item Type and Extract Test Source Content
183
+
184
+ Apply the correct extraction strategy based on work item type:
185
+
186
+ #### If type is `Bug` or `Ticket`:
187
+
188
+ Primary source — **Repro Steps** (`Microsoft.VSTS.TCM.ReproSteps`):
189
+ - Each distinct action sequence is a candidate test case
190
+ - The repro steps define the *negative path* (what triggers the bug)
191
+ - Derive the *positive/fix-verification path* by inverting the expected outcome
192
+ - Also read: **System Info** (`Microsoft.VSTS.TCM.SystemInfo`), **Description**, **QA Notes** (`CIIScrum.QANotes`)
193
+ - Check `Custom.Whatisexpectedtohappen` and `Custom.Whatisactuallyhappening` to anchor pass/fail assertions
194
+
195
+ Secondary sources:
196
+ - Comments for tester observations or specific scenarios to cover
197
+ - Attachments for error data or sample inputs
198
+
199
+ #### If type is `User Story`:
200
+
201
+ Primary source **Acceptance Criteria** (`Microsoft.VSTS.Common.AcceptanceCriteria`):
202
+ - Each acceptance criterion (Given/When/Then or checklist) maps to one or more test cases
203
+ - Also read: **Description** for context and implied behaviors
204
+
205
+ Secondary sources:
206
+ - Comments for clarifications, edge cases raised in refinement, or stakeholder scenarios
207
+ - Attachments for wireframes described in text, sample data, or business rules documents
208
+
209
+ #### If type is unrecognized or fields are empty:
210
+
211
+ Fall back to **Description** as the primary source. Extract any stated behaviors, expected outcomes, or constraints. Note the fallback in the output.
212
+
213
+ **Cross-reference with codebase map** (if available):
214
+ - Match mentioned components/features against `TEST_SURFACE.md` entry points
215
+ - Check `RISK_MAP.md` for risk level of affected areas
216
+ - Use `API_CONTRACTS.md` for exact endpoint shapes if the work item mentions API behavior
217
+ - Use `CODE_PATTERNS.md` to align test step language with project conventions
218
+
219
+ ---
220
+
221
+ ### Phase 4: Analyze and Design Test Cases
222
+
223
+ Before creating anything in Azure DevOps, plan out all test cases:
224
+
225
+ **For each distinct scenario identified, determine:**
226
+
227
+ 1. **Test Case Title** — concise action-oriented name (e.g., "Verify guest pass entry counter resets at midnight")
228
+ 2. **Steps** — formatted as `{step action} | {expected result}` per step, using `|` as the delimiter
229
+ 3. **Priority** 1 (Critical), 2 (High), 3 (Medium), 4 (Low)
230
+ 4. **Tags** — one or more of: `Smoke`, `Regression`, `Critical`, `AutomationCandidate`, `NeedsReview`
231
+ 5. **Preconditions** — required setup before executing the test
232
+ 6. **Confidence** — `Specified` or `Draft`
233
+
234
+ **Minimum test case coverage per work item type:**
235
+
236
+ | Scenario Type | Bug/Ticket | User Story |
237
+ |---------------|-----------|------------|
238
+ | Happy path (fix verified / AC met) | Required | Required per AC item |
239
+ | Negative / error path | Required (original repro) | Where AC implies failure states |
240
+ | Boundary / edge cases | If data-driven | If AC contains limits or conditions |
241
+ | Boundary value triplets (n-1, n, n+1) | If limits detected | If AC contains limits/ranges |
242
+ | Regression guard (related area) | Required | Required |
243
+
244
+ #### Boundary Value Detection
245
+
246
+ Scan all source content for **boundary keyword triggers**:
247
+
248
+ > `max`, `min`, `limit`, `threshold`, `cap`, `ceiling`, `floor`, `range`, `between`, `up to`, `at most`, `at least`, `no more than`, `no fewer than`, `maximum`, `minimum`, `exactly`, `exceeds`, `boundary`
249
+
250
+ When a trigger is found alongside a numeric value **N**:
251
+
252
+ 1. **Generate three test cases** (the boundary triplet):
253
+ - **N - 1** just below the boundary
254
+ - **N** exactly at the boundary
255
+ - **N + 1** — just above the boundary
256
+ 2. Title them clearly: e.g., `"Verify entry limit at 99 (below threshold)"`, `"...at 100 (at threshold)"`, `"...at 101 (above threshold)"`.
257
+ 3. Tag all three with `Regression`.
258
+ 4. If the boundary is on a critical-path field (per `CRITICAL_PATHS.md` or keyword detection), also tag `Critical`.
259
+
260
+ If the source mentions a range, generate boundary triplets for **both** ends.
261
+
262
+ #### Tagging Rules
263
+
264
+ | Tag | Assign when... |
265
+ |-----|---------------|
266
+ | `Smoke` | Verifies core, user-facing functionality that must work for the app to be usable at all. Limit to the most essential 1-2 cases per work item. |
267
+ | `Regression` | Guards against the specific bug or behavior being re-introduced. Every fix-verification test for a Bug/Ticket should be tagged. For User Stories, tag tests covering AC that touches shared or high-traffic code paths. |
268
+ | `Critical` | Covers functionality whose failure would directly impact revenue, security, data integrity, or legal compliance. **Also apply when critical keywords are detected** (see Keyword-Based Critical Tagging below). Apply conservatively. |
269
+ | `AutomationCandidate` | Test has: (a) deterministic steps with no subjective judgment, (b) assertions based on concrete data/state, (c) no manual-only prerequisites. Advisory only — QA confirms. |
270
+
271
+ **Do not assign Smoke to every test case.** Smoke tests are a small, fast-running set.
272
+
273
+ #### Keyword-Based Critical Tagging
274
+
275
+ Automatically tag as `Critical` when any of the following keywords appear in the source content:
276
+
277
+ > `auth`, `authentication`, `login`, `password`, `OAuth`, `SSO`, `payment`, `billing`, `charge`, `invoice`, `PII`, `personal data`, `SSN`, `date of birth`, `security`, `encryption`, `token`, `certificate`, `data integrity`, `transaction`, `rollback`, `compliance`, `HIPAA`, `GDPR`, `SOC`, `audit`, `permission`, `role-based`, `access control`
278
+
279
+ Cross-reference with `RISK_MAP.md` (if available) for additional risk-based tagging.
280
+
281
+ #### Confidence Scoring
282
+
283
+ | Confidence | Criteria | Behavior |
284
+ |------------|----------|----------|
285
+ | **Specified** | Source content explicitly describes the scenario, expected outcome, and data. | Create the TC normally. |
286
+ | **Draft** | Scenario is implied or partially described — inferred from context or sparse source. | Prefix TC title with `[DRAFT]`. Add `NeedsReview` tag. Add final step: `"Review — this test case was auto-generated from sparse source material and requires QA validation before execution." | "QA has reviewed and confirmed or updated the steps."` |
287
+
288
+ **Threshold**: If more than 50% of the source content fields are empty or contain fewer than 20 words, default all inferred TCs to Draft.
289
+
290
+ #### Preconditions Block
291
+
292
+ Every test case documents preconditions:
293
+
294
+ | Field | Description | Example |
295
+ |-------|-------------|--------|
296
+ | **Required Role(s)** | User role(s) or permission level(s) needed | `Admin`, `Property Manager`, `Resident` |
297
+ | **Application State** | System/feature state that must be true before step 1 | `User is logged in`, `Feature flag X is enabled` |
298
+ | **Test Data** | Specific data that must exist or be created | `Resident account with active lease` |
299
+ | **Environment** | Environment-specific requirements | `Staging`, `API key configured` |
300
+
301
+ Prepend preconditions to the TC description field in Azure DevOps:
302
+
303
+ ```
304
+ **Preconditions**
305
+ - Role(s): {roles}
306
+ - State: {state}
307
+ - Test Data: {data}
308
+ - Environment: {env}
309
+ ```
310
+
311
+ If locator registry data is available, include relevant locator references in test steps for E2E-related scenarios.
312
+
313
+ ---
314
+
315
+ ### Phase 5: Create Test Cases in Azure DevOps
316
+
317
+ **Dedup gate**: Before creating each TC, check against the registry from Phase 2b.
318
+
319
+ For each planned test case, call `testplan_create_test_case` with:
320
+
321
+ - `project`: the work item's project
322
+ - `title`: the test case title — prefixed with `[DRAFT]` if confidence is Draft
323
+ - `steps`: formatted as `1. {action}|{expected result}\n2. {action}|{expected result}` — use `|` as delimiter. **Never pass XML or pre-formatted `<steps>` markup** — the tool generates XML from plain-text format.
324
+ - `priority`: numeric priority (1-4)
325
+ - `iterationPath`: use `--iteration-path` override if provided, otherwise source work item's iteration path
326
+ - `areaPath`: use `--area-path` override if provided, otherwise source work item's area path
327
+
328
+ **After creating each test case:**
329
+
330
+ 1. Call `wit_add_artifact_link` or `wit_work_items_link` to link the new TC to the source work item using link type `"tested by"`:
331
+ ```
332
+ source work item --[Tested By]--> test case
333
+ ```
334
+
335
+ 2. Call `wit_update_work_item` on the new TC to set `System.Tags` to semicolon-separated tags (e.g., `"Regression; Critical; AutomationCandidate"`).
336
+ - Draft TCs always include `NeedsReview`.
337
+
338
+ Create all test cases sequentially capture each new TC ID before proceeding.
339
+
340
+ ---
341
+
342
+ ### Phase 6: Synthesize the Output Report
343
+
344
+ Save the report to `ai-tasks/ticket-$ARGUMENTS/test-cases.md`.
345
+
346
+ **Required document structure:**
347
+
348
+ ```markdown
349
+ # Test Cases: {work-item-id} {Work Item Title}
350
+
351
+ **Generated**: {current date}
352
+ **Work Item**: [{work-item-id}]({azure-devops-url}) — {type} | {state}
353
+ **Assigned To**: {assigned-to}
354
+ **Area Path**: {area path}
355
+ **Iteration**: {iteration path}
356
+ **Test Source**: {Repro Steps / Acceptance Criteria / Description (fallback)}
357
+ **Pipeline Context**: Codebase map: {yes/no}, Locator registry: {yes/no}, Preferences: {yes/no}
358
+
359
+ ---
360
+
361
+ ## Source Analysis
362
+
363
+ ### Work Item Summary
364
+ {2-3 sentences describing the work item and what behavior needed to be tested.}
365
+
366
+ ### Key Scenarios Identified
367
+ {Bulleted list of distinct testable scenarios extracted before designing test cases.}
368
+
369
+ ### Source Content Notes
370
+ {Observations about quality/completeness of source material. Were repro steps/AC clear? Did comments add scenarios?}
371
+
372
+ ### Codebase Context Used
373
+ {If codebase map was available: list which documents were read and what context they provided. If not available: note that test cases were generated without codebase context.}
374
+
375
+ ---
376
+
377
+ ## Test Cases Created
378
+
379
+ ### TC-{azure-devops-id}: {title}
380
+
381
+ **Confidence**: `Specified` or `[DRAFT] — NeedsReview`
382
+ **Tags**: `{Smoke}` · `{Regression}` · `{Critical}` · `{AutomationCandidate}` · `{NeedsReview}` *(show only tags that apply)*
383
+ **Priority**: {1 – Critical / 2 – High / 3 – Medium / 4 – Low}
384
+ **Linked To**: Work Item #{work-item-id} via *Tested By*
385
+ **Azure DevOps ID**: {test-case-id}
386
+
387
+ **Preconditions:**
388
+ - **Role(s)**: {required roles or N/A}
389
+ - **State**: {required application state or N/A}
390
+ - **Test Data**: {required data or N/A}
391
+ - **Environment**: {environment requirements or N/A}
392
+
393
+ **Test Steps:**
394
+
395
+ | # | Action | Expected Result |
396
+ |---|--------|-----------------|
397
+ | 1 | {action} | {expected result} |
398
+ | 2 | {action} | {expected result} |
399
+
400
+ {Repeat for each test case.}
401
+
402
+ ---
403
+
404
+ ## Tag Summary
405
+
406
+ | Tag | Count | Test Case IDs |
407
+ |-----|-------|---------------|
408
+ | Smoke | {n} | {comma-separated IDs} |
409
+ | Regression | {n} | {comma-separated IDs} |
410
+ | Critical | {n} | {comma-separated IDs} |
411
+ | AutomationCandidate | {n} | {comma-separated IDs} |
412
+ | NeedsReview | {n} | {comma-separated IDs} |
413
+
414
+ ---
415
+
416
+ ## Dedup Summary
417
+
418
+ | Planned Title | Skipped Reason | Existing TC |
419
+ |---------------|---------------|-------------|
420
+ | {title} | Duplicate of TC #{id} | #{id} — {state} |
421
+
422
+ {If no duplicates: "No duplicates detected — all test cases were created."}
423
+
424
+ ---
425
+
426
+ ## Traceability
427
+
428
+ All test cases linked to work item **#{work-item-id}** via *Tested By*.
429
+
430
+ **Path Overrides Applied**: {If --area-path or --iteration-path provided, state them. Otherwise: "None — used source work item paths."}
431
+ **Confidence Breakdown**: {n} Specified, {n} Draft (NeedsReview)
432
+ **Boundary Triplets Generated**: {n} (from {n} detected boundaries)
433
+ ```
434
+
435
+ ---
436
+
437
+ ### Phase 7: Attach Report to Source Work Item
438
+
439
+ **If `ADO_MCP_AUTH_TOKEN` is set:**
440
+
441
+ Upload `test-cases.md` as an attachment:
442
+
443
+ ```bash
444
+ # Step 1: Upload file
445
+ ATTACHMENT_URL=$(curl -s \
446
+ --header "Authorization: Basic $(echo -n :${ADO_MCP_AUTH_TOKEN} | base64)" \
447
+ --header "Content-Type: application/octet-stream" \
448
+ --request POST \
449
+ --data-binary "@ai-tasks/ticket-$ARGUMENTS/test-cases.md" \
450
+ "https://dev.azure.com/{org}/{project}/_apis/wit/attachments?fileName=test-cases.md&api-version=7.1" \
451
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['url'])")
452
+
453
+ # Step 2: Link attachment to work item
454
+ curl -s \
455
+ --header "Authorization: Basic $(echo -n :${ADO_MCP_AUTH_TOKEN} | base64)" \
456
+ --header "Content-Type: application/json-patch+json" \
457
+ --request PATCH \
458
+ --data "[{\"op\":\"add\",\"path\":\"/relations/-\",\"value\":{\"rel\":\"AttachedFile\",\"url\":\"${ATTACHMENT_URL}\",\"attributes\":{\"comment\":\"Generated test cases report\"}}}]" \
459
+ "https://dev.azure.com/{org}/{project}/_apis/wit/workItems/$ARGUMENTS?api-version=7.1"
460
+ ```
461
+
462
+ **If `ADO_MCP_AUTH_TOKEN` is NOT set (fallback):**
463
+
464
+ Write the full report as HTML to the work item's `Custom.QATestCasesReport` field via `wit_update_work_item`. Include all sections converted to HTML.
465
+
466
+ Note in the final report which method was used.
467
+
468
+ ---
469
+
470
+ ## Final Report to User
471
+
472
+ After completing all phases, provide:
473
+
474
+ 1. Brief inline summary (2-3 sentences) of scenarios covered
475
+ 2. Full path to generated file: `ai-tasks/ticket-{id}/test-cases.md`
476
+ 3. Table of every created TC: ID, title, tags, confidence
477
+ 4. Counts by tag: Smoke, Regression, Critical, AutomationCandidate, NeedsReview
478
+ 5. Dedup summary: how many planned TCs were skipped
479
+ 6. Confidence summary: Specified vs Draft counts
480
+ 7. Boundary summary: how many boundary triplets generated
481
+ 8. Pipeline context: which codebase map documents and locator registry data were used
482
+ 9. Gaps or assumptions made
483
+ 10. Path override confirmation (if used)
484
+ 11. Report delivery confirmation (attached as file or written to custom field)
485
+
486
+ $ARGUMENTS