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
|
@@ -1,354 +1,354 @@
|
|
|
1
|
-
---
|
|
2
|
-
template_name: testid-audit-report
|
|
3
|
-
version: "1.0"
|
|
4
|
-
artifact_type: audit
|
|
5
|
-
produces: TESTID_AUDIT_REPORT.md
|
|
6
|
-
producer_agent: qa-testid-injector
|
|
7
|
-
consumer_agents:
|
|
8
|
-
- qa-executor
|
|
9
|
-
- human-reviewer
|
|
10
|
-
required_sections:
|
|
11
|
-
- summary
|
|
12
|
-
- coverage-score
|
|
13
|
-
- file-details
|
|
14
|
-
- naming-convention-compliance
|
|
15
|
-
- decision-gate
|
|
16
|
-
example_domain: shopflow
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
# TESTID_AUDIT_REPORT.md Template
|
|
20
|
-
|
|
21
|
-
**Purpose:** Audit of `data-testid` coverage across frontend component files, identifying interactive elements that lack stable test selectors and proposing injection values following a consistent naming convention.
|
|
22
|
-
|
|
23
|
-
**Producer:** `qa-testid-injector` (Phase 2: AUDIT step)
|
|
24
|
-
**Consumers:** `qa-executor` (uses proposed test IDs when writing E2E tests), `human-reviewer` (reviews proposed values before injection)
|
|
25
|
-
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
## Required Sections
|
|
29
|
-
|
|
30
|
-
### Section 1: Summary
|
|
31
|
-
|
|
32
|
-
**Description:** High-level counts of scanned files, interactive elements found, and breakdown of missing `data-testid` attributes by priority.
|
|
33
|
-
|
|
34
|
-
**Fields:**
|
|
35
|
-
|
|
36
|
-
| Field | Type | Required | Description |
|
|
37
|
-
|-------|------|----------|-------------|
|
|
38
|
-
| files_scanned | integer | YES | Total number of component files scanned |
|
|
39
|
-
| total_interactive_elements | integer | YES | Total interactive elements found across all files |
|
|
40
|
-
| elements_with_testid | integer | YES | Elements that already have a `data-testid` attribute |
|
|
41
|
-
| elements_missing_testid | integer | YES | Elements that need a `data-testid` injected |
|
|
42
|
-
| p0_missing | integer | YES | P0 (must have): form inputs, submit buttons, primary actions |
|
|
43
|
-
| p1_missing | integer | YES | P1 (should have): navigation links, secondary actions, feedback elements |
|
|
44
|
-
| p2_missing | integer | YES | P2 (nice to have): decorative images, static containers showing dynamic data |
|
|
45
|
-
|
|
46
|
-
**Priority Definitions:**
|
|
47
|
-
|
|
48
|
-
| Priority | Label | Elements |
|
|
49
|
-
|----------|-------|----------|
|
|
50
|
-
| P0 | Must Have | Form `<input>`, `<select>`, `<textarea>`, submit `<button>`, primary action buttons, `<form>` tags |
|
|
51
|
-
| P1 | Should Have | Navigation `<a>` links, secondary buttons, error/alert messages, toggle/checkbox/radio |
|
|
52
|
-
| P2 | Nice to Have | Images showing product data, badges, decorative containers with dynamic content |
|
|
53
|
-
|
|
54
|
-
---
|
|
55
|
-
|
|
56
|
-
### Section 2: Coverage Score
|
|
57
|
-
|
|
58
|
-
**Description:** Quantified coverage percentage with interpretation and projected post-injection score.
|
|
59
|
-
|
|
60
|
-
**Fields:**
|
|
61
|
-
|
|
62
|
-
| Field | Type | Required | Description |
|
|
63
|
-
|-------|------|----------|-------------|
|
|
64
|
-
| current_coverage | percentage | YES | `elements_with_testid / total_interactive_elements * 100` |
|
|
65
|
-
| projected_coverage | percentage | YES | Coverage percentage after all proposed injections are applied |
|
|
66
|
-
| score_interpretation | string | YES | One of: EXCELLENT, GOOD, NEEDS WORK, CRITICAL |
|
|
67
|
-
|
|
68
|
-
**Formula:**
|
|
69
|
-
```
|
|
70
|
-
Current Coverage = (elements_with_testid / total_interactive_elements) * 100
|
|
71
|
-
Projected Coverage = ((elements_with_testid + elements_missing_testid) / total_interactive_elements) * 100
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
**Interpretation Thresholds:**
|
|
75
|
-
|
|
76
|
-
| Score Range | Interpretation | Meaning |
|
|
77
|
-
|-------------|---------------|---------|
|
|
78
|
-
| > 90% | EXCELLENT | Most elements already have test IDs; selective injection only |
|
|
79
|
-
| 50% - 90% | GOOD | Decent baseline; targeted injection pass needed |
|
|
80
|
-
| 1% - 49% | NEEDS WORK | Significant gaps; full injection pass required |
|
|
81
|
-
| 0% | CRITICAL | No test IDs exist; P0-first strategy recommended |
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
### Section 3: File Details
|
|
86
|
-
|
|
87
|
-
**Description:** Per-component file audit showing every interactive element, its current selector state, and the proposed `data-testid` value.
|
|
88
|
-
|
|
89
|
-
**Per-File Structure:**
|
|
90
|
-
|
|
91
|
-
| Field | Type | Required | Description |
|
|
92
|
-
|-------|------|----------|-------------|
|
|
93
|
-
| file_path | string | YES | Full path to the component file |
|
|
94
|
-
| component_name | string | YES | Name of the React/Vue/Angular component |
|
|
95
|
-
| element_count | integer | YES | Total interactive elements in this file |
|
|
96
|
-
|
|
97
|
-
**Per-Element Table Columns:**
|
|
98
|
-
|
|
99
|
-
| Column | Description |
|
|
100
|
-
|--------|-------------|
|
|
101
|
-
| Line | Line number in the source file where the element appears |
|
|
102
|
-
| Element | HTML tag and type (e.g., `<input type="email">`, `<button type="submit">`) |
|
|
103
|
-
| Current Selector | What exists now: `data-testid="value"`, `className="..."`, `name="..."`, or `none` |
|
|
104
|
-
| Proposed data-testid | The proposed value following `{context}-{description}-{element-type}` convention, or `EXISTING -- no change` if already has a `data-testid` |
|
|
105
|
-
| Priority | P0, P1, or P2 |
|
|
106
|
-
|
|
107
|
-
**Rules:**
|
|
108
|
-
- Elements with an EXISTING `data-testid` are marked `EXISTING -- no change` and are never modified
|
|
109
|
-
- Elements missing `data-testid` receive a proposed value following `{context}-{description}-{element-type}` naming convention
|
|
110
|
-
- Context is derived from the component filename (e.g., `LoginPage.tsx` -> `login`, `CheckoutForm.tsx` -> `checkout`)
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
### Section 4: Naming Convention Compliance
|
|
115
|
-
|
|
116
|
-
**Description:** Audit of existing `data-testid` values against the `{context}-{description}-{element-type}` naming pattern.
|
|
117
|
-
|
|
118
|
-
**Fields:**
|
|
119
|
-
|
|
120
|
-
| Field | Type | Required | Description |
|
|
121
|
-
|-------|------|----------|-------------|
|
|
122
|
-
| total_existing | integer | YES | Count of elements with existing `data-testid` |
|
|
123
|
-
| compliant_count | integer | YES | Count that follow the naming convention |
|
|
124
|
-
| non_compliant_count | integer | YES | Count that violate the naming convention |
|
|
125
|
-
|
|
126
|
-
**Per-Value Table Columns:**
|
|
127
|
-
|
|
128
|
-
| Column | Description |
|
|
129
|
-
|--------|-------------|
|
|
130
|
-
| Existing Value | The current `data-testid` value |
|
|
131
|
-
| Compliant | YES or NO |
|
|
132
|
-
| Issue | If non-compliant: what is wrong (e.g., "missing element-type suffix", "camelCase instead of kebab-case") |
|
|
133
|
-
| Suggested Rename | If non-compliant: the corrected value following convention |
|
|
134
|
-
|
|
135
|
-
**Convention Rules:**
|
|
136
|
-
- All values MUST be kebab-case: `login-submit-btn`, never `loginSubmitBtn` or `login_submit_btn`
|
|
137
|
-
- All values MUST end with an element-type suffix: `-btn`, `-input`, `-link`, `-form`, `-img`, etc.
|
|
138
|
-
- All values MUST start with a context prefix derived from the component name
|
|
139
|
-
- No framework-specific prefixes: no `cy-`, `pw-`, `qa-` prefixes
|
|
140
|
-
|
|
141
|
-
---
|
|
142
|
-
|
|
143
|
-
### Section 5: Decision Gate
|
|
144
|
-
|
|
145
|
-
**Description:** Automated recommendation based on coverage score that determines the injection strategy.
|
|
146
|
-
|
|
147
|
-
**Decision Matrix:**
|
|
148
|
-
|
|
149
|
-
| Coverage | Decision | Strategy |
|
|
150
|
-
|----------|----------|----------|
|
|
151
|
-
| > 90% | SELECTIVE | Inject only P0 missing elements |
|
|
152
|
-
| 50% - 90% | TARGETED | Inject P0 and P1 missing elements |
|
|
153
|
-
| 1% - 49% | FULL PASS | Inject all P0, P1, P2 elements |
|
|
154
|
-
| 0% | P0 FIRST | Inject P0 elements only, then re-audit after |
|
|
155
|
-
| 0 files scanned | STOP | No frontend component files detected -- abort injection |
|
|
156
|
-
|
|
157
|
-
**Output Format:**
|
|
158
|
-
```
|
|
159
|
-
DECISION: {decision_type}
|
|
160
|
-
REASON: Current coverage {X}%, {explanation}
|
|
161
|
-
ACTION: {what the injector should do next}
|
|
162
|
-
FILES: {count} files to process
|
|
163
|
-
ELEMENTS: {count} elements to inject
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
---
|
|
167
|
-
|
|
168
|
-
## Worked Example (ShopFlow E-Commerce API)
|
|
169
|
-
|
|
170
|
-
### Summary
|
|
171
|
-
|
|
172
|
-
| Metric | Count |
|
|
173
|
-
|--------|-------|
|
|
174
|
-
| Files Scanned | 6 |
|
|
175
|
-
| Total Interactive Elements | 42 |
|
|
176
|
-
| Elements with Existing data-testid | 8 |
|
|
177
|
-
| Elements Missing data-testid | 34 |
|
|
178
|
-
| P0 Missing (must have) | 18 |
|
|
179
|
-
| P1 Missing (should have) | 12 |
|
|
180
|
-
| P2 Missing (nice to have) | 4 |
|
|
181
|
-
|
|
182
|
-
### Coverage Score
|
|
183
|
-
|
|
184
|
-
```
|
|
185
|
-
Current Coverage = 8 / 42 * 100 = 19.05%
|
|
186
|
-
Projected Coverage = 42 / 42 * 100 = 100%
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Score: 19% -- NEEDS WORK**
|
|
190
|
-
|
|
191
|
-
Current coverage is well below the 50% threshold. A full injection pass is recommended to bring all interactive elements up to testability standards before E2E test generation.
|
|
192
|
-
|
|
193
|
-
### File Details
|
|
194
|
-
|
|
195
|
-
#### LoginPage.tsx -- LoginPage Component
|
|
196
|
-
|
|
197
|
-
**Path:** `src/components/auth/LoginPage.tsx`
|
|
198
|
-
**Interactive elements:** 8 (4 P0, 3 P1, 1 P2)
|
|
199
|
-
|
|
200
|
-
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
201
|
-
|------|---------|-----------------|----------------------|----------|
|
|
202
|
-
| 18 | `<form>` | `className="login-form"` | `login-form` | P0 |
|
|
203
|
-
| 22 | `<input type="email">` | `name="email"` | `login-email-input` | P0 |
|
|
204
|
-
| 28 | `<input type="password">` | `name="password"` | `login-password-input` | P0 |
|
|
205
|
-
| 34 | `<button type="submit">` | `className="btn-primary"` | `login-submit-btn` | P0 |
|
|
206
|
-
| 40 | `<a href="/forgot-password">` | none | `login-forgot-password-link` | P1 |
|
|
207
|
-
| 45 | `<a href="/register">` | none | `login-register-link` | P1 |
|
|
208
|
-
| 50 | `<div className="error">` | `className="error-message"` | `login-error-alert` | P1 |
|
|
209
|
-
| 55 | `<img>` | `className="logo"` | `login-logo-img` | P2 |
|
|
210
|
-
|
|
211
|
-
#### CheckoutForm.tsx -- CheckoutForm Component
|
|
212
|
-
|
|
213
|
-
**Path:** `src/components/checkout/CheckoutForm.tsx`
|
|
214
|
-
**Interactive elements:** 10 (6 P0, 3 P1, 1 P2)
|
|
215
|
-
|
|
216
|
-
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
217
|
-
|------|---------|-----------------|----------------------|----------|
|
|
218
|
-
| 12 | `<form>` | `className="checkout-form"` | `checkout-form` | P0 |
|
|
219
|
-
| 18 | `<input type="email">` | `data-testid="email"` | EXISTING -- no change | P0 |
|
|
220
|
-
| 24 | `<input type="text">` (card number) | `name="cardNumber"` | `checkout-card-number-input` | P0 |
|
|
221
|
-
| 30 | `<input type="text">` (expiry) | `name="expiry"` | `checkout-expiry-input` | P0 |
|
|
222
|
-
| 36 | `<input type="text">` (CVV) | `name="cvv"` | `checkout-cvv-input` | P0 |
|
|
223
|
-
| 42 | `<button type="submit">` | `data-testid="submitBtn"` | EXISTING -- no change | P0 |
|
|
224
|
-
| 48 | `<select>` (country) | `name="country"` | `checkout-country-select` | P1 |
|
|
225
|
-
| 54 | `<input type="text">` (promo code) | none | `checkout-promo-code-input` | P1 |
|
|
226
|
-
| 60 | `<span>` (total display) | `className="order-total"` | `checkout-total-text` | P1 |
|
|
227
|
-
| 66 | `<img>` (card brand icon) | `className="card-icon"` | `checkout-card-brand-img` | P2 |
|
|
228
|
-
|
|
229
|
-
#### ProductCard.tsx -- ProductCard Component
|
|
230
|
-
|
|
231
|
-
**Path:** `src/components/products/ProductCard.tsx`
|
|
232
|
-
**Interactive elements:** 5 (2 P0, 2 P1, 1 P2)
|
|
233
|
-
|
|
234
|
-
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
235
|
-
|------|---------|-----------------|----------------------|----------|
|
|
236
|
-
| 10 | `<button>` (add to cart) | `data-testid="add-cart"` | EXISTING -- no change | P0 |
|
|
237
|
-
| 16 | `<a>` (product detail link) | `className="product-link"` | `product-detail-link` | P0 |
|
|
238
|
-
| 22 | `<span>` (product name) | `data-testid="product_name"` | EXISTING -- no change | P1 |
|
|
239
|
-
| 28 | `<span>` (price display) | `className="price"` | `product-price-text` | P1 |
|
|
240
|
-
| 34 | `<img>` (product image) | `data-testid="productImg"` | EXISTING -- no change | P2 |
|
|
241
|
-
|
|
242
|
-
#### NavigationBar.tsx -- NavigationBar Component
|
|
243
|
-
|
|
244
|
-
**Path:** `src/components/layout/NavigationBar.tsx`
|
|
245
|
-
**Interactive elements:** 7 (1 P0, 5 P1, 1 P2)
|
|
246
|
-
|
|
247
|
-
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
248
|
-
|------|---------|-----------------|----------------------|----------|
|
|
249
|
-
| 8 | `<a>` (logo/home link) | `className="brand"` | `navbar-home-link` | P0 |
|
|
250
|
-
| 14 | `<a>` (products link) | none | `navbar-products-link` | P1 |
|
|
251
|
-
| 20 | `<a>` (orders link) | none | `navbar-orders-link` | P1 |
|
|
252
|
-
| 26 | `<a>` (cart link) | `data-testid="cart-link"` | EXISTING -- no change | P1 |
|
|
253
|
-
| 32 | `<button>` (user menu toggle) | none | `navbar-user-menu-btn` | P1 |
|
|
254
|
-
| 38 | `<a>` (logout link) | none | `navbar-logout-link` | P1 |
|
|
255
|
-
| 44 | `<span>` (cart count badge) | `data-testid="cartCount"` | EXISTING -- no change | P2 |
|
|
256
|
-
|
|
257
|
-
#### OrderHistory.tsx -- OrderHistory Component
|
|
258
|
-
|
|
259
|
-
**Path:** `src/components/orders/OrderHistory.tsx`
|
|
260
|
-
**Interactive elements:** 6 (2 P0, 2 P1, 2 P2)
|
|
261
|
-
|
|
262
|
-
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
263
|
-
|------|---------|-----------------|----------------------|----------|
|
|
264
|
-
| 10 | `<table>` | `className="orders-table"` | `order-history-table` | P0 |
|
|
265
|
-
| 15 | `<button>` (view details) | `className="btn-sm"` | `order-view-details-btn` | P0 |
|
|
266
|
-
| 22 | `<select>` (status filter) | `name="statusFilter"` | `order-status-filter-select` | P1 |
|
|
267
|
-
| 28 | `<input type="text">` (search) | `name="search"` | `order-search-input` | P1 |
|
|
268
|
-
| 34 | `<span>` (order status badge) | `className="status-badge"` | `order-status-badge` | P2 |
|
|
269
|
-
| 40 | `<span>` (order total) | `className="order-amount"` | `order-total-text` | P2 |
|
|
270
|
-
|
|
271
|
-
#### UserProfilePage.tsx -- UserProfilePage Component
|
|
272
|
-
|
|
273
|
-
**Path:** `src/components/user/UserProfilePage.tsx`
|
|
274
|
-
**Interactive elements:** 6 (3 P0, 2 P1, 1 P2)
|
|
275
|
-
|
|
276
|
-
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
277
|
-
|------|---------|-----------------|----------------------|----------|
|
|
278
|
-
| 12 | `<form>` | `className="profile-form"` | `profile-form` | P0 |
|
|
279
|
-
| 18 | `<input type="text">` (name) | `name="displayName"` | `profile-name-input` | P0 |
|
|
280
|
-
| 24 | `<input type="email">` (email) | `name="email"` | `profile-email-input` | P0 |
|
|
281
|
-
| 30 | `<button type="submit">` | `className="save-btn"` | `profile-save-btn` | P1 |
|
|
282
|
-
| 36 | `<button>` (change password) | none | `profile-change-password-btn` | P1 |
|
|
283
|
-
| 42 | `<img>` (avatar) | `className="avatar"` | `profile-avatar-img` | P2 |
|
|
284
|
-
|
|
285
|
-
### Naming Convention Compliance
|
|
286
|
-
|
|
287
|
-
**Existing values audited:** 8
|
|
288
|
-
|
|
289
|
-
| Existing Value | Compliant | Issue | Suggested Rename |
|
|
290
|
-
|----------------|-----------|-------|-----------------|
|
|
291
|
-
| `cart-link` | YES | -- | -- |
|
|
292
|
-
| `cartCount` | NO | camelCase instead of kebab-case; missing element-type suffix | `navbar-cart-count-badge` |
|
|
293
|
-
| `email` | NO | Too generic; missing context prefix and element-type suffix | `checkout-email-input` |
|
|
294
|
-
| `submitBtn` | NO | camelCase instead of kebab-case; missing context prefix | `checkout-submit-btn` |
|
|
295
|
-
| `add-cart` | YES | -- | -- |
|
|
296
|
-
| `product_name` | NO | snake_case instead of kebab-case; missing element-type suffix | `product-name-text` |
|
|
297
|
-
| `productImg` | NO | camelCase instead of kebab-case; missing context in description | `product-image-img` |
|
|
298
|
-
| `cart-count-badge` | YES | -- | -- |
|
|
299
|
-
|
|
300
|
-
**Summary:** 3 of 8 existing `data-testid` values are compliant with the `{context}-{description}-{element-type}` naming convention. 5 values are non-compliant and should be renamed during the injection pass.
|
|
301
|
-
|
|
302
|
-
### Decision Gate
|
|
303
|
-
|
|
304
|
-
```
|
|
305
|
-
DECISION: FULL PASS
|
|
306
|
-
REASON: Current coverage 19% (8/42), well below the 50% threshold
|
|
307
|
-
ACTION: Inject all P0, P1, P2 elements across 6 component files
|
|
308
|
-
FILES: 6 files to process
|
|
309
|
-
ELEMENTS: 34 elements to inject
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
Additionally, 5 existing `data-testid` values should be renamed for naming convention compliance (coordinate with test files that reference old values).
|
|
313
|
-
|
|
314
|
-
---
|
|
315
|
-
|
|
316
|
-
## Guidelines
|
|
317
|
-
|
|
318
|
-
**DO:**
|
|
319
|
-
- Follow `{context}-{description}-{element-type}` pattern strictly for all proposed values
|
|
320
|
-
- Mark elements with existing `data-testid` as `EXISTING -- no change` -- never modify working test IDs without explicit approval
|
|
321
|
-
- Prioritize form inputs (`<input>`, `<select>`, `<textarea>`) and submit buttons as P0
|
|
322
|
-
- Derive context from the component filename: `LoginPage.tsx` becomes `login`, `CheckoutForm.tsx` becomes `checkout`
|
|
323
|
-
- Use the element-type suffix table from the naming convention (see SKILL.md)
|
|
324
|
-
- Include the line number for every element to enable precise injection
|
|
325
|
-
- Check for duplicate `data-testid` values within the same page scope before proposing
|
|
326
|
-
|
|
327
|
-
**DON'T:**
|
|
328
|
-
- Propose duplicate `data-testid` values within the same page or route scope
|
|
329
|
-
- Add `data-testid` to purely non-interactive elements (static `<div>`, `<span>`) unless they display dynamic data the tests need to read
|
|
330
|
-
- Use framework-specific prefixes: no `cy-`, `pw-`, `qa-` -- just the bare value
|
|
331
|
-
- Modify elements that already have a working `data-testid` -- flag for rename review only
|
|
332
|
-
- Skip the naming convention compliance check -- even "EXISTING" values should be audited
|
|
333
|
-
- Propose vague generic values like `input-1`, `button-2` -- always include semantic context and description
|
|
334
|
-
|
|
335
|
-
---
|
|
336
|
-
|
|
337
|
-
## Quality Gate
|
|
338
|
-
|
|
339
|
-
Before delivering this artifact, verify:
|
|
340
|
-
|
|
341
|
-
- [ ] Every interactive element across all scanned files has an entry in the File Details section
|
|
342
|
-
- [ ] All proposed `data-testid` values follow the `{context}-{description}-{element-type}` convention
|
|
343
|
-
- [ ] No duplicate `data-testid` values exist within the same page/route scope
|
|
344
|
-
- [ ] Coverage Score formula is shown explicitly with the correct calculation
|
|
345
|
-
- [ ] Decision Gate recommendation matches the coverage score thresholds
|
|
346
|
-
- [ ] All existing `data-testid` values are audited in the Naming Convention Compliance section
|
|
347
|
-
- [ ] Priority assignments are consistent: form inputs and submit buttons are P0, navigation and feedback are P1, decorative elements are P2
|
|
348
|
-
- [ ] Line numbers are included for every element in every File Details table
|
|
349
|
-
|
|
350
|
-
---
|
|
351
|
-
|
|
352
|
-
*Template version: 1.0*
|
|
353
|
-
*Producer: qa-testid-injector*
|
|
354
|
-
*Last updated: {date}*
|
|
1
|
+
---
|
|
2
|
+
template_name: testid-audit-report
|
|
3
|
+
version: "1.0"
|
|
4
|
+
artifact_type: audit
|
|
5
|
+
produces: TESTID_AUDIT_REPORT.md
|
|
6
|
+
producer_agent: qa-testid-injector
|
|
7
|
+
consumer_agents:
|
|
8
|
+
- qa-executor
|
|
9
|
+
- human-reviewer
|
|
10
|
+
required_sections:
|
|
11
|
+
- summary
|
|
12
|
+
- coverage-score
|
|
13
|
+
- file-details
|
|
14
|
+
- naming-convention-compliance
|
|
15
|
+
- decision-gate
|
|
16
|
+
example_domain: shopflow
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# TESTID_AUDIT_REPORT.md Template
|
|
20
|
+
|
|
21
|
+
**Purpose:** Audit of `data-testid` coverage across frontend component files, identifying interactive elements that lack stable test selectors and proposing injection values following a consistent naming convention.
|
|
22
|
+
|
|
23
|
+
**Producer:** `qa-testid-injector` (Phase 2: AUDIT step)
|
|
24
|
+
**Consumers:** `qa-executor` (uses proposed test IDs when writing E2E tests), `human-reviewer` (reviews proposed values before injection)
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Required Sections
|
|
29
|
+
|
|
30
|
+
### Section 1: Summary
|
|
31
|
+
|
|
32
|
+
**Description:** High-level counts of scanned files, interactive elements found, and breakdown of missing `data-testid` attributes by priority.
|
|
33
|
+
|
|
34
|
+
**Fields:**
|
|
35
|
+
|
|
36
|
+
| Field | Type | Required | Description |
|
|
37
|
+
|-------|------|----------|-------------|
|
|
38
|
+
| files_scanned | integer | YES | Total number of component files scanned |
|
|
39
|
+
| total_interactive_elements | integer | YES | Total interactive elements found across all files |
|
|
40
|
+
| elements_with_testid | integer | YES | Elements that already have a `data-testid` attribute |
|
|
41
|
+
| elements_missing_testid | integer | YES | Elements that need a `data-testid` injected |
|
|
42
|
+
| p0_missing | integer | YES | P0 (must have): form inputs, submit buttons, primary actions |
|
|
43
|
+
| p1_missing | integer | YES | P1 (should have): navigation links, secondary actions, feedback elements |
|
|
44
|
+
| p2_missing | integer | YES | P2 (nice to have): decorative images, static containers showing dynamic data |
|
|
45
|
+
|
|
46
|
+
**Priority Definitions:**
|
|
47
|
+
|
|
48
|
+
| Priority | Label | Elements |
|
|
49
|
+
|----------|-------|----------|
|
|
50
|
+
| P0 | Must Have | Form `<input>`, `<select>`, `<textarea>`, submit `<button>`, primary action buttons, `<form>` tags |
|
|
51
|
+
| P1 | Should Have | Navigation `<a>` links, secondary buttons, error/alert messages, toggle/checkbox/radio |
|
|
52
|
+
| P2 | Nice to Have | Images showing product data, badges, decorative containers with dynamic content |
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### Section 2: Coverage Score
|
|
57
|
+
|
|
58
|
+
**Description:** Quantified coverage percentage with interpretation and projected post-injection score.
|
|
59
|
+
|
|
60
|
+
**Fields:**
|
|
61
|
+
|
|
62
|
+
| Field | Type | Required | Description |
|
|
63
|
+
|-------|------|----------|-------------|
|
|
64
|
+
| current_coverage | percentage | YES | `elements_with_testid / total_interactive_elements * 100` |
|
|
65
|
+
| projected_coverage | percentage | YES | Coverage percentage after all proposed injections are applied |
|
|
66
|
+
| score_interpretation | string | YES | One of: EXCELLENT, GOOD, NEEDS WORK, CRITICAL |
|
|
67
|
+
|
|
68
|
+
**Formula:**
|
|
69
|
+
```
|
|
70
|
+
Current Coverage = (elements_with_testid / total_interactive_elements) * 100
|
|
71
|
+
Projected Coverage = ((elements_with_testid + elements_missing_testid) / total_interactive_elements) * 100
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Interpretation Thresholds:**
|
|
75
|
+
|
|
76
|
+
| Score Range | Interpretation | Meaning |
|
|
77
|
+
|-------------|---------------|---------|
|
|
78
|
+
| > 90% | EXCELLENT | Most elements already have test IDs; selective injection only |
|
|
79
|
+
| 50% - 90% | GOOD | Decent baseline; targeted injection pass needed |
|
|
80
|
+
| 1% - 49% | NEEDS WORK | Significant gaps; full injection pass required |
|
|
81
|
+
| 0% | CRITICAL | No test IDs exist; P0-first strategy recommended |
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
### Section 3: File Details
|
|
86
|
+
|
|
87
|
+
**Description:** Per-component file audit showing every interactive element, its current selector state, and the proposed `data-testid` value.
|
|
88
|
+
|
|
89
|
+
**Per-File Structure:**
|
|
90
|
+
|
|
91
|
+
| Field | Type | Required | Description |
|
|
92
|
+
|-------|------|----------|-------------|
|
|
93
|
+
| file_path | string | YES | Full path to the component file |
|
|
94
|
+
| component_name | string | YES | Name of the React/Vue/Angular component |
|
|
95
|
+
| element_count | integer | YES | Total interactive elements in this file |
|
|
96
|
+
|
|
97
|
+
**Per-Element Table Columns:**
|
|
98
|
+
|
|
99
|
+
| Column | Description |
|
|
100
|
+
|--------|-------------|
|
|
101
|
+
| Line | Line number in the source file where the element appears |
|
|
102
|
+
| Element | HTML tag and type (e.g., `<input type="email">`, `<button type="submit">`) |
|
|
103
|
+
| Current Selector | What exists now: `data-testid="value"`, `className="..."`, `name="..."`, or `none` |
|
|
104
|
+
| Proposed data-testid | The proposed value following `{context}-{description}-{element-type}` convention, or `EXISTING -- no change` if already has a `data-testid` |
|
|
105
|
+
| Priority | P0, P1, or P2 |
|
|
106
|
+
|
|
107
|
+
**Rules:**
|
|
108
|
+
- Elements with an EXISTING `data-testid` are marked `EXISTING -- no change` and are never modified
|
|
109
|
+
- Elements missing `data-testid` receive a proposed value following `{context}-{description}-{element-type}` naming convention
|
|
110
|
+
- Context is derived from the component filename (e.g., `LoginPage.tsx` -> `login`, `CheckoutForm.tsx` -> `checkout`)
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
### Section 4: Naming Convention Compliance
|
|
115
|
+
|
|
116
|
+
**Description:** Audit of existing `data-testid` values against the `{context}-{description}-{element-type}` naming pattern.
|
|
117
|
+
|
|
118
|
+
**Fields:**
|
|
119
|
+
|
|
120
|
+
| Field | Type | Required | Description |
|
|
121
|
+
|-------|------|----------|-------------|
|
|
122
|
+
| total_existing | integer | YES | Count of elements with existing `data-testid` |
|
|
123
|
+
| compliant_count | integer | YES | Count that follow the naming convention |
|
|
124
|
+
| non_compliant_count | integer | YES | Count that violate the naming convention |
|
|
125
|
+
|
|
126
|
+
**Per-Value Table Columns:**
|
|
127
|
+
|
|
128
|
+
| Column | Description |
|
|
129
|
+
|--------|-------------|
|
|
130
|
+
| Existing Value | The current `data-testid` value |
|
|
131
|
+
| Compliant | YES or NO |
|
|
132
|
+
| Issue | If non-compliant: what is wrong (e.g., "missing element-type suffix", "camelCase instead of kebab-case") |
|
|
133
|
+
| Suggested Rename | If non-compliant: the corrected value following convention |
|
|
134
|
+
|
|
135
|
+
**Convention Rules:**
|
|
136
|
+
- All values MUST be kebab-case: `login-submit-btn`, never `loginSubmitBtn` or `login_submit_btn`
|
|
137
|
+
- All values MUST end with an element-type suffix: `-btn`, `-input`, `-link`, `-form`, `-img`, etc.
|
|
138
|
+
- All values MUST start with a context prefix derived from the component name
|
|
139
|
+
- No framework-specific prefixes: no `cy-`, `pw-`, `qa-` prefixes
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
### Section 5: Decision Gate
|
|
144
|
+
|
|
145
|
+
**Description:** Automated recommendation based on coverage score that determines the injection strategy.
|
|
146
|
+
|
|
147
|
+
**Decision Matrix:**
|
|
148
|
+
|
|
149
|
+
| Coverage | Decision | Strategy |
|
|
150
|
+
|----------|----------|----------|
|
|
151
|
+
| > 90% | SELECTIVE | Inject only P0 missing elements |
|
|
152
|
+
| 50% - 90% | TARGETED | Inject P0 and P1 missing elements |
|
|
153
|
+
| 1% - 49% | FULL PASS | Inject all P0, P1, P2 elements |
|
|
154
|
+
| 0% | P0 FIRST | Inject P0 elements only, then re-audit after |
|
|
155
|
+
| 0 files scanned | STOP | No frontend component files detected -- abort injection |
|
|
156
|
+
|
|
157
|
+
**Output Format:**
|
|
158
|
+
```
|
|
159
|
+
DECISION: {decision_type}
|
|
160
|
+
REASON: Current coverage {X}%, {explanation}
|
|
161
|
+
ACTION: {what the injector should do next}
|
|
162
|
+
FILES: {count} files to process
|
|
163
|
+
ELEMENTS: {count} elements to inject
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Worked Example (ShopFlow E-Commerce API)
|
|
169
|
+
|
|
170
|
+
### Summary
|
|
171
|
+
|
|
172
|
+
| Metric | Count |
|
|
173
|
+
|--------|-------|
|
|
174
|
+
| Files Scanned | 6 |
|
|
175
|
+
| Total Interactive Elements | 42 |
|
|
176
|
+
| Elements with Existing data-testid | 8 |
|
|
177
|
+
| Elements Missing data-testid | 34 |
|
|
178
|
+
| P0 Missing (must have) | 18 |
|
|
179
|
+
| P1 Missing (should have) | 12 |
|
|
180
|
+
| P2 Missing (nice to have) | 4 |
|
|
181
|
+
|
|
182
|
+
### Coverage Score
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
Current Coverage = 8 / 42 * 100 = 19.05%
|
|
186
|
+
Projected Coverage = 42 / 42 * 100 = 100%
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Score: 19% -- NEEDS WORK**
|
|
190
|
+
|
|
191
|
+
Current coverage is well below the 50% threshold. A full injection pass is recommended to bring all interactive elements up to testability standards before E2E test generation.
|
|
192
|
+
|
|
193
|
+
### File Details
|
|
194
|
+
|
|
195
|
+
#### LoginPage.tsx -- LoginPage Component
|
|
196
|
+
|
|
197
|
+
**Path:** `src/components/auth/LoginPage.tsx`
|
|
198
|
+
**Interactive elements:** 8 (4 P0, 3 P1, 1 P2)
|
|
199
|
+
|
|
200
|
+
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
201
|
+
|------|---------|-----------------|----------------------|----------|
|
|
202
|
+
| 18 | `<form>` | `className="login-form"` | `login-form` | P0 |
|
|
203
|
+
| 22 | `<input type="email">` | `name="email"` | `login-email-input` | P0 |
|
|
204
|
+
| 28 | `<input type="password">` | `name="password"` | `login-password-input` | P0 |
|
|
205
|
+
| 34 | `<button type="submit">` | `className="btn-primary"` | `login-submit-btn` | P0 |
|
|
206
|
+
| 40 | `<a href="/forgot-password">` | none | `login-forgot-password-link` | P1 |
|
|
207
|
+
| 45 | `<a href="/register">` | none | `login-register-link` | P1 |
|
|
208
|
+
| 50 | `<div className="error">` | `className="error-message"` | `login-error-alert` | P1 |
|
|
209
|
+
| 55 | `<img>` | `className="logo"` | `login-logo-img` | P2 |
|
|
210
|
+
|
|
211
|
+
#### CheckoutForm.tsx -- CheckoutForm Component
|
|
212
|
+
|
|
213
|
+
**Path:** `src/components/checkout/CheckoutForm.tsx`
|
|
214
|
+
**Interactive elements:** 10 (6 P0, 3 P1, 1 P2)
|
|
215
|
+
|
|
216
|
+
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
217
|
+
|------|---------|-----------------|----------------------|----------|
|
|
218
|
+
| 12 | `<form>` | `className="checkout-form"` | `checkout-form` | P0 |
|
|
219
|
+
| 18 | `<input type="email">` | `data-testid="email"` | EXISTING -- no change | P0 |
|
|
220
|
+
| 24 | `<input type="text">` (card number) | `name="cardNumber"` | `checkout-card-number-input` | P0 |
|
|
221
|
+
| 30 | `<input type="text">` (expiry) | `name="expiry"` | `checkout-expiry-input` | P0 |
|
|
222
|
+
| 36 | `<input type="text">` (CVV) | `name="cvv"` | `checkout-cvv-input` | P0 |
|
|
223
|
+
| 42 | `<button type="submit">` | `data-testid="submitBtn"` | EXISTING -- no change | P0 |
|
|
224
|
+
| 48 | `<select>` (country) | `name="country"` | `checkout-country-select` | P1 |
|
|
225
|
+
| 54 | `<input type="text">` (promo code) | none | `checkout-promo-code-input` | P1 |
|
|
226
|
+
| 60 | `<span>` (total display) | `className="order-total"` | `checkout-total-text` | P1 |
|
|
227
|
+
| 66 | `<img>` (card brand icon) | `className="card-icon"` | `checkout-card-brand-img` | P2 |
|
|
228
|
+
|
|
229
|
+
#### ProductCard.tsx -- ProductCard Component
|
|
230
|
+
|
|
231
|
+
**Path:** `src/components/products/ProductCard.tsx`
|
|
232
|
+
**Interactive elements:** 5 (2 P0, 2 P1, 1 P2)
|
|
233
|
+
|
|
234
|
+
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
235
|
+
|------|---------|-----------------|----------------------|----------|
|
|
236
|
+
| 10 | `<button>` (add to cart) | `data-testid="add-cart"` | EXISTING -- no change | P0 |
|
|
237
|
+
| 16 | `<a>` (product detail link) | `className="product-link"` | `product-detail-link` | P0 |
|
|
238
|
+
| 22 | `<span>` (product name) | `data-testid="product_name"` | EXISTING -- no change | P1 |
|
|
239
|
+
| 28 | `<span>` (price display) | `className="price"` | `product-price-text` | P1 |
|
|
240
|
+
| 34 | `<img>` (product image) | `data-testid="productImg"` | EXISTING -- no change | P2 |
|
|
241
|
+
|
|
242
|
+
#### NavigationBar.tsx -- NavigationBar Component
|
|
243
|
+
|
|
244
|
+
**Path:** `src/components/layout/NavigationBar.tsx`
|
|
245
|
+
**Interactive elements:** 7 (1 P0, 5 P1, 1 P2)
|
|
246
|
+
|
|
247
|
+
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
248
|
+
|------|---------|-----------------|----------------------|----------|
|
|
249
|
+
| 8 | `<a>` (logo/home link) | `className="brand"` | `navbar-home-link` | P0 |
|
|
250
|
+
| 14 | `<a>` (products link) | none | `navbar-products-link` | P1 |
|
|
251
|
+
| 20 | `<a>` (orders link) | none | `navbar-orders-link` | P1 |
|
|
252
|
+
| 26 | `<a>` (cart link) | `data-testid="cart-link"` | EXISTING -- no change | P1 |
|
|
253
|
+
| 32 | `<button>` (user menu toggle) | none | `navbar-user-menu-btn` | P1 |
|
|
254
|
+
| 38 | `<a>` (logout link) | none | `navbar-logout-link` | P1 |
|
|
255
|
+
| 44 | `<span>` (cart count badge) | `data-testid="cartCount"` | EXISTING -- no change | P2 |
|
|
256
|
+
|
|
257
|
+
#### OrderHistory.tsx -- OrderHistory Component
|
|
258
|
+
|
|
259
|
+
**Path:** `src/components/orders/OrderHistory.tsx`
|
|
260
|
+
**Interactive elements:** 6 (2 P0, 2 P1, 2 P2)
|
|
261
|
+
|
|
262
|
+
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
263
|
+
|------|---------|-----------------|----------------------|----------|
|
|
264
|
+
| 10 | `<table>` | `className="orders-table"` | `order-history-table` | P0 |
|
|
265
|
+
| 15 | `<button>` (view details) | `className="btn-sm"` | `order-view-details-btn` | P0 |
|
|
266
|
+
| 22 | `<select>` (status filter) | `name="statusFilter"` | `order-status-filter-select` | P1 |
|
|
267
|
+
| 28 | `<input type="text">` (search) | `name="search"` | `order-search-input` | P1 |
|
|
268
|
+
| 34 | `<span>` (order status badge) | `className="status-badge"` | `order-status-badge` | P2 |
|
|
269
|
+
| 40 | `<span>` (order total) | `className="order-amount"` | `order-total-text` | P2 |
|
|
270
|
+
|
|
271
|
+
#### UserProfilePage.tsx -- UserProfilePage Component
|
|
272
|
+
|
|
273
|
+
**Path:** `src/components/user/UserProfilePage.tsx`
|
|
274
|
+
**Interactive elements:** 6 (3 P0, 2 P1, 1 P2)
|
|
275
|
+
|
|
276
|
+
| Line | Element | Current Selector | Proposed data-testid | Priority |
|
|
277
|
+
|------|---------|-----------------|----------------------|----------|
|
|
278
|
+
| 12 | `<form>` | `className="profile-form"` | `profile-form` | P0 |
|
|
279
|
+
| 18 | `<input type="text">` (name) | `name="displayName"` | `profile-name-input` | P0 |
|
|
280
|
+
| 24 | `<input type="email">` (email) | `name="email"` | `profile-email-input` | P0 |
|
|
281
|
+
| 30 | `<button type="submit">` | `className="save-btn"` | `profile-save-btn` | P1 |
|
|
282
|
+
| 36 | `<button>` (change password) | none | `profile-change-password-btn` | P1 |
|
|
283
|
+
| 42 | `<img>` (avatar) | `className="avatar"` | `profile-avatar-img` | P2 |
|
|
284
|
+
|
|
285
|
+
### Naming Convention Compliance
|
|
286
|
+
|
|
287
|
+
**Existing values audited:** 8
|
|
288
|
+
|
|
289
|
+
| Existing Value | Compliant | Issue | Suggested Rename |
|
|
290
|
+
|----------------|-----------|-------|-----------------|
|
|
291
|
+
| `cart-link` | YES | -- | -- |
|
|
292
|
+
| `cartCount` | NO | camelCase instead of kebab-case; missing element-type suffix | `navbar-cart-count-badge` |
|
|
293
|
+
| `email` | NO | Too generic; missing context prefix and element-type suffix | `checkout-email-input` |
|
|
294
|
+
| `submitBtn` | NO | camelCase instead of kebab-case; missing context prefix | `checkout-submit-btn` |
|
|
295
|
+
| `add-cart` | YES | -- | -- |
|
|
296
|
+
| `product_name` | NO | snake_case instead of kebab-case; missing element-type suffix | `product-name-text` |
|
|
297
|
+
| `productImg` | NO | camelCase instead of kebab-case; missing context in description | `product-image-img` |
|
|
298
|
+
| `cart-count-badge` | YES | -- | -- |
|
|
299
|
+
|
|
300
|
+
**Summary:** 3 of 8 existing `data-testid` values are compliant with the `{context}-{description}-{element-type}` naming convention. 5 values are non-compliant and should be renamed during the injection pass.
|
|
301
|
+
|
|
302
|
+
### Decision Gate
|
|
303
|
+
|
|
304
|
+
```
|
|
305
|
+
DECISION: FULL PASS
|
|
306
|
+
REASON: Current coverage 19% (8/42), well below the 50% threshold
|
|
307
|
+
ACTION: Inject all P0, P1, P2 elements across 6 component files
|
|
308
|
+
FILES: 6 files to process
|
|
309
|
+
ELEMENTS: 34 elements to inject
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Additionally, 5 existing `data-testid` values should be renamed for naming convention compliance (coordinate with test files that reference old values).
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## Guidelines
|
|
317
|
+
|
|
318
|
+
**DO:**
|
|
319
|
+
- Follow `{context}-{description}-{element-type}` pattern strictly for all proposed values
|
|
320
|
+
- Mark elements with existing `data-testid` as `EXISTING -- no change` -- never modify working test IDs without explicit approval
|
|
321
|
+
- Prioritize form inputs (`<input>`, `<select>`, `<textarea>`) and submit buttons as P0
|
|
322
|
+
- Derive context from the component filename: `LoginPage.tsx` becomes `login`, `CheckoutForm.tsx` becomes `checkout`
|
|
323
|
+
- Use the element-type suffix table from the naming convention (see SKILL.md)
|
|
324
|
+
- Include the line number for every element to enable precise injection
|
|
325
|
+
- Check for duplicate `data-testid` values within the same page scope before proposing
|
|
326
|
+
|
|
327
|
+
**DON'T:**
|
|
328
|
+
- Propose duplicate `data-testid` values within the same page or route scope
|
|
329
|
+
- Add `data-testid` to purely non-interactive elements (static `<div>`, `<span>`) unless they display dynamic data the tests need to read
|
|
330
|
+
- Use framework-specific prefixes: no `cy-`, `pw-`, `qa-` -- just the bare value
|
|
331
|
+
- Modify elements that already have a working `data-testid` -- flag for rename review only
|
|
332
|
+
- Skip the naming convention compliance check -- even "EXISTING" values should be audited
|
|
333
|
+
- Propose vague generic values like `input-1`, `button-2` -- always include semantic context and description
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Quality Gate
|
|
338
|
+
|
|
339
|
+
Before delivering this artifact, verify:
|
|
340
|
+
|
|
341
|
+
- [ ] Every interactive element across all scanned files has an entry in the File Details section
|
|
342
|
+
- [ ] All proposed `data-testid` values follow the `{context}-{description}-{element-type}` convention
|
|
343
|
+
- [ ] No duplicate `data-testid` values exist within the same page/route scope
|
|
344
|
+
- [ ] Coverage Score formula is shown explicitly with the correct calculation
|
|
345
|
+
- [ ] Decision Gate recommendation matches the coverage score thresholds
|
|
346
|
+
- [ ] All existing `data-testid` values are audited in the Naming Convention Compliance section
|
|
347
|
+
- [ ] Priority assignments are consistent: form inputs and submit buttons are P0, navigation and feedback are P1, decorative elements are P2
|
|
348
|
+
- [ ] Line numbers are included for every element in every File Details table
|
|
349
|
+
|
|
350
|
+
---
|
|
351
|
+
|
|
352
|
+
*Template version: 1.0*
|
|
353
|
+
*Producer: qa-testid-injector*
|
|
354
|
+
*Last updated: {date}*
|