qaa-agent 1.9.0 → 1.9.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/CHANGELOG.md CHANGED
@@ -3,6 +3,15 @@
3
3
 
4
4
  All notable changes to QAA (QA Automation Agent) are documented here.
5
5
 
6
+ ## [1.9.1] - 2026-04-27
7
+
8
+ ### Added
9
+ - **`/qa-test-report` command** — generates a per-ticket QA execution summary and appends it to the Azure DevOps work item's `Custom.QATestCasesReport` field.
10
+ - Resolves the work item and its linked test cases (TestedBy-Forward relations)
11
+ - Pulls test case execution status via REST `/_apis/test/points` (using `ADO_MCP_AUTH_TOKEN` env var as PAT, Basic auth — same pattern as `/qa-create-test --ado`), or falls back to a manual prompt when no run result exists or the token is not set
12
+ - Renders a markdown report in chat (for review) and an HTML report appended to the ADO field — preserving prior content with a blank-line separator (no local file is written)
13
+ - Smoke-tested end-to-end (manual mode, all passed) — field write and ADO render verified
14
+
6
15
  ## [1.9.0] - 2026-04-24
7
16
 
8
17
  ### Added
@@ -0,0 +1,219 @@
1
+ # QA Test Report
2
+
3
+ Generate a per-ticket QA execution summary and append it to the Azure DevOps work item's `Custom.QATestCasesReport` field. For each test case linked to the work item, pull the execution status from ADO Test Runs — or prompt the user when ADO has no run result — then render a bulleted "Tested Scenarios" list (with a separate "Failures" section when anything failed).
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ /qa-test-report <work-item-id>
9
+ ```
10
+
11
+ ### Arguments
12
+
13
+ | Parameter | Purpose | Default |
14
+ |-----------|---------|---------|
15
+ | `<work-item-id>` | Azure DevOps work item ID (Bug, Feature, User Story, Ticket) whose linked test cases you want reported | Required — prompt the user if missing |
16
+
17
+ ## What It Produces
18
+
19
+ - Markdown report printed to chat (for user review)
20
+ - HTML report **appended** to the work item's `Custom.QATestCasesReport` field, separated from prior content by a blank line
21
+ - No local file is written
22
+
23
+ ---
24
+
25
+ ## Process
26
+
27
+ ### Phase 1 — Resolve the Work Item
28
+
29
+ 1. If `$ARGUMENTS` is empty or missing a work item ID, ask the user: *"Which Azure DevOps work item ID should I build the QA Test Cases report for?"* Wait for the answer before proceeding.
30
+ 2. Call `wit_get_work_item` with `expand: "relations"` for the resolved ID.
31
+ - Capture: **title**, **type** (`Bug`, `Feature`, `User Story`, `Ticket`), **state**, **area path**, **iteration path**.
32
+ - For context used in Phase 4, capture type-appropriate content fields:
33
+ - `Bug` / `Ticket`: **Repro Steps** (`Microsoft.VSTS.TCM.ReproSteps`), **System Info** (`Microsoft.VSTS.TCM.SystemInfo`), **Description**, **QA Notes** (`CIIScrum.QANotes`), **What is expected to happen** (`Custom.Whatisexpectedtohappen`), **What is actually happening** (`Custom.Whatisactuallyhappening`).
34
+ - `User Story`: **Acceptance Criteria** (`Microsoft.VSTS.Common.AcceptanceCriteria`), **Description**.
35
+ - `Feature`: **Description**, **Acceptance Criteria** if present.
36
+ - Note the project for all subsequent ADO calls.
37
+ 3. Also call `wit_list_work_item_comments` — comments often contain fail reasons or tester observations referenced in Phase 3 fallbacks.
38
+
39
+ ---
40
+
41
+ ### Phase 2 — Resolve the Test Case List
42
+
43
+ Source-resolution order:
44
+
45
+ 1. **Check for a local file** at `ai-tasks/ticket-{id}/test-cases.md` (produced by `/qa-create-test --ado`). If it exists, parse the TC IDs it contains — this is a hint list only.
46
+ 2. **Always query ADO** — inspect the relations returned in Phase 1, filter for link type `"Microsoft.VSTS.Common.TestedBy-Forward"` (*Tested By*), and build the authoritative list of linked TC IDs.
47
+ 3. **If both exist and disagree**: trust **ADO**. Log the discrepancy in chat as an FYI (e.g., `"TC#4521 was in local file but not linked in ADO — skipped"` or `"TC#4530 is linked in ADO but missing from local file — included"`) but proceed with the ADO list.
48
+ 4. **If no TCs are found in ADO** (and the local file has none either): print `"No test cases linked to work item #{id} — nothing to report."` and stop.
49
+
50
+ For every TC ID in the final list, call `wit_get_work_item` with `expand: "relations"` to capture: **title**, **state**, **steps** (`Microsoft.VSTS.TCM.Steps`), **priority**, **tags**, and any linked runs.
51
+
52
+ ---
53
+
54
+ ### Phase 3 — Resolve Execution Status Per Test Case
55
+
56
+ For each TC, determine a status of **Passed**, **Failed**, or **Blocked** using this order.
57
+
58
+ **Step 1 — Fetch Test Point outcomes via ADO REST (formal path).**
59
+
60
+ The ADO MCP surface does not expose Test Point outcomes, but the REST API does. Use the same auth pattern as `/qa-create-test --ado`: the `ADO_MCP_AUTH_TOKEN` env var as a PAT, sent via Basic auth.
61
+
62
+ 1. Derive **org** and **project** from the work item context captured in Phase 1 (not hardcoded). The work-item URL / project name on the `wit_get_work_item` response gives you both.
63
+ 2. If `ADO_MCP_AUTH_TOKEN` is **not set**, skip directly to Step 2 (and note in the final report: *"Auto-status skipped — ADO_MCP_AUTH_TOKEN not set."*).
64
+ 3. Otherwise, call the Test Points REST endpoint once per run with the list of linked TC IDs:
65
+
66
+ ```bash
67
+ curl -s \
68
+ --header "Authorization: Basic $(echo -n :${ADO_MCP_AUTH_TOKEN} | base64)" \
69
+ --header "Content-Type: application/json" \
70
+ --request POST \
71
+ --data '{"pointsFilter":{"testcaseIds":[<id1>,<id2>,...]}}' \
72
+ "https://dev.azure.com/{org}/{project}/_apis/test/points?api-version=7.1"
73
+ ```
74
+
75
+ 4. Parse the response. For each returned point you get: `testCase.id`, `testPlan.id`, `suite.id`, `outcome`, `lastTestRun.id`, `lastResultDetails.dateCompleted`, `lastResultDetails.runBy`.
76
+ 5. **If a TC has multiple points** (e.g., it lives in several suites or runs on multiple configurations), pick the point with the **most recent `lastResultDetails.dateCompleted`**.
77
+ 6. Map `outcome` (case-insensitive) to our statuses:
78
+ - `passed` → **Passed**
79
+ - `failed` → **Failed**
80
+ - `blocked` → **Blocked**
81
+ - `notExecuted` / `none` / `notApplicable` / `paused` / `inProgress` / `warning` / `error` → treat as missing, fall through to Step 2 for this TC
82
+ 7. **If the call fails** (non-2xx, network error, token rejected): log the failure briefly in chat, skip to Step 2 for all TCs, and note in the final report that auto-status was unavailable.
83
+
84
+ **Step 2 — Ask the user** (per TC that didn't resolve in Step 1). Show the TC ID and its synthesized scenario description (from Phase 4) for context:
85
+
86
+ ```
87
+ TC #{id} — {scenario description}
88
+ Status? [Passed / Failed / Blocked]
89
+ ```
90
+
91
+ Accept case-insensitive input. Re-prompt if the answer is not one of the three.
92
+
93
+ **Step 3 — If the resolved status is Failed**, capture a reason:
94
+
95
+ 1. Check the Test Run data first — when Step 1 returned an outcome, also fetch the Test Result for `lastTestRun.id` to read `errorMessage`/`comment`:
96
+ ```bash
97
+ curl -s \
98
+ --header "Authorization: Basic $(echo -n :${ADO_MCP_AUTH_TOKEN} | base64)" \
99
+ "https://dev.azure.com/{org}/{project}/_apis/test/Runs/{runId}/results?api-version=7.1"
100
+ ```
101
+ If the result has a non-empty `errorMessage` or `comment`, use that as the reason.
102
+ 2. Also check the TC's own comments (`wit_list_work_item_comments` for the TC ID) and the parent work item's comments for any line mentioning this TC.
103
+ 3. If no reason is found, ask the user:
104
+ ```
105
+ TC #{id} failed — what was the reason?
106
+ ```
107
+ Accept a free-text one-liner.
108
+
109
+ Keep the per-TC answers (status, reason, and auto/manual source) in memory; do not write them anywhere intermediate.
110
+
111
+ ---
112
+
113
+ ### Phase 4 — Synthesize Scenario Descriptions
114
+
115
+ For each TC, produce a **readable one-line scenario description** for the bullet list. Do **not** copy the raw TC title when it is terse or cryptic — TC titles are often shorthand.
116
+
117
+ Build the description from:
118
+ - TC **title** (starting point)
119
+ - TC **steps** (each step's action + expected result — gives you what was actually verified)
120
+ - Parent work item **description / repro steps / acceptance criteria** (gives you the user-facing phrasing of *what should be true after the fix*)
121
+
122
+ Write the description in the voice of the tested outcome, not the test action. Examples:
123
+
124
+ | Raw TC title | Good scenario description |
125
+ |---|---|
126
+ | `Verify PH row display logic` | `$0 Previous Balance row no longer appears in Payment History` |
127
+ | `Check login 401 scenario` | `Invalid credentials return a 401 with an error banner` |
128
+ | `Regression: limit 100` | `Entry limit enforced at 100 — the 101st entry is rejected` |
129
+
130
+ Keep bullets short — one line, past-tense or assertive present-tense, user-visible wording.
131
+
132
+ ---
133
+
134
+ ### Phase 5 — Build the Report
135
+
136
+ **Markdown version (for chat output):**
137
+
138
+ ```markdown
139
+ Tested Scenarios
140
+
141
+ - ✅ {scenario}
142
+ - ✅ {scenario}
143
+ - ❌ {scenario}
144
+ - ⚠️ {scenario}
145
+
146
+ Failures
147
+
148
+ - ❌ {scenario}: {reason}
149
+ ```
150
+
151
+ Rules:
152
+ - Status emoji: **Passed → ✅**, **Failed → ❌**, **Blocked → ⚠️**
153
+ - Include the `Failures` section **only if at least one TC failed**. One bullet per failure with the captured reason appended after `:`.
154
+ - Do **not** include a "Result" section.
155
+ - Do **not** include TC IDs, priority, tags, or counts in the bullets.
156
+ - Keep order stable — preserve the order TCs appeared in the ADO linked list.
157
+
158
+ **HTML version (for the ADO field):**
159
+
160
+ Render with the minimum markup needed for ADO's rich-text field to display bullets and line breaks:
161
+
162
+ ```html
163
+ <b>Tested Scenarios</b><br>
164
+ <ul>
165
+ <li>✅ {scenario}</li>
166
+ <li>✅ {scenario}</li>
167
+ <li>❌ {scenario}</li>
168
+ <li>⚠️ {scenario}</li>
169
+ </ul>
170
+ <b>Failures</b><br>
171
+ <ul>
172
+ <li>❌ {scenario}: {reason}</li>
173
+ </ul>
174
+ ```
175
+
176
+ Rules:
177
+ - Escape scenario text for HTML (`&` → `&amp;`, `<` → `&lt;`, `>` → `&gt;`).
178
+ - Emit the `<b>Failures</b>…` block **only if at least one TC failed**.
179
+ - No inline styles, no classes, no wrapping `<div>`.
180
+
181
+ ---
182
+
183
+ ### Phase 6 — Append to the ADO Field
184
+
185
+ 1. Re-read the current `Custom.QATestCasesReport` value for the work item (it may contain prior runs you must preserve).
186
+ 2. Build the new field value:
187
+ - If the existing value is empty or whitespace: new value = the HTML report from Phase 5.
188
+ - Otherwise: new value = existing content + `<br><br>` + the HTML report from Phase 5.
189
+ 3. Call `wit_update_work_item` setting `Custom.QATestCasesReport` to the new value. Pass only this field — do not include any others in the update.
190
+
191
+ Do **not** overwrite other fields. Do **not** create a local file.
192
+
193
+ ---
194
+
195
+ ### Phase 7 — Present to User
196
+
197
+ Print the **markdown** version of the report to the user in chat. After the report, print a one-line confirmation:
198
+
199
+ ```
200
+ Appended to work item #{id} → Custom.QATestCasesReport.
201
+ ```
202
+
203
+ If any scenarios required a manual status answer or a manual failure reason during Phase 3, append a short note listing how many:
204
+
205
+ ```
206
+ {n} status(es) entered manually · {m} failure reason(s) entered manually.
207
+ ```
208
+
209
+ If the TC list had any local-vs-ADO discrepancies (Phase 2), append a short note listing them.
210
+
211
+ ---
212
+
213
+ ## Notes
214
+
215
+ - This skill does **not** create test cases. Use `/qa-create-test --ado <id>` for that.
216
+ - This skill is read-mostly on the ADO side — it only writes to `Custom.QATestCasesReport`. It does not change TC state, does not create Test Runs, and does not modify links.
217
+ - Scenario descriptions are synthesized, not verbatim TC titles — review the chat output before trusting the field content.
218
+
219
+ $ARGUMENTS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qaa-agent",
3
- "version": "1.9.0",
3
+ "version": "1.9.1",
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"