@qa-gentic/stlc-agents 1.0.14 → 1.0.16

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.
Files changed (43) hide show
  1. package/README.md +1 -2
  2. package/package.json +1 -1
  3. package/skills/AGENT-BEHAVIOR.md +15 -22
  4. package/skills/deduplication-protocol/SKILL.md +51 -3
  5. package/skills/generate-gherkin/SKILL.md +15 -30
  6. package/skills/generate-gherkin/references/step-by-step.md +2 -6
  7. package/skills/generate-playwright-code/SKILL.md +19 -122
  8. package/skills/generate-playwright-code/references/file-structures.md +128 -0
  9. package/skills/generate-test-cases/SKILL.md +2 -2
  10. package/skills/write-helix-files/SKILL.md +12 -3
  11. package/src/stlc_agents/__pycache__/__init__.cpython-310.pyc +0 -0
  12. package/src/stlc_agents/agent_gherkin_generator/__pycache__/__init__.cpython-310.pyc +0 -0
  13. package/src/stlc_agents/agent_gherkin_generator/__pycache__/server.cpython-310.pyc +0 -0
  14. package/src/stlc_agents/agent_gherkin_generator/server.py +14 -62
  15. package/src/stlc_agents/agent_gherkin_generator/tools/__pycache__/__init__.cpython-310.pyc +0 -0
  16. package/src/stlc_agents/agent_gherkin_generator/tools/__pycache__/ado_gherkin.cpython-310.pyc +0 -0
  17. package/src/stlc_agents/agent_gherkin_generator/tools/ado_gherkin.py +5 -126
  18. package/src/stlc_agents/agent_helix_writer/__pycache__/__init__.cpython-310.pyc +0 -0
  19. package/src/stlc_agents/agent_helix_writer/__pycache__/server.cpython-310.pyc +0 -0
  20. package/src/stlc_agents/agent_helix_writer/tools/__pycache__/__init__.cpython-310.pyc +0 -0
  21. package/src/stlc_agents/agent_helix_writer/tools/__pycache__/boilerplate.cpython-310.pyc +0 -0
  22. package/src/stlc_agents/agent_helix_writer/tools/__pycache__/helix_write.cpython-310.pyc +0 -0
  23. package/src/stlc_agents/agent_jira_manager/__pycache__/__init__.cpython-310.pyc +0 -0
  24. package/src/stlc_agents/agent_jira_manager/__pycache__/server.cpython-310.pyc +0 -0
  25. package/src/stlc_agents/agent_jira_manager/server.py +0 -32
  26. package/src/stlc_agents/agent_jira_manager/tools/__pycache__/__init__.cpython-310.pyc +0 -0
  27. package/src/stlc_agents/agent_jira_manager/tools/__pycache__/jira_workitem.cpython-310.pyc +0 -0
  28. package/src/stlc_agents/agent_jira_manager/tools/jira_workitem.py +3 -78
  29. package/src/stlc_agents/agent_playwright_generator/__pycache__/__init__.cpython-310.pyc +0 -0
  30. package/src/stlc_agents/agent_playwright_generator/__pycache__/server.cpython-310.pyc +0 -0
  31. package/src/stlc_agents/agent_playwright_generator/server.py +57 -7
  32. package/src/stlc_agents/agent_playwright_generator/tools/__pycache__/__init__.cpython-310.pyc +0 -0
  33. package/src/stlc_agents/agent_playwright_generator/tools/__pycache__/ado_attach.cpython-310.pyc +0 -0
  34. package/src/stlc_agents/agent_test_case_manager/__pycache__/__init__.cpython-310.pyc +0 -0
  35. package/src/stlc_agents/agent_test_case_manager/__pycache__/server.cpython-310.pyc +0 -0
  36. package/src/stlc_agents/agent_test_case_manager/server.py +4 -4
  37. package/src/stlc_agents/agent_test_case_manager/tools/__pycache__/__init__.cpython-310.pyc +0 -0
  38. package/src/stlc_agents/agent_test_case_manager/tools/__pycache__/ado_workitem.cpython-310.pyc +0 -0
  39. package/src/stlc_agents/agent_test_case_manager/tools/ado_workitem.py +3 -5
  40. package/src/stlc_agents/shared/__pycache__/__init__.cpython-310.pyc +0 -0
  41. package/src/stlc_agents/shared/__pycache__/auth.cpython-310.pyc +0 -0
  42. package/src/stlc_agents/shared_jira/__pycache__/__init__.cpython-310.pyc +0 -0
  43. package/src/stlc_agents/shared_jira/__pycache__/auth.cpython-310.pyc +0 -0
package/README.md CHANGED
@@ -170,7 +170,6 @@ Write the generated files to my Helix-QA project at /workspace/my-qa-project
170
170
 
171
171
  | Tool | Description |
172
172
  |---|---|
173
- | `fetch_epic_hierarchy` | Fetch an Epic and all child Features, PBIs, Bugs, and existing test cases. |
174
173
  | `fetch_feature_hierarchy` | Fetch a Feature and all child PBIs/Bugs with acceptance criteria and existing attachments. |
175
174
  | `fetch_work_item_for_gherkin` | Fetch a PBI or Bug with parent Feature context, suggested file name, and linked test case steps. |
176
175
  | `attach_gherkin_to_feature` | Validate and attach a `.feature` file to a Feature work item. |
@@ -331,7 +330,7 @@ and refreshed automatically for ~60 days — no re-prompting.
331
330
  | Step | Azure DevOps | Jira Cloud |
332
331
  |---|---|---|
333
332
  | Fetch issue | `fetch_work_item` | `fetch_jira_issue` |
334
- | Fetch Epic hierarchy | `fetch_epic_hierarchy` | `fetch_jira_epic_hierarchy` |
333
+ | Fetch Epic hierarchy | Not supported — warn user | Not supported — warn user |
335
334
  | Check for duplicates | `get_linked_test_cases` | `get_linked_test_cases` |
336
335
  | Create & link test cases | `create_and_link_test_cases` | `create_and_link_test_cases` |
337
336
  | Generate Gherkin | `fetch_work_item_for_gherkin` → `attach_gherkin_to_work_item` | `qa-gherkin-generator` with Jira issue AC (save locally or attach to Jira) |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qa-gentic/stlc-agents",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "description": "QA STLC Agents — five MCP servers + skills for AI-powered test case, Gherkin, Playwright generation, and Helix-QA file writing against Azure DevOps and Jira Cloud. Full pipeline for both: fetch → test cases → Gherkin → Playwright → Helix-QA. Works with Claude Code, GitHub Copilot, Cursor, Windsurf.",
5
5
  "keywords": [
6
6
  "playwright",
@@ -229,25 +229,18 @@ OUTPUT: .feature file attached to PBI/Bug work item (or shown inline)
229
229
  ```
230
230
  INPUT: Epic ID + org URL + project name
231
231
 
232
- ├─ fetch_epic_hierarchy(id)
233
- │ └─ returns: features[] each with child_work_items[] and existing_test_cases[]
234
-
235
- ├─ [read ALL child Features and ALL child PBIs/Bugs before writing any Gherkin]
236
-
237
- ├─ for each child Feature:
238
- │ ├─ [deduplication-protocol Phase 1+2 for that Feature ID]
239
- │ ├─ [gap check for that Feature]
240
- │ ├─ [live snapshots for that Feature's screens]
241
- │ ├─ generate .feature file (5–10 scenarios)
242
- │ ├─ validate_gherkin_content(scope="feature")
243
- │ ├─ [show content to user]
244
- │ ├─ [ASK: "Attach .feature to Feature #{child_id}?"]
245
- │ └─ yes → attach_gherkin_to_feature(child_id)
246
-
247
- └─ [NEVER call create_and_link_test_cases on the Epic ID]
248
-
249
- OUTPUT: one .feature file per child Feature
250
- test cases NOT created unless user explicitly asks for child Feature/PBI coverage
232
+ └─ DO NOT call any fetch tool.
233
+ Respond immediately with:
234
+ "Epic-scoped Gherkin generation is not supported. An Epic spans multiple Features
235
+ and would produce files that are too large and unfocused to be useful.
236
+
237
+ Please provide one of the following instead:
238
+ A Feature ID I will generate 5–10 scenarios covering all child PBIs
239
+ A PBI or Bug ID — I will generate 3–9 scenarios scoped to that work item
240
+
241
+ To find the child Features under this Epic, look up the work item in Azure DevOps
242
+ and note the Feature IDs, then share them with me."
243
+ Wait for the user to provide a Feature or PBI/Bug ID. Do not proceed.
251
244
  ```
252
245
 
253
246
  ### Chain E — Playwright TypeScript from Gherkin
@@ -322,7 +315,7 @@ User provides work item ID
322
315
 
323
316
 
324
317
  Call the fetch tool for the intended operation
325
- (fetch_work_item, fetch_work_item_for_gherkin, or fetch_epic_hierarchy)
318
+ (fetch_work_item or fetch_work_item_for_gherkin)
326
319
 
327
320
 
328
321
  Read work_item_type from response
@@ -332,8 +325,8 @@ User provides work item ID
332
325
  "Epic" not "Epic"
333
326
  │ │
334
327
  ▼ ┌─────┴────────┐
335
- HARD STOP for test cases "Feature" "PBI"/"Bug"
336
- Use fetch_epic_hierarchy for Gherkin │ │
328
+ HARD STOP warn user to provide "Feature" "PBI"/"Bug"
329
+ a Feature or PBI/Bug ID instead │ │
337
330
  Never call create_and_link_test_cases │ │
338
331
  Never call attach_code_to_work_item │ │
339
332
  on the Epic ID Feature path PBI/Bug path
@@ -122,6 +122,53 @@ From the feature hierarchy response, check for:
122
122
  > If you cannot read an attachment's content, treat it as fully covering its domain and
123
123
  > produce NO new file of that type unless you can prove a gap.
124
124
 
125
+ ### 1E — Helix step-pattern scan (mandatory before generating any step definitions)
126
+
127
+ ADO attachments only cover files explicitly uploaded. The Helix-QA project on disk contains
128
+ all currently registered step definitions — many of which are **never attached to ADO** but
129
+ will be active at runtime because `cucumber.js` loads them via `src/test/steps/**/*.ts`.
130
+
131
+ Generating a new step that duplicates an existing Helix step causes an
132
+ `Ambiguous step definition` runtime error, even if the ADO dedup scan found nothing.
133
+
134
+ **Procedure — run every time before writing any `*.steps.ts`:**
135
+
136
+ ```
137
+ 1. qa-helix-writer:list_helix_tree(helix_root)
138
+ → collect all paths matching src/test/steps/*.steps.ts
139
+
140
+ 2. For each path found:
141
+ qa-helix-writer:read_helix_file(helix_root, path)
142
+ → extract all step pattern strings (Given/When/Then/And/But)
143
+ → extract all Before/After hook tags
144
+ → add to CACHE[id].existing_attachments.steps_files[]
145
+
146
+ 3. For each path matching src/test/features/*.feature:
147
+ qa-helix-writer:read_helix_file(helix_root, path)
148
+ → extract the Background step strings verbatim
149
+ → add to CACHE[id].existing_attachments.background_steps[]
150
+ ```
151
+
152
+ **Background reuse rule:** If a Background in a new feature file can be expressed entirely
153
+ using step patterns already registered in any existing `*.steps.ts`, you **must** use the
154
+ exact registered wording — do NOT generate new step strings for the same intent.
155
+
156
+ ```
157
+ # ✅ Correct — reuses registered pattern from reset-app-state.steps.ts
158
+ Background:
159
+ Given the user is logged in as "standard_user"
160
+ And the user is on the inventory page
161
+
162
+ # ❌ Wrong — generates duplicate steps that cause Ambiguous step definition
163
+ Background:
164
+ Given I am on the SauceDemo login page at "https://www.saucedemo.com/"
165
+ And I log in with username "standard_user" and password "secret_sauce"
166
+ And I am on the inventory page at "https://www.saucedemo.com/inventory.html"
167
+ ```
168
+
169
+ > This scan is **not optional for Jira pipelines either**. If the Helix project is present,
170
+ > always perform step 1E before writing steps, regardless of the work item source.
171
+
125
172
  ---
126
173
 
127
174
  ## PHASE 2 — DIFF Using Semantic Matching
@@ -163,7 +210,7 @@ For each proposed Gherkin scenario:
163
210
 
164
211
  - `locators.ts`: only emit keys not already in existing file; if delta empty → skip; if non-empty → attach as `locators.delta.ts`
165
212
  - `*Page.ts`: only emit methods not already present; if delta empty → skip; if non-empty → attach as `*Page.delta.ts`
166
- - `*.steps.ts`: only emit step strings not already registered; NEVER re-register an existing step (causes `Ambiguous step definition` runtime error)
213
+ - `*.steps.ts`: cross-check every proposed step pattern against **both** ADO attachment step strings (1D) **and** Helix on-disk step strings (1E); only emit step strings that appear in neither; NEVER re-register an existing step (causes `Ambiguous step definition` runtime error); reuse exact registered wording in Background blocks
167
214
 
168
215
  ---
169
216
 
@@ -211,7 +258,7 @@ Output after every run regardless of whether anything was created:
211
258
 
212
259
  1. **NEVER call `create_and_link_test_cases` without first calling `get_linked_test_cases`** on the same work item.
213
260
  2. **NEVER attach a `.feature` file without first checking for existing feature file attachments.**
214
- 3. **NEVER attach a `steps.ts` that re-registers an existing step string** — causes `Ambiguous step definition` at runtime.
261
+ 3. **NEVER attach a `steps.ts` that re-registers an existing step string** — causes `Ambiguous step definition` at runtime. Perform the Helix step-pattern scan (Phase 1E) before writing any step definition. ADO attachment checks alone are insufficient because most Helix step files are never attached to ADO.
215
262
  4. **NEVER treat tag differences as meaningful.** `[REGRESSION] Export List downloads CSV` is a duplicate of `[SMOKE] Clicking Export List downloads a valid CSV file`.
216
263
  5. **NEVER create more than one test case covering the same (subject, condition) pair.**
217
264
  6. **NEVER skip this protocol because the work item appears new.** `existing_test_cases_count: 0` in the hierarchy can still have cases via `get_linked_test_cases` — always call both.
@@ -252,7 +299,8 @@ CACHE[work_item_id] = {
252
299
  feature_files: [{ name, content }],
253
300
  locators_ts: { found: bool, keys: [] },
254
301
  page_objects: [{ name, methods: [] }],
255
- steps_files: [{ name, step_strings: [] }],
302
+ steps_files: [{ name, step_strings: [] }], # populated from BOTH 1D (ADO attachments) AND 1E (Helix on-disk read)
303
+ background_steps: [], # exact step strings from existing Helix *.feature Background blocks — new Backgrounds must reuse these
256
304
  },
257
305
  gap_check_completed: bool, # set true after generate-gherkin Step 2 passes
258
306
  phase1_completed: true,
@@ -4,7 +4,7 @@ description: >-
4
4
  Use when generating Gherkin feature files, BDD scenarios, or .feature files from Azure DevOps
5
5
  or Jira work items. Triggers on: "Gherkin", "feature file", "BDD", "scenarios", "acceptance
6
6
  criteria automation", "Given When Then", "regression suite". Enforces live navigation before
7
- writing any scenario and links generated files back to work items. Works with Epic, Feature,
7
+ writing any scenario and links generated files back to work items. Works with Feature,
8
8
  PBI, and Bug work item types.
9
9
  license: MIT
10
10
  compatibility: "Requires qa-gherkin-generator, qa-playwright-generator, qa-test-case-manager MCP servers and Playwright MCP running at localhost:8931 for live locator verification."
@@ -60,7 +60,7 @@ work items in ADO.**
60
60
 
61
61
  | ID type given by user | Goal | Fetch tool | Attach tool | Scope |
62
62
  |---|---|---|---|---|
63
- | **Epic ID** | Full regression suite across ALL child Features and their PBIs/Bugs | `fetch_epic_hierarchy` | `attach_gherkin_to_feature` (once per child Feature) | 5–10 scenarios per Feature |
63
+ | **Epic ID** | Not supported warn user | | | |
64
64
  | **Feature ID** | Full regression suite across all child PBIs | `fetch_feature_hierarchy` | `attach_gherkin_to_feature` | 5–10 scenarios |
65
65
  | **PBI or Bug ID** | Scoped file for that single story in the current sprint | `fetch_work_item_for_gherkin` | `attach_gherkin_to_work_item` | 3–9 scenarios |
66
66
 
@@ -68,15 +68,19 @@ work items in ADO.**
68
68
 
69
69
  ```
70
70
  if user_input contains an Epic ID:
71
- ALWAYS use fetch_epic_hierarchy (never fall through to fetch_feature_hierarchy)
72
- fetch_epic_hierarchy returns ALL child Features, their PBIs/Bugs, and all linked TCs
73
- analyse every Feature and every child PBI/Bug before generating any Gherkin
74
- generate one .feature file per child Feature (5–10 scenarios each)
75
- attach each via attach_gherkin_to_feature on the respective Feature ID
76
- → DO NOT create manual test cases (create_and_link_test_cases) for the Epic itself
77
- inform the user: "Test cases cannot be created for an Epic. They can only be
78
- created for PBIs, Bugs, or Features. Would you like me to create test cases for
79
- the individual child Features or PBIs instead?"
71
+ DO NOT call any fetch tool.
72
+ Respond immediately with:
73
+ "Epic-scoped Gherkin generation is not supported. An Epic spans multiple Features
74
+ and would produce files that are too large and unfocused to be useful as a
75
+ regression suite.
76
+
77
+ Please provide one of the following instead:
78
+ A Feature ID I will generate 5–10 scenarios covering all child PBIs
79
+ A PBI or Bug ID — I will generate 3–9 scenarios scoped to that work item
80
+
81
+ To find the child Features under this Epic, look up the work item in Azure DevOps
82
+ and note the Feature IDs, then share them with me."
83
+ → Wait for the user to provide a Feature or PBI/Bug ID. Do not proceed.
80
84
 
81
85
  if user_input contains a Feature ID:
82
86
  → use fetch_feature_hierarchy + attach_gherkin_to_feature
@@ -93,12 +97,6 @@ if ambiguous (no ID, just a title or description):
93
97
  → do not guess or default to either path
94
98
  ```
95
99
 
96
- When using the **Epic path**, `fetch_epic_hierarchy` returns a `features` list where each
97
- entry contains the Feature's metadata plus its `child_work_items` (PBIs/Bugs) and
98
- `existing_test_cases`. **Read every Feature and every child PBI/Bug in this list** before
99
- writing a single scenario — the full cross-Feature flow is the only correct input for an
100
- Epic-scope suite.
101
-
102
100
  When using the **PBI/Bug path**, `fetch_work_item_for_gherkin` returns `parent_feature`
103
101
  metadata. Use it for context when writing scenarios — but the generated file covers **only
104
102
  the PBI/Bug's own acceptance criteria**, not the full Feature. The file is attached to the
@@ -153,19 +151,6 @@ A single work item never tells the whole story.
153
151
 
154
152
  **1A — Route to the correct fetch tool (see Tool Routing above):**
155
153
 
156
- *Epic path (ALWAYS use when an Epic ID is provided):*
157
- ```
158
- qa-gherkin-generator:fetch_epic_hierarchy(
159
- epic_id : <Epic ID>
160
- organization_url : ...
161
- project_name : ...
162
- )
163
- ```
164
- Extract: epic title/description, **all child Features**, each Feature's child PBIs/Bugs
165
- with their ACs, and all existing test cases. Analyse the ENTIRE hierarchy — every Feature
166
- and every PBI/Bug — before writing a single scenario. Generate one .feature file per
167
- child Feature.
168
-
169
154
  *Feature path:*
170
155
  ```
171
156
  qa-gherkin-generator:fetch_feature_hierarchy(
@@ -197,15 +197,11 @@ that document — do not carry over the Gherkin attachment confirmation.
197
197
 
198
198
  ## Quality Gates — Do Not Attach Without These
199
199
 
200
- - [ ] Work item type identified — **correct tool-routing path selected** (Epic vs Feature vs PBI/Bug)
201
- - [ ] **Epic path**: `fetch_epic_hierarchy` called — NOT `fetch_feature_hierarchy` or `fetch_work_item_for_gherkin`
202
- - [ ] **Epic path**: ALL child Features and ALL child PBIs/Bugs read and analysed before any Gherkin written
203
- - [ ] **Epic path**: One .feature file generated per child Feature (not one file for the whole Epic)
204
- - [ ] **Epic path**: `create_and_link_test_cases` NOT called on the Epic ID — user informed that test cases are scoped to Features/PBIs/Bugs only
200
+ - [ ] Work item type identified — **correct tool-routing path selected** (Feature vs PBI/Bug)
205
201
  - [ ] **Feature path**: `fetch_feature_hierarchy` called — all child PBIs/Bugs reviewed
206
202
  - [ ] **Feature path**: User confirmation received before calling `create_and_link_test_cases`
207
203
  - [ ] **PBI/Bug path**: `fetch_work_item_for_gherkin` called — parent Feature context reviewed
208
- - [ ] Correct fetch tool called: `fetch_epic_hierarchy` for Epic, `fetch_feature_hierarchy` for Feature, `fetch_work_item_for_gherkin` for PBI/Bug
204
+ - [ ] Correct fetch tool called: `fetch_feature_hierarchy` for Feature, `fetch_work_item_for_gherkin` for PBI/Bug
209
205
  - [ ] Parent Feature hierarchy context reviewed — all active sibling PBIs/Bugs read and flow map built
210
206
  - [ ] Gap check (Step 2) completed — every G1–G7 gap type checked
211
207
  - [ ] **All gaps answered by user before any Gherkin was written** (or explicit sign-off obtained)
@@ -218,7 +218,15 @@ qa-playwright-generator:generate_playwright_code(
218
218
  )
219
219
  ```
220
220
 
221
- The tool produces four files:
221
+ The response contains `cache_key`, `files_manifest` (list of file paths), and `validation`. File
222
+ contents are held server-side to keep them out of conversation history. Retrieve them only when
223
+ you are about to attach or write to disk:
224
+
225
+ ```
226
+ qa-playwright-generator:get_generated_files(cache_key: "<cache_key from above>")
227
+ ```
228
+
229
+ The four generated files are:
222
230
  - `locators.ts` — selector registry with intent, stability score, visualIntent flag
223
231
  - `{ScreenName}Page.ts` — three-layer self-healing page object
224
232
  - `{feature}.steps.ts` — Cucumber step definitions
@@ -264,17 +272,21 @@ Note:
264
272
 
265
273
  **Do not call `attach_code_to_work_item` until the user replies "yes".**
266
274
 
267
- If user says "yes", call with delta files only:
275
+ If user says "yes", first retrieve the file contents then attach:
268
276
 
269
277
  ```
278
+ # 1 — Retrieve file contents from cache
279
+ qa-playwright-generator:get_generated_files(cache_key: "<cache_key>")
280
+
281
+ # 2 — Attach delta files only
270
282
  qa-playwright-generator:attach_code_to_work_item(
271
283
  organization_url : "<org_url>",
272
284
  project_name : "<project>",
273
285
  work_item_id : <id>,
274
286
  files : [
275
- { file_name: "locators.delta.ts", content: "..." },
276
- { file_name: "{ScreenName}Page.delta.ts", content: "..." },
277
- { file_name: "{feature}.steps.delta.ts", content: "..." }
287
+ { file_name: "locators.delta.ts", content: "<from get_generated_files>" },
288
+ { file_name: "{ScreenName}Page.delta.ts", content: "<from get_generated_files>" },
289
+ { file_name: "{feature}.steps.delta.ts", content: "<from get_generated_files>" }
278
290
  ]
279
291
  )
280
292
  ```
@@ -289,123 +301,8 @@ Helix-QA disk writes are a separate decision requiring a separate user request.
289
301
 
290
302
  ## Generated File Structures
291
303
 
292
- ### locators.ts
293
-
294
- ```typescript
295
- /**
296
- * Locators: <ScreenName>Page
297
- * SOURCE: Playwright MCP AX tree snapshot — <app-url>/<route>
298
- * Stability: data-testid(100) > role+name(90) > id(80) > aria-label(70) > placeholder(60)
299
- * ⚠ stability:0 entries were NOT reached in the live session — get user sign-off before using.
300
- */
301
- export const <ScreenName>Locators = {
302
- // stability: 100 — data-testid, survives refactors
303
- addUsersButton: {
304
- selector : "[data-testid='person_header-button-add_users']",
305
- intent : "Add Users button that opens the slide-out panel",
306
- stability : 100,
307
- },
308
- // stability: 90 — aria-role+name, visualIntent: screenshot at assertions
309
- exportListButton: {
310
- selector : "button:has-text('Export List')",
311
- intent : "Export List button on the failure summary screen",
312
- stability : 90,
313
- visualIntent : true,
314
- },
315
- // ⚠ stability: 0 — NOT VERIFIED: could not reach this screen (reason: <why>)
316
- // Get user sign-off before using in automation.
317
- someUnreachedElement: {
318
- selector : "[data-testid='TODO']",
319
- intent : "...",
320
- stability : 0,
321
- },
322
- } as const;
323
-
324
- export type LocatorKey = keyof typeof <ScreenName>Locators;
325
- ```
326
-
327
- ### {ScreenName}Page.ts
328
-
329
- ```typescript
330
- import { Page, expect, Download } from '@playwright/test';
331
- import { fixture } from '@hooks/pageFixture';
332
- import { <ScreenName>Locators } from './locators';
333
- import { LocatorHealer } from '@utils/locators/LocatorHealer';
334
- import { LocatorRepository } from '@utils/locators/LocatorRepository';
335
- import { VisualIntentChecker } from '@utils/locators/VisualIntentChecker';
336
- import { TimingHealer } from '@utils/locators/TimingHealer';
337
-
338
- /**
339
- * <ScreenName>Page — Three-Layer Self-Healing Page Object
340
- * Layer 1 (LocatorHealer): primary → role → label → text → AI Vision → AX tree
341
- * Layer 2 (TimingHealer): network-trace drift → auto-adjusted timeouts
342
- * Layer 3 (VisualIntentChecker): element screenshot diff at key assertions
343
- * HealingDashboard: http://localhost:7890
344
- * RULE: Never use page.click / page.fill / page.locator directly.
345
- */
346
- export default class <ScreenName>Page {
347
- private readonly loc = <ScreenName>Locators;
348
- private readonly page: Page;
349
- private readonly healer: LocatorHealer;
350
- private readonly repo: LocatorRepository;
351
- private readonly visual: VisualIntentChecker;
352
- private readonly timing: TimingHealer;
353
-
354
- constructor(page?: Page) {
355
- this.page = page ?? fixture().page;
356
- this.repo = fixture().locatorRepository ?? new LocatorRepository();
357
- this.healer = new LocatorHealer(this.page, fixture().logger, this.repo);
358
- this.visual = new VisualIntentChecker(this.page, fixture().logger, this.repo);
359
- this.timing = new TimingHealer(this.page, fixture().logger, this.repo);
360
- Object.entries(this.loc).forEach(([k, v]) => this.repo.register(k, v.selector, v.intent));
361
- }
362
-
363
- async login(email: string, password: string): Promise<void> {
364
- await this.page.goto(process.env.APP_BASE_URL!, { waitUntil: 'networkidle' });
365
- await this.healer.fillWithHealing('emailInput', this.loc.emailInput.selector, email, this.loc.emailInput.intent);
366
- await this.healer.fillWithHealing('passwordInput', this.loc.passwordInput.selector, password, this.loc.passwordInput.intent);
367
- await this.healer.clickWithHealing('loginButton', this.loc.loginButton.selector, this.loc.loginButton.intent);
368
- await this.timing.waitForNetworkIdle('login');
369
- }
370
-
371
- // All interactions go through LocatorHealer — never raw page.click / page.fill
372
- }
373
- ```
374
-
375
- ### {feature}.steps.ts
376
-
377
- ```typescript
378
- import { Given, When, Then, Before } from '@cucumber/cucumber';
379
- import { expect } from '@playwright/test';
380
- import { fixture } from '@hooks/pageFixture';
381
- import <ScreenName>Page from '@pages/<screenName>/<ScreenName>Page';
382
-
383
- let page_: <ScreenName>Page;
384
-
385
- Before(async () => { page_ = new <ScreenName>Page(fixture().page); });
386
-
387
- Given('I am logged in to {word} as {string}', async (_app: string, email: string) => {
388
- await page_.login(email, process.env.APP_PASSWORD!);
389
- });
390
-
391
- // Only net-new steps — never re-register steps already in existing files
392
- ```
393
-
394
- ---
395
-
396
- ## Run Commands
397
-
398
- ```bash
399
- ENABLE_SELF_HEALING=true \
400
- HEALING_DASHBOARD_PORT=7890 \
401
- APP_BASE_URL=https://account.myamplify.io \
402
- APP_EMAIL=<email> \
403
- APP_PASSWORD=<password> \
404
- cucumber-js --config=config/cucumber.js -p <feature_profile>
405
-
406
- # Smoke only:
407
- cucumber-js --config=config/cucumber.js -p <feature_profile> --tags "@smoke"
408
- ```
304
+ For TypeScript code templates and run commands, see
305
+ [references/file-structures.md](references/file-structures.md).
409
306
 
410
307
  ---
411
308
 
@@ -0,0 +1,128 @@
1
+ # Generated File Structures — Reference
2
+
3
+ Read this file when you need to understand the exact TypeScript output format or
4
+ run commands. It is not loaded into context automatically.
5
+
6
+ ---
7
+
8
+ ## locators.ts
9
+
10
+ ```typescript
11
+ /**
12
+ * Locators: <ScreenName>Page
13
+ * SOURCE: Playwright MCP AX tree snapshot — <app-url>/<route>
14
+ * Stability: data-testid(100) > role+name(90) > id(80) > aria-label(70) > placeholder(60)
15
+ * ⚠ stability:0 entries were NOT reached in the live session — get user sign-off before using.
16
+ */
17
+ export const <ScreenName>Locators = {
18
+ // stability: 100 — data-testid, survives refactors
19
+ addUsersButton: {
20
+ selector : "[data-testid='person_header-button-add_users']",
21
+ intent : "Add Users button that opens the slide-out panel",
22
+ stability : 100,
23
+ },
24
+ // stability: 90 — aria-role+name, visualIntent: screenshot at assertions
25
+ exportListButton: {
26
+ selector : "button:has-text('Export List')",
27
+ intent : "Export List button on the failure summary screen",
28
+ stability : 90,
29
+ visualIntent : true,
30
+ },
31
+ // ⚠ stability: 0 — NOT VERIFIED: could not reach this screen (reason: <why>)
32
+ // Get user sign-off before using in automation.
33
+ someUnreachedElement: {
34
+ selector : "[data-testid='TODO']",
35
+ intent : "...",
36
+ stability : 0,
37
+ },
38
+ } as const;
39
+
40
+ export type LocatorKey = keyof typeof <ScreenName>Locators;
41
+ ```
42
+
43
+ ---
44
+
45
+ ## {ScreenName}Page.ts
46
+
47
+ ```typescript
48
+ import { Page, expect, Download } from '@playwright/test';
49
+ import { fixture } from '@hooks/pageFixture';
50
+ import { <ScreenName>Locators } from './locators';
51
+ import { LocatorHealer } from '@utils/locators/LocatorHealer';
52
+ import { LocatorRepository } from '@utils/locators/LocatorRepository';
53
+ import { VisualIntentChecker } from '@utils/locators/VisualIntentChecker';
54
+ import { TimingHealer } from '@utils/locators/TimingHealer';
55
+
56
+ /**
57
+ * <ScreenName>Page — Three-Layer Self-Healing Page Object
58
+ * Layer 1 (LocatorHealer): primary → role → label → text → AI Vision → AX tree
59
+ * Layer 2 (TimingHealer): network-trace drift → auto-adjusted timeouts
60
+ * Layer 3 (VisualIntentChecker): element screenshot diff at key assertions
61
+ * HealingDashboard: http://localhost:7890
62
+ * RULE: Never use page.click / page.fill / page.locator directly.
63
+ */
64
+ export default class <ScreenName>Page {
65
+ private readonly loc = <ScreenName>Locators;
66
+ private readonly page: Page;
67
+ private readonly healer: LocatorHealer;
68
+ private readonly repo: LocatorRepository;
69
+ private readonly visual: VisualIntentChecker;
70
+ private readonly timing: TimingHealer;
71
+
72
+ constructor(page?: Page) {
73
+ this.page = page ?? fixture().page;
74
+ this.repo = fixture().locatorRepository ?? new LocatorRepository();
75
+ this.healer = new LocatorHealer(this.page, fixture().logger, this.repo);
76
+ this.visual = new VisualIntentChecker(this.page, fixture().logger, this.repo);
77
+ this.timing = new TimingHealer(this.page, fixture().logger, this.repo);
78
+ Object.entries(this.loc).forEach(([k, v]) => this.repo.register(k, v.selector, v.intent));
79
+ }
80
+
81
+ async login(email: string, password: string): Promise<void> {
82
+ await this.page.goto(process.env.APP_BASE_URL!, { waitUntil: 'networkidle' });
83
+ await this.healer.fillWithHealing('emailInput', this.loc.emailInput.selector, email, this.loc.emailInput.intent);
84
+ await this.healer.fillWithHealing('passwordInput', this.loc.passwordInput.selector, password, this.loc.passwordInput.intent);
85
+ await this.healer.clickWithHealing('loginButton', this.loc.loginButton.selector, this.loc.loginButton.intent);
86
+ await this.timing.waitForNetworkIdle('login');
87
+ }
88
+
89
+ // All interactions go through LocatorHealer — never raw page.click / page.fill
90
+ }
91
+ ```
92
+
93
+ ---
94
+
95
+ ## {feature}.steps.ts
96
+
97
+ ```typescript
98
+ import { Given, When, Then, Before } from '@cucumber/cucumber';
99
+ import { expect } from '@playwright/test';
100
+ import { fixture } from '@hooks/pageFixture';
101
+ import <ScreenName>Page from '@pages/<screenName>/<ScreenName>Page';
102
+
103
+ let page_: <ScreenName>Page;
104
+
105
+ Before(async () => { page_ = new <ScreenName>Page(fixture().page); });
106
+
107
+ Given('I am logged in to {word} as {string}', async (_app: string, email: string) => {
108
+ await page_.login(email, process.env.APP_PASSWORD!);
109
+ });
110
+
111
+ // Only net-new steps — never re-register steps already in existing files
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Run Commands
117
+
118
+ ```bash
119
+ ENABLE_SELF_HEALING=true \
120
+ HEALING_DASHBOARD_PORT=7890 \
121
+ APP_BASE_URL=https://account.myamplify.io \
122
+ APP_EMAIL=<email> \
123
+ APP_PASSWORD=<password> \
124
+ cucumber-js --config=config/cucumber.js -p <feature_profile>
125
+
126
+ # Smoke only:
127
+ cucumber-js --config=config/cucumber.js -p <feature_profile> --tags "@smoke"
128
+ ```
@@ -35,8 +35,8 @@ If the user provides an Epic ID and asks for test cases:
35
35
  - Inform the user explicitly:
36
36
  > "Manual test cases cannot be created or linked to an Epic in ADO.
37
37
  > Test cases must be attached to individual Features, PBIs, or Bugs.
38
- > Would you like me to use `fetch_epic_hierarchy` to identify the child Features
39
- > and PBIs/Bugs, then create test cases for those instead?"
38
+ > Please look up the child Features of this Epic in Azure DevOps, then share
39
+ > the Feature or PBI/Bug IDs and I will create test cases for each."
40
40
  - Do NOT call `create_and_link_test_cases` with an Epic ID under any circumstances.
41
41
 
42
42
  **HARD STOP 2 — Always ask for user confirmation before creating test cases for a Feature.**
@@ -200,10 +200,18 @@ qa-playwright-generator:generate_playwright_code(
200
200
 
201
201
  ### Step 6 — Write files
202
202
 
203
+ First retrieve the file contents from the playwright generator's cache:
204
+
205
+ ```
206
+ qa-playwright-generator:get_generated_files(cache_key: "<cache_key from Step 5>")
207
+ ```
208
+
209
+ Then write to Helix:
210
+
203
211
  ```
204
212
  qa-helix-writer:write_helix_files(
205
213
  helix_root = "<helix_root>",
206
- files = <files dict from generate_playwright_code>,
214
+ files = <files dict from get_generated_files>,
207
215
  mode = "<recommendation from Step 2>"
208
216
  )
209
217
  ```
@@ -318,8 +326,9 @@ Before calling `write_helix_files`:
318
326
  - [ ] Every `*.steps.ts` in the `files` dict uses Cucumber expression syntax (not regex).
319
327
  - [ ] `mode` matches `recommendation` — never override without user instruction.
320
328
  - [ ] `force_scaffold` is `false` unless the user explicitly asked to regenerate.
321
- - [ ] The `files` dict comes directly from `generate_playwright_code` or
322
- `scaffold_locator_repository` never manually constructed.
329
+ - [ ] The `files` dict comes from `get_generated_files(cache_key)` — never manually
330
+ constructed. `generate_playwright_code` and `scaffold_locator_repository` return
331
+ a `cache_key`; call `get_generated_files` to retrieve file contents.
323
332
  - [ ] After writing, the `deduplication` field has been reviewed and reported.
324
333
 
325
334
  ---