qaa-agent 1.6.2 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.mcp.json +8 -8
- package/CHANGELOG.md +93 -71
- package/CLAUDE.md +553 -553
- package/agents/qa-pipeline-orchestrator.md +1378 -1378
- package/agents/qaa-analyzer.md +539 -524
- package/agents/qaa-bug-detective.md +479 -446
- package/agents/qaa-codebase-mapper.md +935 -935
- package/agents/qaa-discovery.md +384 -0
- package/agents/qaa-e2e-runner.md +416 -415
- package/agents/qaa-executor.md +651 -651
- package/agents/qaa-planner.md +405 -390
- package/agents/qaa-project-researcher.md +319 -319
- package/agents/qaa-scanner.md +424 -424
- package/agents/qaa-testid-injector.md +643 -585
- package/agents/qaa-validator.md +490 -452
- package/bin/install.cjs +200 -198
- package/bin/lib/commands.cjs +709 -709
- package/bin/lib/config.cjs +307 -307
- package/bin/lib/core.cjs +497 -497
- package/bin/lib/frontmatter.cjs +299 -299
- package/bin/lib/init.cjs +989 -989
- package/bin/lib/milestone.cjs +241 -241
- package/bin/lib/model-profiles.cjs +60 -60
- package/bin/lib/phase.cjs +911 -911
- package/bin/lib/roadmap.cjs +306 -306
- package/bin/lib/state.cjs +748 -748
- package/bin/lib/template.cjs +222 -222
- package/bin/lib/verify.cjs +842 -842
- package/bin/qaa-tools.cjs +607 -607
- package/commands/qa-audit.md +119 -0
- package/commands/qa-create-test.md +288 -0
- package/commands/qa-fix.md +147 -0
- package/commands/qa-map.md +137 -0
- package/{.claude/commands → commands}/qa-pr.md +23 -23
- package/{.claude/commands → commands}/qa-start.md +22 -22
- package/{.claude/commands → commands}/qa-testid.md +19 -19
- package/docs/COMMANDS.md +341 -341
- package/docs/DEMO.md +182 -182
- package/docs/TESTING.md +156 -156
- package/package.json +6 -7
- package/{.claude/settings.json → settings.json} +1 -2
- package/templates/failure-classification.md +391 -391
- package/templates/gap-analysis.md +409 -409
- package/templates/pr-template.md +48 -48
- package/templates/qa-analysis.md +381 -381
- package/templates/qa-audit-report.md +465 -465
- package/templates/qa-repo-blueprint.md +636 -636
- package/templates/scan-manifest.md +312 -312
- package/templates/test-inventory.md +582 -582
- package/templates/testid-audit-report.md +354 -354
- package/templates/validation-report.md +243 -243
- package/workflows/qa-analyze.md +296 -296
- package/workflows/qa-from-ticket.md +536 -536
- package/workflows/qa-gap.md +309 -303
- package/workflows/qa-pr.md +389 -389
- package/workflows/qa-start.md +1192 -1168
- package/workflows/qa-testid.md +384 -356
- package/workflows/qa-validate.md +299 -295
- package/.claude/commands/create-test.md +0 -164
- package/.claude/commands/qa-audit.md +0 -37
- package/.claude/commands/qa-blueprint.md +0 -54
- package/.claude/commands/qa-fix.md +0 -36
- package/.claude/commands/qa-from-ticket.md +0 -24
- package/.claude/commands/qa-gap.md +0 -20
- package/.claude/commands/qa-map.md +0 -47
- package/.claude/commands/qa-pom.md +0 -36
- package/.claude/commands/qa-pyramid.md +0 -37
- package/.claude/commands/qa-report.md +0 -38
- package/.claude/commands/qa-research.md +0 -33
- package/.claude/commands/qa-validate.md +0 -42
- package/.claude/commands/update-test.md +0 -58
- package/.claude/skills/qa-learner/SKILL.md +0 -150
- /package/{.claude/skills → skills}/qa-bug-detective/SKILL.md +0 -0
- /package/{.claude/skills → skills}/qa-repo-analyzer/SKILL.md +0 -0
- /package/{.claude/skills → skills}/qa-self-validator/SKILL.md +0 -0
- /package/{.claude/skills → skills}/qa-template-engine/SKILL.md +0 -0
- /package/{.claude/skills → skills}/qa-testid-injector/SKILL.md +0 -0
- /package/{.claude/skills → skills}/qa-workflow-documenter/SKILL.md +0 -0
package/workflows/qa-testid.md
CHANGED
|
@@ -1,356 +1,384 @@
|
|
|
1
|
-
<purpose>
|
|
2
|
-
Scan a frontend codebase, audit every interactive UI element for data-testid coverage, and inject missing data-testid attributes following the `{context}-{description}-{element-type}` naming convention from CLAUDE.md. Operates on a separate branch (`qa/testid-{project}-{date}`) to keep the working copy clean. Produces TESTID_AUDIT_REPORT.md with coverage scores, proposed values, and a decision gate. The user reviews and approves proposed changes before injection. Use this workflow to prepare a frontend codebase for reliable Tier 1 test selectors.
|
|
3
|
-
</purpose>
|
|
4
|
-
|
|
5
|
-
<required_reading>
|
|
6
|
-
- `CLAUDE.md` -- data-testid Convention (naming pattern, context derivation, element-type suffix table, third-party handling), Locator Strategy (Tier 1 includes data-testid)
|
|
7
|
-
- `data-testid-SKILL.md` -- Complete naming convention reference, framework-specific injection syntax, edge case handling
|
|
8
|
-
- `agents/qaa-scanner.md` -- Scanner agent definition (detects frontend framework, enumerates component files)
|
|
9
|
-
- `agents/qaa-testid-injector.md` -- TestID injector agent definition (4-phase: SCAN, AUDIT, INJECT, VALIDATE)
|
|
10
|
-
- `templates/scan-manifest.md` -- SCAN_MANIFEST.md format contract
|
|
11
|
-
- `templates/testid-audit-report.md` -- TESTID_AUDIT_REPORT.md format contract
|
|
12
|
-
</required_reading>
|
|
13
|
-
|
|
14
|
-
<process>
|
|
15
|
-
|
|
16
|
-
<step name="parse_arguments">
|
|
17
|
-
## Step 1: Parse Arguments
|
|
18
|
-
|
|
19
|
-
Parse `$ARGUMENTS` for the source directory path.
|
|
20
|
-
|
|
21
|
-
**Supported arguments:**
|
|
22
|
-
- `<path>` -- Path to the frontend source directory (positional)
|
|
23
|
-
- No arguments -- auto-detect frontend directories
|
|
24
|
-
|
|
25
|
-
**Parsing logic:**
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
SOURCE_DIR=""
|
|
29
|
-
|
|
30
|
-
# Parse positional path argument from $ARGUMENTS
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
**Validation:**
|
|
34
|
-
- If a path is provided, verify it exists and is a directory. If not, print error: `"Error: Source directory does not exist: {path}"` and STOP.
|
|
35
|
-
- If no path provided, proceed to auto-detection in the next step.
|
|
36
|
-
</step>
|
|
37
|
-
|
|
38
|
-
<step name="detect_frontend">
|
|
39
|
-
## Step 2: Detect Frontend Directory and Framework
|
|
40
|
-
|
|
41
|
-
If no source directory was specified, auto-detect by searching for common frontend directory patterns.
|
|
42
|
-
|
|
43
|
-
**Directory detection order:**
|
|
44
|
-
|
|
45
|
-
1. `src/` -- Most common source directory
|
|
46
|
-
2. `app/` -- Next.js app directory, or generic app directory
|
|
47
|
-
3. `components/` -- Component-focused projects
|
|
48
|
-
4. `pages/` -- File-based routing frameworks (Next.js, Nuxt)
|
|
49
|
-
5. `lib/` -- Library projects
|
|
50
|
-
6. `client/` -- Monorepo client directory
|
|
51
|
-
|
|
52
|
-
**Detection logic:**
|
|
53
|
-
|
|
54
|
-
```bash
|
|
55
|
-
if SOURCE_DIR is empty:
|
|
56
|
-
for dir in src app components pages lib client:
|
|
57
|
-
if directory exists at "${dir}":
|
|
58
|
-
SOURCE_DIR="${dir}"
|
|
59
|
-
break
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
**If no frontend directory found:**
|
|
63
|
-
|
|
64
|
-
Print error and STOP:
|
|
65
|
-
```
|
|
66
|
-
Error: No frontend source directory found.
|
|
67
|
-
Searched for: src/, app/, components/, pages/, lib/, client/
|
|
68
|
-
Provide the source directory path as an argument: /qa-testid <path>
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
**Detect frontend framework:**
|
|
72
|
-
|
|
73
|
-
Check for framework indicators in the project root:
|
|
74
|
-
|
|
75
|
-
| Framework | Detection Method |
|
|
76
|
-
|-----------|-----------------|
|
|
77
|
-
| React | `react` or `react-dom` in package.json dependencies; `*.jsx` or `*.tsx` files present |
|
|
78
|
-
| Vue | `vue` in package.json dependencies; `*.vue` files present |
|
|
79
|
-
| Angular | `@angular/core` in package.json dependencies; `*.component.ts` and `*.component.html` files present |
|
|
80
|
-
| Svelte | `svelte` in package.json dependencies; `*.svelte` files present |
|
|
81
|
-
| Plain HTML | None of the above; `*.html` files present (excluding build output) |
|
|
82
|
-
|
|
83
|
-
```bash
|
|
84
|
-
FRONTEND_FRAMEWORK=""
|
|
85
|
-
|
|
86
|
-
# Check package.json for framework dependencies
|
|
87
|
-
# Check for framework-specific file extensions in SOURCE_DIR
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
**If no frontend framework detected:**
|
|
91
|
-
|
|
92
|
-
Print error and STOP:
|
|
93
|
-
```
|
|
94
|
-
Error: No frontend framework detected.
|
|
95
|
-
Checked package.json dependencies and file extensions in {SOURCE_DIR}.
|
|
96
|
-
No React (.jsx/.tsx), Vue (.vue), Angular (.component.ts), Svelte (.svelte), or HTML files found.
|
|
97
|
-
|
|
98
|
-
This workflow requires a frontend codebase with UI components to inject data-testid attributes.
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
**Count component files:**
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
# Count files matching the detected framework's extensions
|
|
105
|
-
COMPONENT_COUNT=$(find "${SOURCE_DIR}" -type f \( -name "*.tsx" -o -name "*.jsx" -o -name "*.vue" -o -name "*.svelte" -o -name "*.component.html" \) \
|
|
106
|
-
! -path "*/node_modules/*" ! -path "*/dist/*" ! -path "*/build/*" \
|
|
107
|
-
! -name "*.test.*" ! -name "*.spec.*" ! -name "*.stories.*" | wc -l)
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
If `COMPONENT_COUNT` is 0, print error and STOP:
|
|
111
|
-
```
|
|
112
|
-
Error: No component files found in {SOURCE_DIR}.
|
|
113
|
-
Framework detected: {FRONTEND_FRAMEWORK}
|
|
114
|
-
Expected file patterns: {patterns for that framework}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
**Print detection results:**
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
Frontend Detection:
|
|
121
|
-
Source Directory: {SOURCE_DIR}
|
|
122
|
-
Framework: {FRONTEND_FRAMEWORK}
|
|
123
|
-
Component Files: {COMPONENT_COUNT}
|
|
124
|
-
```
|
|
125
|
-
</step>
|
|
126
|
-
|
|
127
|
-
<step name="run_scanner">
|
|
128
|
-
## Step 3: Spawn Scanner Agent
|
|
129
|
-
|
|
130
|
-
Spawn the scanner agent to produce SCAN_MANIFEST.md with the frontend component file list.
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
Task(
|
|
134
|
-
prompt="
|
|
135
|
-
<objective>Scan frontend repository and produce SCAN_MANIFEST.md with component file enumeration</objective>
|
|
136
|
-
<execution_context>@agents/qaa-scanner.md</execution_context>
|
|
137
|
-
<files_to_read>
|
|
138
|
-
- CLAUDE.md
|
|
139
|
-
</files_to_read>
|
|
140
|
-
<parameters>
|
|
141
|
-
dev_repo_path: {project root}
|
|
142
|
-
qa_repo_path: null
|
|
143
|
-
output_path: {OUTPUT_DIR}/SCAN_MANIFEST.md
|
|
144
|
-
</parameters>
|
|
145
|
-
"
|
|
146
|
-
)
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
**Set output directory:**
|
|
150
|
-
|
|
151
|
-
```bash
|
|
152
|
-
OUTPUT_DIR=".qa-output"
|
|
153
|
-
mkdir -p "${OUTPUT_DIR}"
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
**Handle scanner return:**
|
|
157
|
-
|
|
158
|
-
- Extract `has_frontend` -- MUST be `true`. If `false`, print error and STOP:
|
|
159
|
-
```
|
|
160
|
-
Error: Scanner reports has_frontend: false.
|
|
161
|
-
The detected framework ({FRONTEND_FRAMEWORK}) and component files ({COMPONENT_COUNT}) suggest frontend is present,
|
|
162
|
-
but the scanner could not classify them as frontend components.
|
|
163
|
-
Check SCAN_MANIFEST.md for details: {OUTPUT_DIR}/SCAN_MANIFEST.md
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
**Verify SCAN_MANIFEST.md exists:**
|
|
167
|
-
|
|
168
|
-
```bash
|
|
169
|
-
[ -f "${OUTPUT_DIR}/SCAN_MANIFEST.md" ] && echo "FOUND" || echo "MISSING"
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
If missing, print error and STOP.
|
|
173
|
-
</step>
|
|
174
|
-
|
|
175
|
-
<step name="run_testid_injector">
|
|
176
|
-
## Step 4: Spawn TestID Injector Agent
|
|
177
|
-
|
|
178
|
-
Spawn the testid-injector agent which operates in 4 phases: SCAN, AUDIT, INJECT, VALIDATE.
|
|
179
|
-
|
|
180
|
-
```
|
|
181
|
-
Task(
|
|
182
|
-
prompt="
|
|
183
|
-
<objective>Audit frontend components for data-testid coverage and inject missing attributes
|
|
184
|
-
<execution_context>@agents/qaa-testid-injector.md</execution_context>
|
|
185
|
-
<files_to_read>
|
|
186
|
-
- {OUTPUT_DIR}/SCAN_MANIFEST.md
|
|
187
|
-
- CLAUDE.md
|
|
188
|
-
- data-testid-SKILL.md
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
|
351
|
-
|
|
352
|
-
| SCAN_MANIFEST.md
|
|
353
|
-
|
|
|
354
|
-
|
|
|
355
|
-
|
|
|
356
|
-
|
|
1
|
+
<purpose>
|
|
2
|
+
Scan a frontend codebase, audit every interactive UI element for data-testid coverage, and inject missing data-testid attributes following the `{context}-{description}-{element-type}` naming convention from CLAUDE.md. Operates on a separate branch (`qa/testid-{project}-{date}`) to keep the working copy clean. Produces TESTID_AUDIT_REPORT.md with coverage scores, proposed values, and a decision gate. The user reviews and approves proposed changes before injection. Use this workflow to prepare a frontend codebase for reliable Tier 1 test selectors.
|
|
3
|
+
</purpose>
|
|
4
|
+
|
|
5
|
+
<required_reading>
|
|
6
|
+
- `CLAUDE.md` -- data-testid Convention (naming pattern, context derivation, element-type suffix table, third-party handling), Locator Strategy (Tier 1 includes data-testid)
|
|
7
|
+
- `data-testid-SKILL.md` -- Complete naming convention reference, framework-specific injection syntax, edge case handling
|
|
8
|
+
- `agents/qaa-scanner.md` -- Scanner agent definition (detects frontend framework, enumerates component files)
|
|
9
|
+
- `agents/qaa-testid-injector.md` -- TestID injector agent definition (4-phase: SCAN, AUDIT, INJECT, VALIDATE)
|
|
10
|
+
- `templates/scan-manifest.md` -- SCAN_MANIFEST.md format contract
|
|
11
|
+
- `templates/testid-audit-report.md` -- TESTID_AUDIT_REPORT.md format contract
|
|
12
|
+
</required_reading>
|
|
13
|
+
|
|
14
|
+
<process>
|
|
15
|
+
|
|
16
|
+
<step name="parse_arguments">
|
|
17
|
+
## Step 1: Parse Arguments
|
|
18
|
+
|
|
19
|
+
Parse `$ARGUMENTS` for the source directory path.
|
|
20
|
+
|
|
21
|
+
**Supported arguments:**
|
|
22
|
+
- `<path>` -- Path to the frontend source directory (positional)
|
|
23
|
+
- No arguments -- auto-detect frontend directories
|
|
24
|
+
|
|
25
|
+
**Parsing logic:**
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
SOURCE_DIR=""
|
|
29
|
+
|
|
30
|
+
# Parse positional path argument from $ARGUMENTS
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Validation:**
|
|
34
|
+
- If a path is provided, verify it exists and is a directory. If not, print error: `"Error: Source directory does not exist: {path}"` and STOP.
|
|
35
|
+
- If no path provided, proceed to auto-detection in the next step.
|
|
36
|
+
</step>
|
|
37
|
+
|
|
38
|
+
<step name="detect_frontend">
|
|
39
|
+
## Step 2: Detect Frontend Directory and Framework
|
|
40
|
+
|
|
41
|
+
If no source directory was specified, auto-detect by searching for common frontend directory patterns.
|
|
42
|
+
|
|
43
|
+
**Directory detection order:**
|
|
44
|
+
|
|
45
|
+
1. `src/` -- Most common source directory
|
|
46
|
+
2. `app/` -- Next.js app directory, or generic app directory
|
|
47
|
+
3. `components/` -- Component-focused projects
|
|
48
|
+
4. `pages/` -- File-based routing frameworks (Next.js, Nuxt)
|
|
49
|
+
5. `lib/` -- Library projects
|
|
50
|
+
6. `client/` -- Monorepo client directory
|
|
51
|
+
|
|
52
|
+
**Detection logic:**
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
if SOURCE_DIR is empty:
|
|
56
|
+
for dir in src app components pages lib client:
|
|
57
|
+
if directory exists at "${dir}":
|
|
58
|
+
SOURCE_DIR="${dir}"
|
|
59
|
+
break
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**If no frontend directory found:**
|
|
63
|
+
|
|
64
|
+
Print error and STOP:
|
|
65
|
+
```
|
|
66
|
+
Error: No frontend source directory found.
|
|
67
|
+
Searched for: src/, app/, components/, pages/, lib/, client/
|
|
68
|
+
Provide the source directory path as an argument: /qa-testid <path>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
**Detect frontend framework:**
|
|
72
|
+
|
|
73
|
+
Check for framework indicators in the project root:
|
|
74
|
+
|
|
75
|
+
| Framework | Detection Method |
|
|
76
|
+
|-----------|-----------------|
|
|
77
|
+
| React | `react` or `react-dom` in package.json dependencies; `*.jsx` or `*.tsx` files present |
|
|
78
|
+
| Vue | `vue` in package.json dependencies; `*.vue` files present |
|
|
79
|
+
| Angular | `@angular/core` in package.json dependencies; `*.component.ts` and `*.component.html` files present |
|
|
80
|
+
| Svelte | `svelte` in package.json dependencies; `*.svelte` files present |
|
|
81
|
+
| Plain HTML | None of the above; `*.html` files present (excluding build output) |
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
FRONTEND_FRAMEWORK=""
|
|
85
|
+
|
|
86
|
+
# Check package.json for framework dependencies
|
|
87
|
+
# Check for framework-specific file extensions in SOURCE_DIR
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**If no frontend framework detected:**
|
|
91
|
+
|
|
92
|
+
Print error and STOP:
|
|
93
|
+
```
|
|
94
|
+
Error: No frontend framework detected.
|
|
95
|
+
Checked package.json dependencies and file extensions in {SOURCE_DIR}.
|
|
96
|
+
No React (.jsx/.tsx), Vue (.vue), Angular (.component.ts), Svelte (.svelte), or HTML files found.
|
|
97
|
+
|
|
98
|
+
This workflow requires a frontend codebase with UI components to inject data-testid attributes.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**Count component files:**
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# Count files matching the detected framework's extensions
|
|
105
|
+
COMPONENT_COUNT=$(find "${SOURCE_DIR}" -type f \( -name "*.tsx" -o -name "*.jsx" -o -name "*.vue" -o -name "*.svelte" -o -name "*.component.html" \) \
|
|
106
|
+
! -path "*/node_modules/*" ! -path "*/dist/*" ! -path "*/build/*" \
|
|
107
|
+
! -name "*.test.*" ! -name "*.spec.*" ! -name "*.stories.*" | wc -l)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
If `COMPONENT_COUNT` is 0, print error and STOP:
|
|
111
|
+
```
|
|
112
|
+
Error: No component files found in {SOURCE_DIR}.
|
|
113
|
+
Framework detected: {FRONTEND_FRAMEWORK}
|
|
114
|
+
Expected file patterns: {patterns for that framework}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Print detection results:**
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
Frontend Detection:
|
|
121
|
+
Source Directory: {SOURCE_DIR}
|
|
122
|
+
Framework: {FRONTEND_FRAMEWORK}
|
|
123
|
+
Component Files: {COMPONENT_COUNT}
|
|
124
|
+
```
|
|
125
|
+
</step>
|
|
126
|
+
|
|
127
|
+
<step name="run_scanner">
|
|
128
|
+
## Step 3: Spawn Scanner Agent
|
|
129
|
+
|
|
130
|
+
Spawn the scanner agent to produce SCAN_MANIFEST.md with the frontend component file list.
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
Task(
|
|
134
|
+
prompt="
|
|
135
|
+
<objective>Scan frontend repository and produce SCAN_MANIFEST.md with component file enumeration</objective>
|
|
136
|
+
<execution_context>@agents/qaa-scanner.md</execution_context>
|
|
137
|
+
<files_to_read>
|
|
138
|
+
- CLAUDE.md
|
|
139
|
+
</files_to_read>
|
|
140
|
+
<parameters>
|
|
141
|
+
dev_repo_path: {project root}
|
|
142
|
+
qa_repo_path: null
|
|
143
|
+
output_path: {OUTPUT_DIR}/SCAN_MANIFEST.md
|
|
144
|
+
</parameters>
|
|
145
|
+
"
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Set output directory:**
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
OUTPUT_DIR=".qa-output"
|
|
153
|
+
mkdir -p "${OUTPUT_DIR}"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**Handle scanner return:**
|
|
157
|
+
|
|
158
|
+
- Extract `has_frontend` -- MUST be `true`. If `false`, print error and STOP:
|
|
159
|
+
```
|
|
160
|
+
Error: Scanner reports has_frontend: false.
|
|
161
|
+
The detected framework ({FRONTEND_FRAMEWORK}) and component files ({COMPONENT_COUNT}) suggest frontend is present,
|
|
162
|
+
but the scanner could not classify them as frontend components.
|
|
163
|
+
Check SCAN_MANIFEST.md for details: {OUTPUT_DIR}/SCAN_MANIFEST.md
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Verify SCAN_MANIFEST.md exists:**
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
[ -f "${OUTPUT_DIR}/SCAN_MANIFEST.md" ] && echo "FOUND" || echo "MISSING"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
If missing, print error and STOP.
|
|
173
|
+
</step>
|
|
174
|
+
|
|
175
|
+
<step name="run_testid_injector">
|
|
176
|
+
## Step 4: Spawn TestID Injector Agent
|
|
177
|
+
|
|
178
|
+
Spawn the testid-injector agent which operates in 4 phases: SCAN, AUDIT, INJECT, VALIDATE.
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
Task(
|
|
182
|
+
prompt="
|
|
183
|
+
<objective>Audit frontend components for data-testid coverage and inject missing attributes. Use Playwright MCP to verify against live DOM. Use codebase map for component structure context. Update locator registry with discovered and injected locators.</objective>
|
|
184
|
+
<execution_context>@agents/qaa-testid-injector.md</execution_context>
|
|
185
|
+
<files_to_read>
|
|
186
|
+
- {OUTPUT_DIR}/SCAN_MANIFEST.md
|
|
187
|
+
- CLAUDE.md
|
|
188
|
+
- data-testid-SKILL.md
|
|
189
|
+
- .qa-output/locators/LOCATOR_REGISTRY.md (if exists -- existing locators to cross-reference)
|
|
190
|
+
- .qa-output/codebase/CODE_PATTERNS.md (if exists -- component naming conventions for context derivation)
|
|
191
|
+
- .qa-output/codebase/TEST_SURFACE.md (if exists -- UI component list with props/events)
|
|
192
|
+
- .qa-output/codebase/TESTABILITY.md (if exists -- component testability for injection priority)
|
|
193
|
+
</files_to_read>
|
|
194
|
+
<parameters>
|
|
195
|
+
source_dir: {SOURCE_DIR}
|
|
196
|
+
frontend_framework: {FRONTEND_FRAMEWORK}
|
|
197
|
+
output_path: {OUTPUT_DIR}/TESTID_AUDIT_REPORT.md
|
|
198
|
+
app_url: {auto-detect from dev server or ask user}
|
|
199
|
+
</parameters>
|
|
200
|
+
"
|
|
201
|
+
)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
**Injector agent phases:**
|
|
205
|
+
|
|
206
|
+
1. **SCAN phase:** The injector detects the framework, lists component files, classifies them by interaction density (HIGH/MEDIUM/LOW), and sorts by priority.
|
|
207
|
+
|
|
208
|
+
2. **AUDIT phase:** For each component file, the injector identifies every interactive element (buttons, inputs, selects, forms, links, modals, etc.), checks for existing data-testid attributes, proposes values for missing attributes following `{context}-{description}-{element-type}` convention, classifies elements by priority (P0/P1/P2), and calculates the coverage score.
|
|
209
|
+
|
|
210
|
+
3. **CHECKPOINT:** The injector presents the TESTID_AUDIT_REPORT.md to the user for review before injecting. The user can:
|
|
211
|
+
- Approve all proposed values
|
|
212
|
+
- Reject specific elements
|
|
213
|
+
- Rename proposed values
|
|
214
|
+
- Approve renaming of non-compliant existing values
|
|
215
|
+
- Change priority classifications
|
|
216
|
+
|
|
217
|
+
4. **INJECT phase (after approval):** Creates a separate branch `qa/testid-inject-{YYYY-MM-DD}`, injects approved data-testid attributes using framework-specific syntax (JSX attributes for React, HTML attributes for Vue templates, `[attr.data-testid]` binding for Angular), preserves all existing formatting, and preserves existing data-testid values.
|
|
218
|
+
|
|
219
|
+
5. **VALIDATE phase:** Runs syntax checks on all modified files, verifies uniqueness of data-testid values per page/route scope, checks naming convention compliance, and verifies no unintended source code changes (non-interference check). If syntax fails, reverts the specific file.
|
|
220
|
+
|
|
221
|
+
6. **BROWSER VERIFY phase (if app URL available and Playwright MCP connected):**
|
|
222
|
+
|
|
223
|
+
After injection and static validation, use Playwright MCP to verify the injected `data-testid` attributes are present in the rendered DOM:
|
|
224
|
+
|
|
225
|
+
1. Navigate to each page/route that has injected components:
|
|
226
|
+
```
|
|
227
|
+
mcp__playwright__browser_navigate({ url: "{app_url}/{route}" })
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
2. Take an accessibility snapshot to inspect the rendered DOM:
|
|
231
|
+
```
|
|
232
|
+
mcp__playwright__browser_snapshot()
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
3. Cross-reference: for each injected `data-testid`, verify it appears in the snapshot. Report:
|
|
236
|
+
- **CONFIRMED**: `data-testid` found in rendered DOM
|
|
237
|
+
- **NOT RENDERED**: Component exists in source but not rendered on this route (may appear conditionally)
|
|
238
|
+
- **MISSING**: `data-testid` expected but not found in DOM (possible injection error)
|
|
239
|
+
|
|
240
|
+
4. Add browser verification results to the TESTID_AUDIT_REPORT.md as a "Browser Verification" section.
|
|
241
|
+
|
|
242
|
+
This step is **optional** -- if no app URL is available or the app is not running, skip and rely on static validation only.
|
|
243
|
+
|
|
244
|
+
**Handle injector return:**
|
|
245
|
+
|
|
246
|
+
Extract:
|
|
247
|
+
- `report_path` -- Path to TESTID_AUDIT_REPORT.md
|
|
248
|
+
- `changelog_path` -- Path to INJECTION_CHANGELOG.md
|
|
249
|
+
- `branch` -- Name of the injection branch
|
|
250
|
+
- `coverage_before` -- Coverage before injection
|
|
251
|
+
- `coverage_after` -- Coverage after injection
|
|
252
|
+
- `elements_injected` -- Count of injected attributes
|
|
253
|
+
- `elements_deferred` -- Count of deferred elements
|
|
254
|
+
- `files_modified` -- Count of modified files
|
|
255
|
+
- `validation_passed` -- Whether all validation checks passed
|
|
256
|
+
</step>
|
|
257
|
+
|
|
258
|
+
<step name="create_branch_and_commit">
|
|
259
|
+
## Step 5: Create Branch and Commit
|
|
260
|
+
|
|
261
|
+
The testid-injector agent handles branch creation and commits internally on the `qa/testid-inject-{YYYY-MM-DD}` branch. Verify the branch was created and commits exist.
|
|
262
|
+
|
|
263
|
+
**Verify branch:**
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
git branch --list "qa/testid-inject-*"
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
If the branch does not exist, the injector may not have reached the injection phase (stopped at audit checkpoint). This is expected behavior -- the audit report is still produced.
|
|
270
|
+
|
|
271
|
+
**Verify commit (if injection was performed):**
|
|
272
|
+
|
|
273
|
+
```bash
|
|
274
|
+
git log --oneline -3 "qa/testid-inject-*" 2>/dev/null
|
|
275
|
+
```
|
|
276
|
+
</step>
|
|
277
|
+
|
|
278
|
+
<step name="print_summary">
|
|
279
|
+
## Step 6: Print Summary
|
|
280
|
+
|
|
281
|
+
Print a comprehensive summary of the testid injection results.
|
|
282
|
+
|
|
283
|
+
```
|
|
284
|
+
=== TestID Injection Complete ===
|
|
285
|
+
|
|
286
|
+
Frontend:
|
|
287
|
+
Framework: {FRONTEND_FRAMEWORK}
|
|
288
|
+
Source Directory: {SOURCE_DIR}
|
|
289
|
+
Component Files: {COMPONENT_COUNT}
|
|
290
|
+
|
|
291
|
+
Coverage:
|
|
292
|
+
Before: {coverage_before}%
|
|
293
|
+
After: {coverage_after}%
|
|
294
|
+
Change: +{coverage_after - coverage_before}%
|
|
295
|
+
|
|
296
|
+
Elements:
|
|
297
|
+
Total Interactive: {total_elements}
|
|
298
|
+
Already Had TestID: {existing_count}
|
|
299
|
+
Injected: {elements_injected}
|
|
300
|
+
Deferred (P1/P2): {elements_deferred}
|
|
301
|
+
|
|
302
|
+
By Priority:
|
|
303
|
+
P0 (inputs, buttons, forms): {p0_count} ({p0_injected} injected)
|
|
304
|
+
P1 (links, alerts, toggles): {p1_count} ({p1_injected} injected)
|
|
305
|
+
P2 (images, badges, tables): {p2_count} ({p2_injected} injected)
|
|
306
|
+
|
|
307
|
+
Validation:
|
|
308
|
+
Syntax Check: {PASS|FAIL}
|
|
309
|
+
Uniqueness Check: {PASS|FAIL}
|
|
310
|
+
Convention Check: {PASS|FAIL}
|
|
311
|
+
Non-Interference: {PASS|FAIL}
|
|
312
|
+
|
|
313
|
+
Branch: {branch_name}
|
|
314
|
+
Files Modified: {files_modified}
|
|
315
|
+
|
|
316
|
+
Artifacts:
|
|
317
|
+
- {OUTPUT_DIR}/SCAN_MANIFEST.md
|
|
318
|
+
- {OUTPUT_DIR}/TESTID_AUDIT_REPORT.md
|
|
319
|
+
- {OUTPUT_DIR}/INJECTION_CHANGELOG.md (after injection)
|
|
320
|
+
|
|
321
|
+
Next Steps:
|
|
322
|
+
1. Review changes on branch: git diff main..{branch_name}
|
|
323
|
+
2. If approved, merge: git merge {branch_name}
|
|
324
|
+
3. Run tests to verify no regressions
|
|
325
|
+
=================================
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**If injection was not performed (stopped at audit checkpoint):**
|
|
329
|
+
|
|
330
|
+
```
|
|
331
|
+
=== TestID Audit Complete (Injection Pending) ===
|
|
332
|
+
|
|
333
|
+
The audit report has been produced. Review the proposed data-testid values
|
|
334
|
+
in {OUTPUT_DIR}/TESTID_AUDIT_REPORT.md and re-run with approvals to inject.
|
|
335
|
+
|
|
336
|
+
Coverage Score: {coverage_before}%
|
|
337
|
+
Decision: {SELECTIVE|TARGETED|FULL PASS|P0 FIRST}
|
|
338
|
+
Missing TestIDs: {missing_count} ({p0_missing} P0, {p1_missing} P1, {p2_missing} P2)
|
|
339
|
+
=============================================
|
|
340
|
+
```
|
|
341
|
+
</step>
|
|
342
|
+
|
|
343
|
+
</process>
|
|
344
|
+
|
|
345
|
+
<output>
|
|
346
|
+
This workflow audits and injects data-testid attributes into frontend components.
|
|
347
|
+
|
|
348
|
+
**Artifacts produced:**
|
|
349
|
+
|
|
350
|
+
| Artifact | When Produced | Description |
|
|
351
|
+
|----------|---------------|-------------|
|
|
352
|
+
| SCAN_MANIFEST.md | Always | Repository scan with component file list and framework detection |
|
|
353
|
+
| TESTID_AUDIT_REPORT.md | Always | Comprehensive audit: coverage score, per-element tables, naming compliance, decision gate |
|
|
354
|
+
| INJECTION_CHANGELOG.md | After injection approval | Per-file log of every injection action with validation results |
|
|
355
|
+
| Modified source files | After injection approval | Component files with data-testid attributes added, on separate branch |
|
|
356
|
+
|
|
357
|
+
**Branch management:**
|
|
358
|
+
- Injection branch: `qa/testid-inject-{YYYY-MM-DD}`
|
|
359
|
+
- Working copy on the original branch is NOT modified
|
|
360
|
+
- User merges the injection branch if approved
|
|
361
|
+
|
|
362
|
+
**Decision gate thresholds (from CLAUDE.md):**
|
|
363
|
+
|
|
364
|
+
| Current Coverage | Decision | Strategy |
|
|
365
|
+
|-----------------|----------|----------|
|
|
366
|
+
| > 90% | SELECTIVE | Inject only P0 missing elements |
|
|
367
|
+
| 50% - 90% | TARGETED | Inject P0 and P1 missing elements |
|
|
368
|
+
| 1% - 49% | FULL PASS | Inject all P0, P1, P2 elements |
|
|
369
|
+
| 0% | P0 FIRST | Inject P0 elements only, then re-audit |
|
|
370
|
+
</output>
|
|
371
|
+
|
|
372
|
+
<error_handling>
|
|
373
|
+
| Error | Cause | Action |
|
|
374
|
+
|-------|-------|--------|
|
|
375
|
+
| Source directory does not exist | Invalid path argument | Print error with path, STOP |
|
|
376
|
+
| No frontend directory found | No common frontend dirs in project | Print error listing searched dirs, suggest providing path, STOP |
|
|
377
|
+
| No frontend framework detected | Missing framework deps and file extensions | Print error with detection details, STOP |
|
|
378
|
+
| No component files found | Directory exists but no components | Print error with expected patterns for the detected framework, STOP |
|
|
379
|
+
| Scanner reports has_frontend: false | Scanner classification issue | Print error with suggestion to check SCAN_MANIFEST.md, STOP |
|
|
380
|
+
| SCAN_MANIFEST.md missing | Scanner failed | Print error, STOP |
|
|
381
|
+
| Syntax check fails after injection | Injection broke file syntax | Injector reverts the specific file automatically, reports in changelog |
|
|
382
|
+
| Duplicate data-testid detected | Same value on same rendered page | Injector renames the newer injection to disambiguate |
|
|
383
|
+
| Non-compliant existing values | Existing data-testid does not follow convention | Reported in audit but NOT auto-renamed (user decides) |
|
|
384
|
+
</error_handling>
|