@qa-gentic/stlc-agents 1.0.5 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +175 -34
- package/bin/postinstall.js +125 -44
- package/bin/qa-stlc.js +15 -8
- package/package.json +2 -2
- package/skills/{qa-stlc/AGENT-BEHAVIOR.md → AGENT-BEHAVIOR.md} +7 -6
- package/{.github/copilot-instructions/deduplication-protocol.md → skills/deduplication-protocol/SKILL.md} +16 -21
- package/skills/generate-gherkin/SKILL.md +287 -0
- package/skills/generate-gherkin/references/step-by-step.md +267 -0
- package/skills/{qa-stlc/generate-playwright-code.md → generate-playwright-code/SKILL.md} +13 -23
- package/{.github/copilot-instructions/generate-test-cases.md → skills/generate-test-cases/SKILL.md} +16 -2
- package/skills/qa-jira-manager/SKILL.md +287 -0
- package/{.github/copilot-instructions/write-helix-files.md → skills/write-helix-files/SKILL.md} +11 -17
- package/src/{boilerplate-bundle.js → cli/boilerplate-bundle.js} +8 -8
- package/src/cli/cmd-init.js +145 -0
- package/src/{cmd-mcp-config.js → cli/cmd-mcp-config.js} +72 -9
- package/src/cli/cmd-skills.js +209 -0
- package/src/{cmd-verify.js → cli/cmd-verify.js} +35 -3
- package/src/cli/prompt-integration.js +87 -0
- package/src/stlc_agents/agent_helix_writer/tools/boilerplate.py +8 -8
- package/src/stlc_agents/agent_jira_manager/__init__.py +0 -0
- package/src/stlc_agents/agent_jira_manager/server.py +500 -0
- package/src/stlc_agents/agent_jira_manager/tools/__init__.py +0 -0
- package/src/stlc_agents/agent_jira_manager/tools/jira_workitem.py +467 -0
- package/src/stlc_agents/shared_jira/__init__.py +0 -0
- package/src/stlc_agents/shared_jira/auth.py +270 -0
- package/.github/copilot-instructions/AGENT-BEHAVIOR.md +0 -448
- package/.github/copilot-instructions/generate-gherkin.md +0 -550
- package/.github/copilot-instructions/generate-playwright-code.md +0 -464
- package/skills/qa-stlc/deduplication-protocol.md +0 -303
- package/skills/qa-stlc/generate-gherkin.md +0 -550
- package/skills/qa-stlc/generate-test-cases.md +0 -176
- package/skills/qa-stlc/write-helix-files.md +0 -374
- package/src/cmd-init.js +0 -92
- package/src/cmd-skills.js +0 -124
- /package/src/{cmd-scaffold.js → cli/cmd-scaffold.js} +0 -0
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
# Skill: Generate Test Cases from Azure DevOps Work Item
|
|
2
|
-
|
|
3
|
-
> **Read `AGENT-BEHAVIOR.md` before this skill.** The behavior rules there override any
|
|
4
|
-
> inference. This skill provides the step-by-step workflow only.
|
|
5
|
-
|
|
6
|
-
Use this skill when asked to generate, create, or write test cases for an Azure DevOps
|
|
7
|
-
PBI, Bug, User Story, or Feature.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## 🚨 HARD STOP RULES — Read Before Anything Else
|
|
12
|
-
|
|
13
|
-
**HARD STOP 0 — Never infer delivery destination.**
|
|
14
|
-
Generating test cases ≠ creating them in ADO. Show the user what you plan to create.
|
|
15
|
-
Get explicit confirmation. Do not auto-submit.
|
|
16
|
-
|
|
17
|
-
**HARD STOP 1 — Never create test cases for an Epic.**
|
|
18
|
-
Test cases in ADO are always scoped to PBIs, Bugs, or Features — never to Epics.
|
|
19
|
-
If the user provides an Epic ID and asks for test cases:
|
|
20
|
-
- Call `fetch_work_item` with the Epic ID — the tool will return `"error": "epic_not_supported"`.
|
|
21
|
-
- Inform the user explicitly:
|
|
22
|
-
> "Manual test cases cannot be created or linked to an Epic in ADO.
|
|
23
|
-
> Test cases must be attached to individual Features, PBIs, or Bugs.
|
|
24
|
-
> Would you like me to use `fetch_epic_hierarchy` to identify the child Features
|
|
25
|
-
> and PBIs/Bugs, then create test cases for those instead?"
|
|
26
|
-
- Do NOT call `create_and_link_test_cases` with an Epic ID under any circumstances.
|
|
27
|
-
|
|
28
|
-
**HARD STOP 2 — Always ask for user confirmation before creating test cases for a Feature.**
|
|
29
|
-
When the target work item is a Feature, the server will return `"confirmation_required": true`.
|
|
30
|
-
At that point, **stop and ask the user**:
|
|
31
|
-
> "I'm about to create {N} manual test case(s) linked to Feature #{id} — "{title}".
|
|
32
|
-
> Please confirm (yes / no) before I proceed."
|
|
33
|
-
Do not call `create_and_link_test_cases` again until the user replies affirmatively.
|
|
34
|
-
If the user replies 'no' or 'cancel', abort and inform them no test cases were created.
|
|
35
|
-
|
|
36
|
-
## ⛔ Mandatory Pre-Flight: Deduplication Protocol
|
|
37
|
-
|
|
38
|
-
Before executing any step below, run the deduplication protocol:
|
|
39
|
-
`skills/deduplication-protocol.md`
|
|
40
|
-
|
|
41
|
-
The protocol is **work-item-scoped**: PHASE 1 runs once per `work_item_id` and its results
|
|
42
|
-
are cached. If this skill is invoked for the same `work_item_id` that another agent already
|
|
43
|
-
processed, skip PHASE 1 and read from `CACHE[work_item_id]` directly.
|
|
44
|
-
A different `work_item_id` always triggers a fresh PHASE 1.
|
|
45
|
-
|
|
46
|
-
---
|
|
47
|
-
|
|
48
|
-
## Steps
|
|
49
|
-
|
|
50
|
-
### Step 1 — Fetch the work item and existing test cases
|
|
51
|
-
|
|
52
|
-
**1A — Fetch the work item:**
|
|
53
|
-
Call `fetch_work_item` with the work item ID, organization URL, and project name.
|
|
54
|
-
|
|
55
|
-
The response contains:
|
|
56
|
-
- `work_item` — title, acceptance_criteria, description, repro_steps (for Bugs), story_points, priority, area_path, iteration_path
|
|
57
|
-
- `parent_feature` — parent Feature if present
|
|
58
|
-
- `existing_test_cases_count` — count of already-linked test cases (use as a signal only)
|
|
59
|
-
- `coverage_hints` — keys derived from AC text flagging areas that need coverage
|
|
60
|
-
|
|
61
|
-
**1B — Fetch existing test case titles (always, before generating):**
|
|
62
|
-
`existing_test_cases_count` is a count, not the actual titles. Two concurrent runs against the
|
|
63
|
-
same work item will duplicate test cases unless you fetch the real titles first.
|
|
64
|
-
|
|
65
|
-
```
|
|
66
|
-
qa-test-case-manager:get_linked_test_cases(
|
|
67
|
-
organization_url : ...
|
|
68
|
-
project_name : ...
|
|
69
|
-
work_item_id : <same ID>
|
|
70
|
-
)
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
The response contains a `linked_test_cases` list with `id`, `title`, `state`, `priority`.
|
|
74
|
-
**Skip any test case whose title (or a near-identical paraphrase) already exists in this list.**
|
|
75
|
-
If `existing_test_cases_count` is 0 you may skip the call.
|
|
76
|
-
|
|
77
|
-
### Step 2 — Determine complexity
|
|
78
|
-
Use `story_points` and the count of distinct acceptance criteria:
|
|
79
|
-
- **Simple** (3–6 TCs): ≤ 2 points or ≤ 2 AC items
|
|
80
|
-
- **Medium** (6–12 TCs): 3–5 points or 3–5 AC items
|
|
81
|
-
- **Complex** (12–18 TCs): > 5 points or > 5 AC items
|
|
82
|
-
|
|
83
|
-
Add +1 TC for each `coverage_hint` not already addressed.
|
|
84
|
-
|
|
85
|
-
### Step 3 — Apply the granularity rule
|
|
86
|
-
Ask: "Does this step naturally flow into the next as part of one user journey?" If yes,
|
|
87
|
-
merge into ONE test case with multiple steps. Avoid micro-interaction test cases.
|
|
88
|
-
|
|
89
|
-
- ✗ BAD: TC="Slide-out opens", TC="File picker appears"
|
|
90
|
-
- ✓ GOOD: TC="User opens profile and initiates photo update" (multi-step)
|
|
91
|
-
|
|
92
|
-
### Step 4 — Design test cases covering all applicable categories
|
|
93
|
-
|
|
94
|
-
| Category | Description |
|
|
95
|
-
|---|---|
|
|
96
|
-
| Happy paths | Successful end-to-end flows |
|
|
97
|
-
| Success feedback | Toast/confirmation messages after success |
|
|
98
|
-
| Post-action state | UI reflects the change (photo displayed, count updated) |
|
|
99
|
-
| Validation errors | Invalid input, wrong format, missing required fields |
|
|
100
|
-
| Boundary conditions | Test AT the exact limit stated in ACs (exactly 5 MB, not 4 MB or 6 MB) |
|
|
101
|
-
| Edge cases | Empty state, default state, fallback display (initials avatar) |
|
|
102
|
-
| Negative scenarios | Failure states, error toasts, state unchanged after failure |
|
|
103
|
-
| Data persistence | Data survives page refresh or re-login |
|
|
104
|
-
| Computed/derived state | Values derived from other fields update correctly |
|
|
105
|
-
| Platform-specific | Mobile/webview scenarios when mentioned in ACs |
|
|
106
|
-
| Cancel flows | Cancel/discard discards changes without saving |
|
|
107
|
-
|
|
108
|
-
Apply every hint in `coverage_hints`. Skip titles already in the `linked_test_cases` list from Step 1B.
|
|
109
|
-
|
|
110
|
-
### Step 4B — Delivery gate (mandatory — do not skip)
|
|
111
|
-
|
|
112
|
-
Before calling `create_and_link_test_cases`, present the following to the user and wait:
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
I've designed {N} test cases for work item #{id} — "{title}".
|
|
116
|
-
|
|
117
|
-
Here is the list:
|
|
118
|
-
1. {TC title}
|
|
119
|
-
2. {TC title}
|
|
120
|
-
...
|
|
121
|
-
|
|
122
|
-
**Do you want me to create these in ADO now? (yes / no)**
|
|
123
|
-
|
|
124
|
-
Note:
|
|
125
|
-
- Saying yes here only creates test cases — it does not generate Gherkin or Playwright code.
|
|
126
|
-
- If you also want Gherkin or Playwright code, say so separately.
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
**Do not call `create_and_link_test_cases` until the user replies "yes".**
|
|
130
|
-
**Do not carry this confirmation forward to any other artifact.**
|
|
131
|
-
|
|
132
|
-
### Step 5 — Create and link
|
|
133
|
-
Call `create_and_link_test_cases` with your test cases. Do NOT specify `area_path` —
|
|
134
|
-
it is automatically inherited from the parent work item.
|
|
135
|
-
|
|
136
|
-
Each test case:
|
|
137
|
-
- `title` — clear, specific, describes what is being tested
|
|
138
|
-
- `steps` — array of `{ action, expected_result }` — at least 2 steps per TC
|
|
139
|
-
- `priority` — 1=Critical, 2=High (default), 3=Medium, 4=Low
|
|
140
|
-
|
|
141
|
-
## Example tool call
|
|
142
|
-
|
|
143
|
-
```json
|
|
144
|
-
{
|
|
145
|
-
"work_item_id": 12345,
|
|
146
|
-
"organization_url": "https://dev.azure.com/myorg",
|
|
147
|
-
"project_name": "MyProject",
|
|
148
|
-
"test_cases": [
|
|
149
|
-
{
|
|
150
|
-
"title": "TC_12345_01 — User uploads valid profile photo and sees success confirmation",
|
|
151
|
-
"priority": 2,
|
|
152
|
-
"steps": [
|
|
153
|
-
{"action": "Navigate to My Profile slide-out", "expected_result": "Profile section opens showing current photo or initials"},
|
|
154
|
-
{"action": "Click Update Photo and select a valid JPG file under 5 MB", "expected_result": "Image preview is shown in the crop editor"},
|
|
155
|
-
{"action": "Adjust crop area and click Save", "expected_result": "Success toast 'Profile photo updated' is displayed and photo appears in the header"}
|
|
156
|
-
]
|
|
157
|
-
}
|
|
158
|
-
]
|
|
159
|
-
}
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## Explicit Delivery Rules — No Inference
|
|
165
|
-
|
|
166
|
-
| Decision | Rule |
|
|
167
|
-
|---|---|
|
|
168
|
-
| Generate test cases | Always: show the proposed list first |
|
|
169
|
-
| Create in ADO | Requires explicit "yes" at Step 4B gate |
|
|
170
|
-
| User says "no" at gate | Abort; report "No test cases created" |
|
|
171
|
-
| User confirms Feature test cases | Separate confirmation at HARD STOP 2 — not carried from Step 4B |
|
|
172
|
-
| Generate Gherkin next | Must be a separate user request — not triggered by this skill |
|
|
173
|
-
| Generate Playwright next | Must be a separate user request — not triggered by this skill |
|
|
174
|
-
| Save locally | Only if user explicitly says "save" or "download" |
|
|
175
|
-
|
|
176
|
-
**Each artifact delivery is independent. A yes/no for one does not answer any other.**
|
|
@@ -1,374 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: write-helix-files
|
|
3
|
-
description: >
|
|
4
|
-
Use this skill whenever generated Playwright TypeScript files (locators,
|
|
5
|
-
page objects, step definitions, feature files, healing infrastructure) need
|
|
6
|
-
to be placed into a local Helix-QA project on disk. Triggers after
|
|
7
|
-
generate-playwright-code or scaffold_locator_repository has produced a
|
|
8
|
-
'files' dict. Always calls inspect_helix_project first to determine whether
|
|
9
|
-
the framework exists, then picks the correct write mode automatically.
|
|
10
|
-
compatibility:
|
|
11
|
-
tools:
|
|
12
|
-
- qa-helix-writer:inspect_helix_project
|
|
13
|
-
- qa-helix-writer:list_helix_tree
|
|
14
|
-
- qa-helix-writer:read_helix_file
|
|
15
|
-
- qa-helix-writer:write_helix_files
|
|
16
|
-
- qa-helix-writer:update_helix_file
|
|
17
|
-
- qa-playwright-generator:generate_playwright_code
|
|
18
|
-
- qa-playwright-generator:scaffold_locator_repository
|
|
19
|
-
- qa-playwright-generator:pre_validate_cucumber_steps
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
# Write Helix Files Skill
|
|
23
|
-
|
|
24
|
-
## 🚨 HARD STOP RULES — Read Before Anything Else
|
|
25
|
-
|
|
26
|
-
**HARD STOP 1 — NEVER use `create_file` as a fallback.**
|
|
27
|
-
`create_file` bypasses deduplication, interface-adaptation rewrites, and file routing.
|
|
28
|
-
If `write_helix_files` returns an error, diagnose and fix the payload — do NOT route
|
|
29
|
-
around the tool. If the error cannot be resolved, surface it to the user verbatim.
|
|
30
|
-
|
|
31
|
-
**HARD STOP 2 — NEVER create a new locator or step file when one already exists.**
|
|
32
|
-
Before writing, call `list_helix_tree` to check what files are already on disk.
|
|
33
|
-
If `src/locators/<foo>.locators.ts` already exists → it is the only correct target.
|
|
34
|
-
Do NOT create `src/locators/<foo>-bar.locators.ts` or any variant filename.
|
|
35
|
-
`write_helix_files` will merge new keys into the existing file automatically.
|
|
36
|
-
|
|
37
|
-
**HARD STOP 3 — Step definitions MUST use Cucumber expressions, not regex.**
|
|
38
|
-
`write_helix_files` runs a parenthesis-balance validator on every `*.steps.ts` file.
|
|
39
|
-
Regex step patterns (e.g. `/^I click "([^"]*)"$/`) contain un-paired parentheses and
|
|
40
|
-
will fail this check. Before submitting, verify every `When/Then/Given` block matches
|
|
41
|
-
the Cucumber expression format:
|
|
42
|
-
|
|
43
|
-
```typescript
|
|
44
|
-
// ✅ Correct — Cucumber expression
|
|
45
|
-
When('the user enters {string} in the username field', async function (value: string) {
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
```typescript
|
|
49
|
-
// ❌ Rejected — regex pattern
|
|
50
|
-
When(/^the user enters "([^"]*)" in the username field$/, async function (value: string) {
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
If `generate_playwright_code` produced regex patterns, use `pre_validate_cucumber_steps`
|
|
54
|
-
to identify them, then convert to Cucumber expressions before calling `write_helix_files`.
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
Place files produced by `qa-playwright-generator` into a local Helix-QA
|
|
59
|
-
project. The skill handles two situations automatically:
|
|
60
|
-
|
|
61
|
-
| Situation | What happens |
|
|
62
|
-
|---|---|
|
|
63
|
-
| Framework does not exist yet | Scaffold infrastructure + write test files |
|
|
64
|
-
| Framework already exists | Merge only the new work item's test files; never touch infrastructure |
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Helix-QA Directory Layout
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
<helix_root>/
|
|
72
|
-
├── src/
|
|
73
|
-
│ ├── locators/ ← <kebab>.locators.ts (merged per file)
|
|
74
|
-
│ ├── pages/ ← <Page>.page.ts (merged per file)
|
|
75
|
-
│ ├── test/
|
|
76
|
-
│ │ ├── features/ ← <feature>.feature (overwritten)
|
|
77
|
-
│ │ └── steps/ ← <feature>.steps.ts (merged per file)
|
|
78
|
-
│ ├── utils/
|
|
79
|
-
│ │ └── locators/ ← LocatorHealer.ts etc. (protected)
|
|
80
|
-
│ └── config/
|
|
81
|
-
│ └── cucumber.config.ts ← profile blocks appended (deduplicated)
|
|
82
|
-
└── package.json
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
---
|
|
86
|
-
|
|
87
|
-
## Decision Flow
|
|
88
|
-
|
|
89
|
-
```
|
|
90
|
-
inspect_helix_project(helix_root)
|
|
91
|
-
│
|
|
92
|
-
├─ framework_state: "absent" or "partial"
|
|
93
|
-
│ │
|
|
94
|
-
│ └─ scaffold_locator_repository(...)
|
|
95
|
-
│ │
|
|
96
|
-
│ └─ write_helix_files(..., mode="scaffold_and_tests")
|
|
97
|
-
│ Writes infra files that don't exist + test files
|
|
98
|
-
│
|
|
99
|
-
└─ framework_state: "present"
|
|
100
|
-
│
|
|
101
|
-
└─ write_helix_files(..., mode="tests_only")
|
|
102
|
-
Merges only locators / page / steps / feature
|
|
103
|
-
Infrastructure files are NEVER touched
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
---
|
|
107
|
-
|
|
108
|
-
## Step-by-Step Workflow
|
|
109
|
-
|
|
110
|
-
### Step 1 — Confirm helix_root
|
|
111
|
-
|
|
112
|
-
Ask the user for the absolute path to the Helix-QA project root if not provided.
|
|
113
|
-
This is the directory containing `package.json` and `src/`.
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
### Step 2 — Inspect framework state
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
qa-helix-writer:inspect_helix_project(helix_root)
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
Read the response:
|
|
124
|
-
|
|
125
|
-
```json
|
|
126
|
-
{
|
|
127
|
-
"framework_state": "present",
|
|
128
|
-
"existing_infra": ["LocatorHealer.ts", "LocatorRepository.ts", ...],
|
|
129
|
-
"missing_infra": [],
|
|
130
|
-
"recommendation": "tests_only",
|
|
131
|
-
"message": "Helix-QA framework is present. ..."
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
**Act on `recommendation` directly — do not ask the user to choose the mode.**
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
### Step 3A — Framework absent or partial → scaffold first
|
|
140
|
-
|
|
141
|
-
Only when `recommendation` is `"scaffold_and_tests"`:
|
|
142
|
-
|
|
143
|
-
```
|
|
144
|
-
# Generate infrastructure
|
|
145
|
-
qa-playwright-generator:scaffold_locator_repository(
|
|
146
|
-
output_dir = "src/utils/locators",
|
|
147
|
-
enable_ai_vision = true,
|
|
148
|
-
repository_path = "test-results/locator-repository.json",
|
|
149
|
-
dashboard_port = 7890,
|
|
150
|
-
enable_timing_healing = true,
|
|
151
|
-
enable_visual_regression = true,
|
|
152
|
-
enable_devtools_healer = true
|
|
153
|
-
)
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
Then proceed to Step 4 with `mode="scaffold_and_tests"`.
|
|
157
|
-
|
|
158
|
-
---
|
|
159
|
-
|
|
160
|
-
### Step 3B — Framework present → skip scaffold
|
|
161
|
-
|
|
162
|
-
When `recommendation` is `"tests_only"`, skip Step 3A entirely.
|
|
163
|
-
Proceed to Step 4 with `mode="tests_only"`.
|
|
164
|
-
|
|
165
|
-
---
|
|
166
|
-
|
|
167
|
-
### Step 4 — Read existing feature file before generating
|
|
168
|
-
|
|
169
|
-
**MANDATORY before calling `generate_playwright_code`.**
|
|
170
|
-
|
|
171
|
-
If a `.feature` file already exists on disk for this work item, read it first:
|
|
172
|
-
|
|
173
|
-
```
|
|
174
|
-
qa-helix-writer:read_helix_file(
|
|
175
|
-
helix_root = "<helix_root>",
|
|
176
|
-
relative_path = "src/test/features/<feature>.feature"
|
|
177
|
-
)
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
If `exists: true`, extract the following from the response and pass as generation context:
|
|
181
|
-
|
|
182
|
-
1. **Existing scenario titles** — the generator MUST use these verbatim for any scenario it generates that covers the same test intent. Never produce a title that differs only by a word ("all 6" vs "all available") — that creates a phantom duplicate.
|
|
183
|
-
2. **Existing step phrasings** — for steps the generator would otherwise write in a slightly different form (e.g. `the user logs in with "X" and "Y"` vs `the user logs in with username "X" and password "Y"`), use the existing phrasing exactly. Semantic equivalence is not enough; step text must match character-for-character for deduplication to work.
|
|
184
|
-
3. **Scenarios to skip** — if the generator would produce a scenario whose steps are semantically equivalent to an existing one (same action, same data, same assertions — just different wording), omit it entirely from the generated output. Do not generate it at all; the helix writer cannot perform semantic reasoning.
|
|
185
|
-
|
|
186
|
-
If `exists: false`, skip this step — the file will be created fresh.
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
### Step 5 — Generate test files
|
|
191
|
-
|
|
192
|
-
Run `generate_playwright_code` for the work item's Gherkin feature:
|
|
193
|
-
|
|
194
|
-
```
|
|
195
|
-
qa-playwright-generator:generate_playwright_code(
|
|
196
|
-
gherkin_content = <validated .feature file content>,
|
|
197
|
-
page_class_name = "<PageClass>",
|
|
198
|
-
app_name = "<app>",
|
|
199
|
-
healing_strategy = "role-label-text-ai",
|
|
200
|
-
enable_visual_regression = true,
|
|
201
|
-
enable_timing_healing = true
|
|
202
|
-
)
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
---
|
|
206
|
-
|
|
207
|
-
### Step 6 — Write files
|
|
208
|
-
|
|
209
|
-
```
|
|
210
|
-
qa-helix-writer:write_helix_files(
|
|
211
|
-
helix_root = "<helix_root>",
|
|
212
|
-
files = <files dict from generate_playwright_code>,
|
|
213
|
-
mode = "<recommendation from Step 2>"
|
|
214
|
-
)
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
The tool handles everything automatically:
|
|
218
|
-
|
|
219
|
-
**File routing:**
|
|
220
|
-
|
|
221
|
-
| Generator key | Helix destination |
|
|
222
|
-
|---|---|
|
|
223
|
-
| `src/pages/<k>/locators.ts` | `src/locators/<k>.locators.ts` |
|
|
224
|
-
| `src/pages/<k>/<k>.page.ts` | `src/pages/<k>.page.ts` |
|
|
225
|
-
| `src/test/steps/<k>.steps.ts` | `src/test/steps/<k>.steps.ts` |
|
|
226
|
-
| `*.feature` | `src/test/features/<k>.feature` |
|
|
227
|
-
| `config/cucumber.js (add this profile)` | `src/config/cucumber.config.ts` (appended) |
|
|
228
|
-
| `src/utils/locators/Locator*.ts` | `src/utils/locators/<file>` |
|
|
229
|
-
|
|
230
|
-
**Deduplication per file type:**
|
|
231
|
-
|
|
232
|
-
| File | Behaviour when file already exists |
|
|
233
|
-
|---|---|
|
|
234
|
-
| `locators.ts` | New const-object keys appended; existing keys skipped |
|
|
235
|
-
| `*.steps.ts` | New step blocks appended; steps with matching regex skipped |
|
|
236
|
-
| `*.page.ts` | New async methods appended; existing method names skipped |
|
|
237
|
-
| `*.feature` | New scenario blocks appended; scenarios with matching titles skipped (existing step wording preserved) |
|
|
238
|
-
| `cucumber.config.ts` | Profile block appended; duplicate profile names skipped |
|
|
239
|
-
| Infrastructure `*.ts` | Protected in `tests_only`; written-if-absent in `scaffold_and_tests` |
|
|
240
|
-
|
|
241
|
-
**Interface adaptation (applied automatically):**
|
|
242
|
-
|
|
243
|
-
| Generated code | Rewritten to |
|
|
244
|
-
|---|---|
|
|
245
|
-
| `repo.updateHealed(k, s, …)` | `repo.setHealed(k, s)` |
|
|
246
|
-
| `repo.getBBox(key)` | `null` |
|
|
247
|
-
| `repo.incrementSuccess/Failure(…)` | removed |
|
|
248
|
-
| `repo.queueSuggestion(…)` | removed |
|
|
249
|
-
| `repo.updateBoundingBox(…)` | removed |
|
|
250
|
-
| `fixture().logger` | `this.logger` |
|
|
251
|
-
| `fixture().locatorRepository` | `this.repo` |
|
|
252
|
-
| `fixture().page` | `this.page` |
|
|
253
|
-
| `import { Logger } from "winston"` | `import { HealerLogger }` |
|
|
254
|
-
| `EnvironmentManager` | Helix `environment` singleton |
|
|
255
|
-
|
|
256
|
-
---
|
|
257
|
-
|
|
258
|
-
### Step 7 — Verify the response
|
|
259
|
-
|
|
260
|
-
```json
|
|
261
|
-
{
|
|
262
|
-
"summary": { "requested": 4, "written": 4, "skipped": 0 },
|
|
263
|
-
"deduplication": {
|
|
264
|
-
"src/locators/checkout.locators.ts": {
|
|
265
|
-
"type": "locators",
|
|
266
|
-
"added_keys": ["checkoutBtn", "summaryTotal"],
|
|
267
|
-
"skipped_keys": ["submitBtn", "cancelBtn"]
|
|
268
|
-
},
|
|
269
|
-
"src/test/steps/checkout.steps.ts": {
|
|
270
|
-
"type": "steps",
|
|
271
|
-
"added_patterns": ["user completes checkout"],
|
|
272
|
-
"skipped_patterns": ["user logs in"]
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
Report the `deduplication` summary to the user so they can confirm which
|
|
279
|
-
symbols were added vs skipped.
|
|
280
|
-
|
|
281
|
-
**Skipped reasons to handle:**
|
|
282
|
-
|
|
283
|
-
| Reason | Action |
|
|
284
|
-
|---|---|
|
|
285
|
-
| `"empty content"` | Normal — generator produced no content for that file |
|
|
286
|
-
| `"profile '…' already exists"` | Normal — no action needed |
|
|
287
|
-
| `"infrastructure file already exists"` | Normal in `tests_only` mode |
|
|
288
|
-
| `"infrastructure file — skipped in tests_only mode"` | Normal |
|
|
289
|
-
| Any `OSError` | Report path and error to user |
|
|
290
|
-
|
|
291
|
-
---
|
|
292
|
-
|
|
293
|
-
## Scaffold vs Regenerate Infrastructure
|
|
294
|
-
|
|
295
|
-
**First-time setup** (`framework_state` is `"absent"` or `"partial"`):
|
|
296
|
-
|
|
297
|
-
```
|
|
298
|
-
scaffold_locator_repository(...) # generate 6 infra files
|
|
299
|
-
write_helix_files(..., mode="scaffold_and_tests")
|
|
300
|
-
# Writes missing infra files + test files
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
**Intentional infrastructure regeneration** (user explicitly requests it):
|
|
304
|
-
|
|
305
|
-
```
|
|
306
|
-
write_helix_files(..., mode="scaffold_and_tests", force_scaffold=true)
|
|
307
|
-
# Overwrites ALL infra files — use deliberately
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
**Never** call with `force_scaffold=true` unless the user has explicitly asked
|
|
311
|
-
to regenerate the healing infrastructure.
|
|
312
|
-
|
|
313
|
-
---
|
|
314
|
-
|
|
315
|
-
## Quality Gates
|
|
316
|
-
|
|
317
|
-
Before calling `write_helix_files`:
|
|
318
|
-
|
|
319
|
-
- [ ] `inspect_helix_project` has been called and `recommendation` noted.
|
|
320
|
-
- [ ] `list_helix_tree` has been called — existing file names recorded to prevent new-file creation.
|
|
321
|
-
- [ ] **Existing `*.feature` file read** (`read_helix_file`) and its scenario titles + step phrasings were passed to the generator as context (Step 4 above). If this was skipped, STOP — regenerate with the existing file as context before writing.
|
|
322
|
-
- [ ] **`pre_validate_cucumber_steps` called with `existing_steps_ts_contents`** — read every existing `*.steps.ts` in `src/test/steps/` via `read_helix_file` and pass as the `existing_steps_ts_contents` map. This enables check 6 (cross-file duplicate detection). Skipping this is the most common source of redundant step definitions across files.
|
|
323
|
-
- [ ] `pre_validate_cucumber_steps` returned `valid: true` and `errors` is empty.
|
|
324
|
-
- [ ] Every `*.steps.ts` in the `files` dict uses Cucumber expression syntax (not regex).
|
|
325
|
-
- [ ] `mode` matches `recommendation` — never override without user instruction.
|
|
326
|
-
- [ ] `force_scaffold` is `false` unless the user explicitly asked to regenerate.
|
|
327
|
-
- [ ] The `files` dict comes directly from `generate_playwright_code` or
|
|
328
|
-
`scaffold_locator_repository` — never manually constructed.
|
|
329
|
-
- [ ] After writing, the `deduplication` field has been reviewed and reported.
|
|
330
|
-
|
|
331
|
-
---
|
|
332
|
-
|
|
333
|
-
## Failure Recovery Procedure
|
|
334
|
-
|
|
335
|
-
When `write_helix_files` returns an error:
|
|
336
|
-
|
|
337
|
-
### 1 — Parenthesis / bracket balance error in a steps file
|
|
338
|
-
|
|
339
|
-
**Symptom:** Tool returns a message about parenthesis balance, bracket imbalance,
|
|
340
|
-
or validator failure on a `*.steps.ts` file.
|
|
341
|
-
|
|
342
|
-
**Root cause:** The step definitions contain regex patterns. Regex uses un-paired
|
|
343
|
-
parentheses (`(`, `)`) that the file validator counts as unbalanced.
|
|
344
|
-
|
|
345
|
-
**Fix:**
|
|
346
|
-
1. Call `pre_validate_cucumber_steps` on the failing steps file content — it identifies
|
|
347
|
-
every offending pattern and provides a ready-to-paste Cucumber expression replacement.
|
|
348
|
-
2. Convert any regex patterns to Cucumber expressions:
|
|
349
|
-
- `"([^"]*)"` → `{string}`
|
|
350
|
-
- `(\d+)` → `{int}`
|
|
351
|
-
- `/^…$/` wrapper → plain quoted string
|
|
352
|
-
3. Retry `write_helix_files` with the corrected `files` dict.
|
|
353
|
-
4. Do NOT call `create_file` at any point.
|
|
354
|
-
|
|
355
|
-
### 2 — `OSError` / path error
|
|
356
|
-
|
|
357
|
-
**Symptom:** Tool returns an `OSError`, `FileNotFoundError`, or similar path message.
|
|
358
|
-
|
|
359
|
-
**Fix:** Report the exact path and error to the user. Do not attempt to create the
|
|
360
|
-
directory or file manually unless the user explicitly instructs it.
|
|
361
|
-
|
|
362
|
-
### 3 — Any other tool error
|
|
363
|
-
|
|
364
|
-
**Fix:** Report the raw error text to the user verbatim. Ask: "How would you like
|
|
365
|
-
to proceed?" Do not attempt any workaround autonomously.
|
|
366
|
-
|
|
367
|
-
---
|
|
368
|
-
|
|
369
|
-
## Known Tool Limitations (Document These for Future Agent Runs)
|
|
370
|
-
|
|
371
|
-
| Limitation | Description | Workaround |
|
|
372
|
-
|---|---|---|
|
|
373
|
-
| Parenthesis validator | Rejects step files with regex step patterns; error message names regex preprocessor as cause and prescribes Cucumber expressions | Use `pre_validate_cucumber_steps` before submitting to catch and fix offending patterns |
|
|
374
|
-
| `update_helix_file` for single-file edits | Use `qa-helix-writer:update_helix_file` for targeted single-file changes instead of re-submitting the full `files` dict | Pass `relative_path` and the new content directly; set `force_overwrite=true` only when replacing existing content |
|
package/src/cmd-init.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* cmd-init.js — `qa-stlc init`
|
|
3
|
-
*
|
|
4
|
-
* Full bootstrap: install Python agents + skills + MCP config.
|
|
5
|
-
*/
|
|
6
|
-
"use strict";
|
|
7
|
-
|
|
8
|
-
const { execSync, spawnSync } = require("child_process");
|
|
9
|
-
const path = require("path");
|
|
10
|
-
const fs = require("fs");
|
|
11
|
-
|
|
12
|
-
const cmdSkills = require("./cmd-skills");
|
|
13
|
-
const cmdMcpConfig = require("./cmd-mcp-config");
|
|
14
|
-
|
|
15
|
-
const C = {
|
|
16
|
-
reset: "\x1b[0m", bold: "\x1b[1m",
|
|
17
|
-
green: "\x1b[32m", cyan: "\x1b[36m",
|
|
18
|
-
yellow: "\x1b[33m", red: "\x1b[31m", dim: "\x1b[2m",
|
|
19
|
-
};
|
|
20
|
-
const ok = (m) => console.log(`${C.green}✓${C.reset} ${m}`);
|
|
21
|
-
const info = (m) => console.log(`${C.cyan}→${C.reset} ${m}`);
|
|
22
|
-
const warn = (m) => console.log(`${C.yellow}⚠${C.reset} ${m}`);
|
|
23
|
-
const die = (m) => { console.error(`${C.red}✗${C.reset} ${m}`); process.exit(1); };
|
|
24
|
-
|
|
25
|
-
module.exports = async function init(opts) {
|
|
26
|
-
console.log(`\n${C.bold}QA STLC Agents — init${C.reset}\n`);
|
|
27
|
-
|
|
28
|
-
// ── 1. Check Python ──────────────────────────────────────────────────────
|
|
29
|
-
const python = opts.python || "python3";
|
|
30
|
-
info(`Checking Python (${python})…`);
|
|
31
|
-
const pyCheck = spawnSync(python, ["--version"], { encoding: "utf8" });
|
|
32
|
-
if (pyCheck.status !== 0) {
|
|
33
|
-
die(`Python not found at '${python}'. Install Python 3.10+ or pass --python <path>.`);
|
|
34
|
-
}
|
|
35
|
-
const pyVersion = (pyCheck.stdout || pyCheck.stderr || "").trim();
|
|
36
|
-
const match = pyVersion.match(/Python (\d+)\.(\d+)/);
|
|
37
|
-
if (!match || parseInt(match[1]) < 3 || parseInt(match[2]) < 10) {
|
|
38
|
-
die(`Python 3.10+ required, found: ${pyVersion}`);
|
|
39
|
-
}
|
|
40
|
-
ok(`${pyVersion} found.`);
|
|
41
|
-
|
|
42
|
-
// ── 2. pip install qa-gentic-stlc-agents ────────────────────────────────────────
|
|
43
|
-
info("Installing qa-gentic-stlc-agents (pip)…");
|
|
44
|
-
const pip = spawnSync(python, ["-m", "pip", "install", "qa-gentic-stlc-agents>=1.0.1", "--quiet"], {
|
|
45
|
-
stdio: "inherit",
|
|
46
|
-
encoding: "utf8",
|
|
47
|
-
});
|
|
48
|
-
if (pip.status !== 0) {
|
|
49
|
-
die("pip install failed. Run manually: pip install qa-gentic-stlc-agents");
|
|
50
|
-
}
|
|
51
|
-
ok("qa-gentic-stlc-agents installed.");
|
|
52
|
-
|
|
53
|
-
// ── 3. Install skills ────────────────────────────────────────────────────
|
|
54
|
-
info("Installing skills…");
|
|
55
|
-
const skillTarget = opts.vscode ? "both" : "claude";
|
|
56
|
-
await cmdSkills({ target: skillTarget });
|
|
57
|
-
|
|
58
|
-
// ── 4. Write MCP config ──────────────────────────────────────────────────
|
|
59
|
-
info("Writing MCP config…");
|
|
60
|
-
await cmdMcpConfig({
|
|
61
|
-
vscode: opts.vscode || false,
|
|
62
|
-
print: false,
|
|
63
|
-
python: python,
|
|
64
|
-
playwrightPort: "8931",
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// ── 5. Done ──────────────────────────────────────────────────────────────
|
|
68
|
-
const mcpLocation = opts.vscode ? ".vscode/mcp.json" : ".mcp.json";
|
|
69
|
-
const skillsLocation = opts.vscode
|
|
70
|
-
? ".github/copilot-instructions/ (reload VS Code window to activate)"
|
|
71
|
-
: ".claude/skills/";
|
|
72
|
-
|
|
73
|
-
console.log(`
|
|
74
|
-
${C.bold}Setup complete.${C.reset}
|
|
75
|
-
|
|
76
|
-
${C.dim}MCP config :${C.reset} ${mcpLocation}
|
|
77
|
-
${C.dim}Skills :${C.reset} ${skillsLocation}
|
|
78
|
-
|
|
79
|
-
${C.bold}Start Playwright MCP${C.reset} ${C.dim}(keep running in a separate terminal):${C.reset}
|
|
80
|
-
|
|
81
|
-
${C.cyan}npx @playwright/mcp@latest --port 8931${C.reset}
|
|
82
|
-
|
|
83
|
-
${C.bold}STLC Workflow${C.reset} ${C.dim}— use agents in this order:${C.reset}
|
|
84
|
-
|
|
85
|
-
${C.dim}1 →${C.reset} ${C.yellow}qa-test-case-manager${C.reset} ${C.dim}ADO work item ID → create manual test cases in ADO${C.reset}
|
|
86
|
-
${C.dim}2 →${C.reset} ${C.yellow}qa-gherkin-generator${C.reset} ${C.dim}Epic / Feature / PBI → BDD .feature file attached to ADO${C.reset}
|
|
87
|
-
${C.dim}3 →${C.reset} ${C.yellow}qa-playwright-generator${C.reset} ${C.dim}Gherkin + live page snapshot → self-healing Playwright TypeScript${C.reset}
|
|
88
|
-
${C.dim}4 →${C.reset} ${C.yellow}qa-helix-writer${C.reset} ${C.dim}Generated files → merged into Helix-QA project on disk${C.reset}
|
|
89
|
-
|
|
90
|
-
${C.dim}Skills reference all four steps — ask your agent: "@generate-playwright-code"${C.reset}
|
|
91
|
-
`);
|
|
92
|
-
};
|