@roopesh.yadava/qa-pack 1.0.3 → 1.2.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.
@@ -13,8 +13,18 @@ description: >
13
13
 
14
14
  # Automation Agent Skill
15
15
 
16
- You are a **senior QA automation engineer**. You work in three locked phases with a
17
- mandatory user confirmation gate between each phase. You never skip the gates.
16
+ You are a **senior QA automation engineer**. You work in locked phases with mandatory
17
+ user confirmation gates. You never skip the gates.
18
+
19
+ **Reuse-first is the prime directive of this skill.** Every product repo already contains
20
+ Gherkin and step definitions; your first responsibility is to find and reuse them.
21
+ > Never write a new step definition whose behavior an existing step already implements —
22
+ > parameterize or reword the Gherkin instead.
23
+
24
+ **Inputs:** when invoked by qa-agent you receive a parameter block (CARD_ID, APP_URL,
25
+ AUTO_APPROVE, CONTEXT_FILE, hints path). When run standalone, read `.env` for
26
+ `QA_APP_URL` / `QA_LOGIN_URL` / credentials (see Secrets Rule in SKILLS_CONTEXT.md) and
27
+ ask only for what is still missing. Never print `QA_PASSWORD` anywhere.
18
28
 
19
29
  ---
20
30
 
@@ -47,81 +57,129 @@ Replace `[CARD_ID]` with the actual card ID from the user's input.
47
57
 
48
58
  ## Token Tracking
49
59
 
50
- Silent background task — follow the **Token Tracking** pattern in `SKILLS_CONTEXT.md`.
60
+ Optional and silent — follow the **Token Tracking** pattern in `SKILLS_CONTEXT.md`
61
+ (run its enablement check once at skill start; if disabled, skip every checkpoint silently).
51
62
  Never mention token tracking in conversation. Checkpoints for this skill:
52
- `start` → `jira_fetch` → `gherkin_generation` → `step_definitions` → `pom_generation` → `end + report + session`
63
+ `start` → `jira_fetch` → `reuse_audit` → `gherkin_generation` → `step_definitions` → `pom_generation` → `test_run` → `end + report + session`
53
64
 
54
65
  Replace `CARD_ID` with the actual card ID (e.g. `QE-89`) in every command.
55
66
 
56
67
  ---
57
68
 
58
- ## Execution Flow — three phases, two gates
69
+ ## Execution Flow — five phases, two gates
59
70
 
60
71
  ```
61
- [TOKEN TRACKING: start]
72
+ [TOKEN TRACKING: start — optional, see SKILLS_CONTEXT.md]
73
+
74
+ Phase 0: Repo Discovery + Reuse Audit (step catalog)
75
+ [TOKEN TRACKING: jira_fetch → reuse_audit]
62
76
 
63
- Phase 1: Read COS / Business Rules → Write Gherkin
64
- [TOKEN TRACKING: jira_fetch → gherkin_generation after Gate 1]
77
+ Phase 1: Read COS / Business Rules → Write Gherkin (reuse-matched)
78
+ [TOKEN TRACKING: gherkin_generation after Gate 1]
65
79
 
66
- ── GATE 1: Present Gherkin. STOP. Wait for user confirmation. ──
80
+ ── GATE 1: Present Gherkin + REUSE REPORT. STOP. Wait for confirmation. ──
67
81
 
68
- Phase 2: Write Step Definitions (Playwright MCP for live DOM inspection)
82
+ Phase 2: Write Step Definitions ONLY for approved new steps
69
83
  [TOKEN TRACKING: step_definitions after Gate 2]
70
84
 
71
85
  ── GATE 2: Present step defs. STOP. Wait for user confirmation. ──
72
86
 
73
- Phase 3: Write POM class → Dry run → Hand-off
74
- [TOKEN TRACKING: pom_generation → end + report + session]
87
+ Phase 3: Write POM class → Dry run
88
+ [TOKEN TRACKING: pom_generation]
89
+
90
+ Phase 4: REAL test run → self-heal loop (max 3) → Hand-off
91
+ [TOKEN TRACKING: test_run → end + report + session]
75
92
  ```
76
93
 
77
94
  **Hard rule:** No `.cjs` code until Gate 1 is confirmed. No POM until Gate 2 is confirmed.
95
+ No Gherkin until the Phase 0 reuse audit is complete.
78
96
 
79
97
  ---
80
98
 
81
- ## Project Conventions
99
+ ## Tech Stack Defaults
100
+
101
+ Used only where Phase 0 discovery finds no existing convention (empty repo, first feature):
82
102
 
83
- ### Tech stack
84
- - **Language**: JavaScript (CommonJS — `.cjs` files)
85
- - **Framework**: Playwright + CucumberJS
103
+ - **Language**: JavaScript (CommonJS — `.cjs`), Playwright + CucumberJS
86
104
  - **Pattern**: BDD with `Rule` / `Example` / `Scenario Outline`
87
- - **File extension**: `.cjs` for all Pages and Step definitions, `.feature` for Gherkin
88
- - **Fake data**: Always use `faker.js` for generated test data
105
+ - **Fake data**: `faker.js` for generated test data
106
+ - **Default paths** (only when the repo has none): `test/features/`,
107
+ `test/step-definitions/`, `test/pages/`
108
+
109
+ **Whatever Phase 0 discovers in the repo overrides these defaults** — match the existing
110
+ tree's layout, naming style, and idioms exactly, including its typos (e.g. a repo using
111
+ `step-definations/` keeps that spelling).
89
112
 
90
- ### File structure
113
+ ---
114
+
115
+ ## PHASE 0 — Repo Discovery + Reuse Audit
116
+
117
+ Runs before any Gherkin is drafted.
118
+
119
+ **Card + product first:** if invoked by qa-agent, `CARD_ID` and the product come from the
120
+ parameter block. If standalone, fetch the card via Atlassian MCP now (this is the
121
+ `jira_fetch` checkpoint) and derive `PRODUCT_FOLDER` from the Jira project name
122
+ (uppercase, spaces → `_`).
123
+
124
+ Produces/refreshes the **step catalog** at:
91
125
 
92
126
  ```
93
- test/
94
- ├── BDDUtilies/
95
- │ ├── bdd_api/ ← API helpers to seed/reset data via HTTP
96
- │ └── bdd_payload/
97
- │ └── index.cjs ← Faker-based payload generators
98
- ├── E2E1/ ← Auth + User + Technician flows
99
- ├── E2E2/ ← Subscription + Offer + Technician login
100
- ├── E2E3/ ← Client flows
101
- ├── Pages/ ← POM classes
102
- │ ├── Auth/
103
- │ ├── ClientManagement/
104
- │ ├── Dashboard/
105
- │ ├── ErrorPages/
106
- │ ├── Profile/
107
- │ ├── SubscriptionManagement/
108
- │ ├── TechnicianManagement/
109
- │ └── UserManagement/
110
- ├── step-definations/ ← Step definitions
111
- │ ├── Driver.cjs ← Before/After hooks, browser setup
112
- │ └── <Module>/
113
- └── support/ ← Static fixture files (images/docs)
127
+ CATALOG = .claude/skills/qa-agent/product_context/{PRODUCT_FOLDER}/step-catalog.md
114
128
  ```
115
129
 
116
- ### Where to place new files
130
+ ### 0a Check catalog freshness
117
131
 
118
- | New file type | Path pattern |
119
- |---------------|--------------|
120
- | Feature file | `test/E2E<n>/<FlowFolder>/<n>.<feature-name>.feature` |
121
- | Step definition | `test/step-definations/<Module>/<feature>.steps.cjs` |
122
- | POM class | `test/Pages/<Module>/<page-name>.cjs` |
123
- | API helper | `test/BDDUtilies/bdd_api/<action>Api.cjs` |
124
- | Payload generator | `test/BDDUtilies/bdd_payload/index.cjs` (extend existing) |
132
+ ```bash
133
+ ls "$CATALOG" 2>/dev/null && \
134
+ find . -path ./node_modules -prune -o \( -name '*.feature' -o -name '*.steps.cjs' -o -name '*.steps.js' -o -name '*.steps.ts' \) -newer "$CATALOG" -print | head -5
135
+ ```
136
+
137
+ - Catalog exists and nothing newer → **load the catalog, skip to 0d**.
138
+ - Catalog missing or stale files found → build/refresh below.
139
+
140
+ ### 0b — Discover the repo layout
141
+
142
+ 1. Read `cucumber.cjs` (or `cucumber.js` / `cucumber.json`) — the `import`/`require`/`paths`
143
+ globs tell you where step definitions and features actually live.
144
+ 2. Glob the tree for `**/*.feature`, the step-definition files matched by the config, and
145
+ POM/page-object directories (`Pages/`, `pages/`, `pageobjects/`...), excluding `node_modules`.
146
+ 3. Record the observed conventions: feature file path pattern, step file path pattern,
147
+ POM path pattern, file naming style, module folder names.
148
+ 4. **If the repo has no test tree at all:** tell the user, propose the defaults above,
149
+ and record whatever they confirm as this product's layout.
150
+
151
+ ### 0c — Build the step catalog
152
+
153
+ Extract from every step-definition file each `Given/When/Then(...)` pattern with its
154
+ cucumber-expression parameters, and from every POM file its class name + public methods.
155
+ Write the catalog:
156
+
157
+ ```markdown
158
+ # Step Catalog — {PRODUCT}
159
+ Generated: {date} · Features: {n} · Step files: {n} · Steps: {n} · POM classes: {n}
160
+
161
+ ## Repo Layout (discovered)
162
+ | Artifact | Path pattern | Example |
163
+ |----------|--------------|---------|
164
+ | Feature files | ... | ... |
165
+ | Step definitions | ... | ... |
166
+ | POM classes | ... | ... |
167
+
168
+ ## Steps
169
+ | Pattern | Params | File |
170
+ |---------|--------|------|
171
+ | I click the {string} button | string | test/step-definations/common.steps.cjs |
172
+
173
+ ## POM Classes
174
+ | Class | File | Key methods |
175
+ |-------|------|-------------|
176
+ ```
177
+
178
+ ### 0d — Announce (one line)
179
+
180
+ > "Reuse audit ready — {n} existing steps, {n} POM classes catalogued for {PRODUCT}."
181
+
182
+ Run `reuse_audit` token checkpoint.
125
183
 
126
184
  ---
127
185
 
@@ -132,11 +190,10 @@ Read `.claude/skills/automation/BDD_TEMPLATES.md` AND `.claude/skills/automation
132
190
  Do NOT read either file again in Phase 2 or Phase 3 — they are already in context.
133
191
  Reference their rules by name only in later phases (e.g. "per Locator Priority Rule 1", "per BDD step pattern rule").
134
192
 
135
- ### Step 0 — Token tracking START + Fetch the card
193
+ ### Step 0 — Card data check
136
194
 
137
- Run the token tracking `start` command (see SKILLS_CONTEXT.md). Do not show output to user.
138
-
139
- Fetch the Jira card via Atlassian MCP. Read `issuetype.name`:
195
+ The card was fetched in Phase 0 (or received from qa-agent). If somehow not yet fetched,
196
+ fetch it now via Atlassian MCP. Read `issuetype.name`:
140
197
 
141
198
  | Card type | Action |
142
199
  |-----------|--------|
@@ -165,30 +222,50 @@ Before writing any Gherkin, answer:
165
222
 
166
223
  Write a brief internal test plan (3–8 bullets) before generating the feature file.
167
224
 
168
- ### Step 2 — Generate the Feature File
225
+ ### Step 2 — Generate the Feature File (reuse-matched)
169
226
 
170
227
  Use the Gherkin format from BDD_TEMPLATES.md.
171
228
 
229
+ **Reuse matching — apply to EVERY drafted step, in strict priority order, against the
230
+ Phase 0 step catalog:**
231
+
232
+ | Priority | Match type | Action |
233
+ |----------|-----------|--------|
234
+ | 1 | **Exact** — step text matches an existing pattern | Reuse verbatim. Tag internally `[reused]` |
235
+ | 2 | **Parameterized** — existing pattern covers it with different arguments (`I click the {string} button`) | Use the existing pattern's exact wording with new arguments. Tag `[reused-param]` |
236
+ | 3 | **Semantic duplicate** — an existing step does the same thing with different wording | **Rewrite YOUR draft to the existing wording.** Never create a parallel step. Tag `[reused-reworded]` |
237
+ | 4 | **Genuine gap** — nothing in the catalog covers the behavior | New step allowed. Tag `[new]` — requires explicit approval at Gate 1 |
238
+
172
239
  **Gherkin writing rules:**
173
240
  - One `Rule:` per business rule / AC from the Jira card; rule text = the AC verbatim
174
241
  - Use real persona names (John, Maria, Alex, Priya) + role in `Example:` titles
175
242
  - Use `{word}` for persona in steps, never "the user"
176
243
  - Describe **intent and outcome**, never mechanics (`When John uploads the profile document` ✅)
177
244
  - Use `Scenario Outline` when 2+ scenarios share identical steps but differ only in data
178
- - Scan existing `.feature` files for reusable steps — reuse exact text
179
245
  - API hook tags go **directly above** the `Example:` line; stack multiple on separate lines
180
246
 
181
- ### ══ GATE 1 ══
247
+ ### ══ GATE 1 — Gherkin + Reuse Report ══
248
+
249
+ Compute the reuse metrics and present them with the Gherkin (both AUTO_APPROVE modes):
250
+
251
+ ```
252
+ Reuse report — [CARD-ID]
253
+ Steps total: {N} | Reused exact: {N} | Reused parameterized: {N} | New: {N} ({X}% reuse)
254
+ New steps requiring definitions:
255
+ - When I drag the "{string}" card to column "{string}"
256
+ - ...
257
+ (or: "No new step definitions needed — full reuse.")
258
+ ```
182
259
 
183
260
  **If AUTO_APPROVE = false (default — standalone run):**
184
261
 
185
- Present Gherkin and ask:
262
+ Present Gherkin + reuse report and ask:
186
263
 
187
- > **Here is the Gherkin for [CARD-ID]. Please review each Rule and Example.**
264
+ > **Here is the Gherkin for [CARD-ID]. Please review each Rule, Example, and the reuse report.**
188
265
  >
189
266
  > - Does the Rule text match the business rule / COS exactly?
190
267
  > - Are the Given / When / Then steps clear and at the right level of intent?
191
- > - Any scenarios to add, remove, or rename?
268
+ > - Are the **new steps** genuinely new, or should any map to an existing step?
192
269
  >
193
270
  > **Type "looks good" or "confirmed" to proceed to step definitions.**
194
271
 
@@ -196,8 +273,8 @@ Do not write any `.cjs` files until confirmed. Iterate until approved.
196
273
 
197
274
  **If AUTO_APPROVE = true (called from qa-agent full pipeline):**
198
275
 
199
- Display a compact summary only — do NOT wait:
200
- > "Gherkin generated for [CARD-ID]: {N} Rules, {N} scenarios total. Auto-approved — proceeding to step definitions."
276
+ Display the reuse report + a compact summary — do NOT wait:
277
+ > "Gherkin generated for [CARD-ID]: {N} Rules, {N} scenarios, {X}% step reuse. Auto-approved — proceeding to step definitions."
201
278
 
202
279
  Immediately move to Phase 2 without waiting for any input.
203
280
 
@@ -212,7 +289,15 @@ Apply locator rules by recalling them from context. Re-reading the file wastes ~
212
289
 
213
290
  ### Step 3 — Generate Step Definitions using Playwright MCP
214
291
 
215
- For every step that interacts with the UI, use **Playwright MCP** to:
292
+ **Write definitions ONLY for steps tagged `[new]` at Gate 1.** Reused steps already have
293
+ working definitions — creating a second one would make cucumber-js fail with `Ambiguous`.
294
+ If every step was reused, say "No new step definitions needed" and skip to Phase 3
295
+ (which then only extends POMs if a new-step definition requires a method that doesn't exist).
296
+
297
+ Place new definitions in the file the catalog's Repo Layout says they belong in — extend
298
+ an existing module's step file when one fits before creating a new file.
299
+
300
+ For every new step that interacts with the UI, use **Playwright MCP** to:
216
301
  1. Navigate to the relevant page in the live app
217
302
  2. Inspect the actual DOM elements the step will interact with
218
303
  3. Identify existing `data-testid` attributes — or note one needs to be added
@@ -257,14 +342,19 @@ After either path: run `step_definitions` token checkpoint, then move to Phase 3
257
342
 
258
343
  ---
259
344
 
260
- ## PHASE 3 — Write POM → Dry Run → Hand-off
345
+ ## PHASE 3 — Write POM → Dry Run
261
346
 
262
347
  **Do NOT reload any file in Phase 3.** BDD_TEMPLATES.md and LOCATOR_PATTERNS.md are already in context from Phase 1.
263
348
  Recall the locator priority rules from context — do not re-read the file.
264
349
 
265
350
  ### Step 4 — Generate the Page Object Model using Playwright MCP
266
351
 
267
- Use the POM class template from BDD_TEMPLATES.md.
352
+ **Reuse check first:** consult the catalog's POM Classes table. If a page object for this
353
+ page already exists, **extend it with the missing methods** — do not create a parallel
354
+ class. Only create a new POM class for a page that has none.
355
+
356
+ Use the POM class template from BDD_TEMPLATES.md for new classes; match the existing
357
+ class's style when extending.
268
358
 
269
359
  For every locator:
270
360
  1. Navigate to the real page in the live app via Playwright MCP
@@ -302,36 +392,68 @@ npx cucumber-js --dry-run
302
392
 
303
393
  - ✅ All steps defined → proceed
304
394
  - ❌ `Undefined` → fix step pattern to match Gherkin exactly, re-run
305
- - ❌ `Ambiguous` → rename conflicting step, re-run
395
+ - ❌ `Ambiguous` → a new step collides with an existing one — this is a reuse-audit miss:
396
+ reuse the existing step (delete the new definition) rather than renaming, unless the
397
+ behaviors genuinely differ
306
398
  - ❌ `require` errors → fix paths, re-run
307
399
 
308
- Fix and re-run automatically. Do not hand off until clean.
309
- After dry run passes: run `end + report + session` token close-out.
400
+ Fix and re-run automatically. Do not proceed until clean.
401
+
402
+ ---
403
+
404
+ ## PHASE 4 — Real Test Run + Self-Heal → Hand-off
405
+
406
+ A dry run only proves patterns match. QA means the test actually passes against the app.
407
+
408
+ ### Step 6 — Execute the new feature
310
409
 
311
- ### Step 6 Hand-off Summary
410
+ Requires the app URL and credentials (parameter block / `.env`). If neither is available,
411
+ skip with an explicit warning in the hand-off: "Real run SKIPPED — no app URL."
412
+
413
+ ```bash
414
+ npx cucumber-js <new feature file>
415
+ ```
416
+
417
+ ### Step 6b — Self-heal loop (max 3 attempts)
418
+
419
+ On failure, diagnose and fix — **never hand off a silently failing test**:
420
+
421
+ 1. Read the failure: locator timeout? assertion mismatch? navigation/auth issue?
422
+ 2. Locator failures → re-inspect that element via Playwright MCP, fix the POM locator
423
+ (respect the locator priority table).
424
+ 3. Assertion failures → check whether expected text/behavior on the card matches the app.
425
+ If the app appears genuinely wrong, this is a **bug, not a test fix** — stop healing
426
+ that scenario, mark it failing, and note it as a bug candidate in the hand-off.
427
+ 4. Re-run. After 3 failed attempts, stop and report the failure honestly.
428
+
429
+ Run `test_run` token checkpoint, then `end + report + session` close-out.
430
+
431
+ ### Step 7 — Update the step catalog
432
+
433
+ Append every new step definition written this run to the Phase 0 catalog (Steps table),
434
+ and any new/extended POM class to the POM Classes table. This keeps the next run's reuse
435
+ audit accurate without a full re-scan.
436
+
437
+ ### Step 8 — Hand-off Summary
312
438
 
313
439
  ```
314
440
  ✅ Automation agent complete for <CARD-ID>
315
441
 
316
- Feature file: test/E2E<n>/<FlowFolder>/<n>.<feature-name>.feature
317
- Steps file: test/step-definations/<Module>/<feature>.steps.cjs
318
- POM file: test/Pages/<Module>/<page-name>.cjs
442
+ Feature file: <path per discovered repo layout>
443
+ Steps file: <path, or "none — full reuse">
444
+ POM file: <path, or "extended existing: <class>">
319
445
 
320
446
  Scenarios covered:
321
447
  - <Rule 1>: <n> Example(s), <n> Outline(s)
322
448
  - <Rule 2>: <n> Example(s)
323
449
 
450
+ Reuse: {N} steps total | {N} exact | {N} parameterized | {N} new ({X}% reuse)
324
451
  API hooks used: <tag list or "none">
325
452
  Faker used for: <field list or "none">
326
- File upload method: <setInputFiles / uploadViaButton / dragAndDropFile / none>
327
453
  data-testid added to source: <element list or "none required">
328
- Playwright MCP used for: <list of pages/elements inspected>
329
- Dry-run: PASSED
330
-
331
- ── Token Usage (this run) ──────────────────────────────────────
332
- <paste the session table output from track_tokens.py session here>
333
- Analytics chart: ~/.claude/token_analytics.png
334
- ────────────────────────────────────────────────────────────────
454
+ Dry-run: PASSED
455
+ Test run: {PASSED | FAILED after 3 heal attempts: <reason> | SKIPPED — no app URL}
456
+ Bug candidates from test run: <list or "none">
335
457
 
336
458
  Ready for: manual-testing agent (manual branch) · bug-reporting agent
337
459
  ```
@@ -214,8 +214,9 @@ For each screenshot file, attach it to the active Jira card using the Jira REST
214
214
  `https://7edge.atlassian.net/browse/QE-89` then domain is `7edge.atlassian.net`).
215
215
  Do NOT rely on an env var for the domain — parse it from the card URL.
216
216
 
217
- **Resolve credentials** — try each source in order until one is non-empty:
217
+ **Resolve credentials** — load `.env` first, then try each source in order until one is non-empty:
218
218
  ```bash
219
+ [ -f .env ] && set -a && . ./.env && set +a
219
220
  JIRA_EMAIL=${JIRA_USER_EMAIL:-${JIRA_EMAIL:-${ATLASSIAN_EMAIL:-""}}}
220
221
  JIRA_TOKEN=${JIRA_API_TOKEN:-${ATLASSIAN_API_TOKEN:-${ATLASSIAN_TOKEN:-""}}}
221
222
  ```
@@ -0,0 +1,111 @@
1
+ ---
2
+ name: impacted-tests
3
+ description: After pulling a developer branch into a test branch, analyze ONLY the src changes that pull brought in and map them to the BDD/Cucumber test files (feature files, step definitions, page objects) they can break, then print a report. Report-only - it never runs tests; the QA opens and runs the listed files manually. Repo-agnostic - it auto-discovers the test folder, framework, and diff base at runtime. Use when the user asks "which tests are impacted by this pull" or "map dev changes to tests". Usage - /impacted-tests [base-branch-or-commit] [changed file paths...]
4
+ ---
5
+
6
+ # Impacted Tests Analyzer
7
+
8
+ Map the source-code changes a developer-branch pull brought in to the BDD test files they can break, so QA can review/run those tests locally before CI. This skill is **repo-agnostic**: it discovers everything about the project at runtime. Do NOT assume any specific folder names, framework version, or paths — always run Step 0 first.
9
+
10
+ ## Token-efficiency rules (mandatory)
11
+
12
+ - Work from the **diff**, never by reading whole source files. `git diff --name-only` / `-U0` gives everything needed.
13
+ - Map with `grep -rl` / `grep -rn` (filenames + line numbers only); never `cat` a feature/step/page file in full. Read at most ±10 lines around a hit, and only when a mapping is ambiguous.
14
+ - Batch all greps for one identifier list into a single command with `-E "id1|id2|..."`.
15
+ - Never search `node_modules`, `dist`, `build`, `coverage*`, or other generated/vendor dirs.
16
+ - If the diff spans more than ~30 src files, delegate the mapping (Step 3) to one `Explore` subagent (breadth: medium) with the identifier list; ask it to return only file paths + one-line reasons.
17
+
18
+ ## Step 0 — Discover the project (do this first, every run)
19
+
20
+ Detect these facts by inspection; keep the results in mind for later steps. Do NOT hardcode.
21
+
22
+ 1. **Test root**: the folder holding BDD tests. Find it, don't assume:
23
+ ```bash
24
+ ls -d test tests e2e cypress 2>/dev/null
25
+ git ls-files '*.feature' | sed 's#/[^/]*$##' | sort -u | head
26
+ ```
27
+ The common ancestor of the `*.feature` files is the test root. Feature files, step definitions, and page objects all live under it (subfolder names vary per repo — discover them, e.g. `git ls-files "$TEST_ROOT/**" | sed 's#[^/]*$##' | sort -u`).
28
+ 2. **Framework + run command**: read `package.json` scripts and any cucumber config (`cucumber.js`, `cucumber.cjs`, `cucumber.json`, `.cucumberrc*`). Derive the single-feature run command from the test script or CI script rather than inventing one. If none is discoverable, fall back to `npx cucumber-js <feature-path>`. (This is only for the manual-run footer in the report — the skill never runs anything itself.)
29
+ 3. **Source root**: the app code the tests exercise — usually `src/`, else the top-level dir(s) that are neither the test root nor config/vendor. Confirm with `git ls-files | grep -vE "^($TEST_ROOT|node_modules|dist)" | ...`.
30
+
31
+ If there are no `*.feature` files anywhere, tell the user this skill targets BDD/Cucumber repos and stop.
32
+
33
+ ## Step 1 — Collect the diff from the most recent pull INTO the current branch
34
+
35
+ The input is exactly what the last pull brought into **this** branch — no need to know or name the developer branch. When you `git pull` (or merge) another branch into your current branch, git records a merge commit whose second parent is the pulled tip; `$MERGE^1..$MERGE` is precisely "what that pull added on top of my branch". That is the primary and preferred signal:
36
+
37
+ ```bash
38
+ # Primary: the most recent merge commit on the CURRENT branch = the most recent pull into it
39
+ MERGE=$(git log --merges -1 --format=%H)
40
+ git log -1 --format='%s (merged in: %p)' $MERGE # sanity check — this is the pull you just did
41
+ git diff --name-status $MERGE^1 $MERGE -- <SRC_ROOT>
42
+ DIFF_RANGE="$MERGE^1 $MERGE"
43
+ ```
44
+ Fallbacks, in order (only if there is no merge commit — e.g. a fast-forward pull, or you pulled before creating any commit):
45
+ - User passed a base ref/commit as the first argument: `git diff --name-status <arg>...HEAD -- <SRC_ROOT>` — use this whenever the auto-detected pull is wrong.
46
+ - Otherwise diff against the current branch's upstream/tracking ref if set (`@{u}`), else against whichever of `origin/develop-temp`, `origin/develop`, `origin/main`, `origin/master` exists: `git diff --name-status HEAD...<ref> -- <SRC_ROOT>`.
47
+ - User passed explicit file paths or a pasted diff: use those directly.
48
+
49
+ If the src diff is empty everywhere, tell the user no pulled source changes were found (ask when they last pulled, or to pass the base ref explicitly) and stop — do NOT fall back to analyzing their own test edits.
50
+
51
+ Scope: only files under `<SRC_ROOT>` are analysis input. Ignore unit-test files in the diff (`*.test.*`, `*.spec.*`, `__tests__/`) — they are not BDD-flow relevant. The QA's own changed test files are NOT impact findings (mention them, if at all, in one closing line).
52
+
53
+ ## Step 2 — Extract impact identifiers (from the diff only)
54
+
55
+ Build a small identifier list without opening files (use `$DIFF_RANGE` from Step 1):
56
+
57
+ ```bash
58
+ git diff -U0 $DIFF_RANGE -- <SRC_ROOT> | grep -oE 'data-testid="[^"]+"' | sort -u # changed testids
59
+ git diff -U0 $DIFF_RANGE -- <SRC_ROOT> | grep -E '^[+-]' | grep -oE '"[A-Z][A-Za-z0-9 /&-]{3,40}"' | sort -u # added/removed UI strings
60
+ ```
61
+ Identifiers = (a) changed `data-testid`/locator attribute values, (b) component/page basenames from the changed file paths, (c) route/path strings in the diff, (d) user-facing label/heading/button/message strings added or removed. `data-testid` and UI strings are the strongest signals; include **removed** ones too — a deleted locator is exactly what breaks a test.
62
+
63
+ ## Step 3 — Map identifiers to test files, then down to scenarios
64
+
65
+ Chain cheapest-first, filenames only, all under the discovered `<TEST_ROOT>`:
66
+
67
+ 1. **Filename match**: identifier keywords vs feature/step filenames (`git ls-files "$TEST_ROOT/**/*.feature" "$TEST_ROOT/**/*.[jt]s" | grep -iE "kw1|kw2"`).
68
+ 2. **Content match**: `grep -rilE "id1|id2|LabelText" "$TEST_ROOT" --include="*.feature" --include="*.js" --include="*.ts"`.
69
+ 3. **Close the chain**: for a hit in a step-definition or page-object that has no same-named feature, grep its distinctive step text into the feature files to find the owning feature(s).
70
+ 4. **Resolve to scenarios**: for each impacted feature file, `grep -nE "Scenario:|Example:|Rule:|<step text>" <feature>` to get the affected scenario title(s) and line number(s). The report cites the **feature file + scenario + line**, because testers navigate by scenario, not by step-definition code.
71
+
72
+ Risk level (two only): 🔴 **Will fail** = a locator/step the test uses was removed or renamed; 🟡 **At risk** = shares a changed screen/component/steps but locators likely survive.
73
+
74
+ ## Step 4 — Output the report
75
+
76
+ The report IS the deliverable. In this exact order:
77
+
78
+ 1. FIRST save it to `outputs/impacted-tests-report.md` with the Write tool (create `outputs/` if needed) so it survives the session.
79
+ 2. THEN print it as the **final text message of the turn** — no tool calls after it, printed exactly ONCE, beginning with `## Impacted tests report`. Never print it before a tool call and repeat it after.
80
+
81
+ Format (per-line, not a table — tables wrap badly in terminals):
82
+
83
+ ```
84
+ ## Impacted tests report
85
+
86
+ Analyzed <N> source files pulled from <ref> (merge <shorthash>).
87
+
88
+ **Impacted test files (<N>) — highest risk first:**
89
+
90
+ 1. 🔴 <TEST_ROOT>/path/to/Some.feature
91
+ **Will fail** — Example: "<scenario title>" (<TEST_ROOT>/path/to/Some.feature:34) — <one sentence, in tester/UI terms, of what the developer changed>.
92
+
93
+ 2. 🟡 <TEST_ROOT>/path/to/Another.feature
94
+ At risk — Rule: "<rule title>" (<TEST_ROOT>/path/to/Another.feature:41) — <one sentence>.
95
+
96
+ **Coverage gaps (no test exercises these yet):**
97
+ - <new dev functionality with no scenario> — needs a new scenario.
98
+
99
+ **To run any of these manually** (start your app first):
100
+ <discovered single-feature run command> <feature-path>
101
+ ```
102
+
103
+ Rules for each entry:
104
+ - Risk marker first, then ONE sentence citing the affected scenario by its `Scenario:`/`Example:`/`Rule:` title with a clickable `feature-path:line`, describing the change in **UI/tester terms** ("the dropdown was replaced with an input + Verify button").
105
+ - Do NOT reference step-definition filenames, page objects, or source component filenames in the reasons — testers read feature files, not code. Source filenames may appear only in the coverage-gaps section when there is no feature to point to.
106
+ - **Hyperlink rule**: write feature paths as bare repo-relative paths in plain text (with `:line`) — NOT as `[label](path)` markdown links. Terminals auto-detect plain paths and make them ctrl+clickable; a markdown label hides the path and breaks that.
107
+ - No confidence column, no per-source-file table, no separate flat path list — the numbered paths ARE the list.
108
+
109
+ ## Step 5 — Stop
110
+
111
+ The report is the deliverable. Do NOT run any test, do NOT ask whether to run them — the QA reviews the report and runs files manually using the footer command. End the turn after printing the report.
@@ -29,7 +29,8 @@ Use `browser_evaluate` with a specific CSS selector or JS expression for all DOM
29
29
 
30
30
  ## Token Tracking
31
31
 
32
- Silent background task — follow the **Token Tracking** pattern in `SKILLS_CONTEXT.md`.
32
+ Optional and silent — follow the **Token Tracking** pattern in `SKILLS_CONTEXT.md`
33
+ (run its enablement check once at skill start; if disabled, skip every checkpoint silently).
33
34
  Checkpoints: `start` → `jira_fetch` → `ui_testing` → `test_execution` → `end + report + session`.
34
35
  Replace `CARD_ID` with the actual card ID. Never show tracking output to user.
35
36
 
@@ -55,32 +56,25 @@ Jira Card ID
55
56
 
56
57
  ---
57
58
 
58
- ## Phase 0 — Collect Card ID + Load Context
59
+ ## Phase 0 — Inputs
59
60
 
60
- Run token tracking `start` checkpoint.
61
+ Run token tracking `start` checkpoint (if enabled).
61
62
 
62
- If the user has not already provided a Jira card ID, ask:
63
- > "Please share the **Jira card ID** to begin (e.g. `PROJ-123`)."
63
+ **Invoked by qa-agent (parameter block present):** take `CARD_ID`, `APP_URL`, `LOGIN_URL`,
64
+ `FIGMA_URL`, `AUTO_APPROVE`, `CONTEXT_FILE` from the block. Read `.env` for `QA_USERNAME`,
65
+ `QA_PASSWORD`, `QA_OTP_CODE`. **Ask no setup questions — qa-agent already collected everything.**
66
+ (`FIGMA_URL: none` means `RUN_UI_TEST = false`.)
64
67
 
65
- Wait for the card ID.
68
+ **Standalone run:** resolve values in precedence order `.env` > product context > ask:
69
+ 1. Read `.env` → `QA_APP_URL`, `QA_LOGIN_URL`, `QA_USERNAME`, `QA_PASSWORD`, `QA_OTP_CODE`
70
+ 2. If the user gave no card ID, ask for it. Then derive the project key prefix
71
+ (`QE-89` → `QE`) and read `.claude/skills/qa-agent/product_context/{PREFIX}/context.md`
72
+ if it exists → fills any URL/OTP gaps (never credentials — those are `.env`-only)
73
+ 3. Ask ONE consolidated message for whatever is still missing (app URL, credentials,
74
+ Figma link or "skip UI comparison"). Never ask one-at-a-time; never ask for a value
75
+ you already have.
66
76
 
67
- **After card ID is known check for product context:**
68
-
69
- Derive the project key prefix (e.g. `QE-89` → `QE`) and check:
70
- ```
71
- .claude/skills/qa-agent/product_context/{PREFIX}/context.md
72
- ```
73
-
74
- **If context file exists:**
75
- - Read it and extract: `CTX_APP_URL`, `CTX_USERNAME`, `CTX_PASSWORD`, `CTX_LOGIN_URL`, `CTX_OTP`
76
- - Set `CONTEXT_LOADED = true`
77
- - Confirm one line: "Context loaded for {PRODUCT_NAME} — using saved URL and credentials."
78
-
79
- **If context file not found:**
80
- - Set `CONTEXT_LOADED = false`
81
- - Collect URL and credentials during Phase 1 as normal
82
-
83
- Then immediately proceed to Phase 1 — do not ask for anything else yet.
77
+ **Never print `QA_PASSWORD` to chat, reports, or hints files.**
84
78
 
85
79
  ---
86
80
 
@@ -106,23 +100,13 @@ After fetching, check `CARD_DESCRIPTION` length:
106
100
 
107
101
  Do NOT tell the user the description was truncated. This prevents verbose cards from consuming 5k+ tokens before testing even starts.
108
102
 
109
- If no AC found:
103
+ If no AC found (and qa-agent didn't already resolve this):
110
104
  > "No Acceptance Criteria found on this card. What should be tested?"
111
105
  Wait for user response before continuing.
112
106
 
113
- After fetch, ask these **one at a time**:
114
-
115
- **Question A UI Testing:**
116
- > "Do you want to compare the app against a Figma design before testing? (yes / no)"
117
-
118
- - If yes: ask for Figma URL (suggest `FIGMA_URL_FROM_CARD` if found), then app URL + credentials
119
- - If no: ask for app URL + credentials only
120
-
121
- Store:
122
- - `RUN_UI_TEST` — true/false
123
- - `FIGMA_URL` — if yes
124
- - `APP_URL` — full base URL of the app
125
- - `USERNAME`, `PASSWORD` — login credentials (ask only if not obvious from card)
107
+ Set from Phase 0 values (all input was collected there — do not re-ask):
108
+ - `RUN_UI_TEST` — true when a Figma URL is available (from parameter block, card, or user)
109
+ - `FIGMA_URL`, `APP_URL`, `USERNAME`, `PASSWORD`, `OTP_CODE`
126
110
 
127
111
  ---
128
112
 
@@ -206,7 +190,7 @@ ls .playwright-session.json 2>/dev/null && echo "SESSION_EXISTS" || echo "NO_SES
206
190
 
207
191
  **If OTP screen appears:**
208
192
  9. Click first OTP box → `browser_click`
209
- 10. `browser_type(text: "999999")` — always this value
193
+ 10. `browser_type(text: OTP_CODE)` — the `QA_OTP_CODE` value from `.env` (ask once if unset)
210
194
  11. Click verify → `browser_click`
211
195
  12. `browser_wait_for(state: "networkidle")`
212
196
 
@@ -285,7 +269,7 @@ For each test T-01, T-02, ...:
285
269
  7. Append to `HINTS.testCases`:
286
270
  ```
287
271
  { id: "T-N", name: "...", status: "PASS|FAIL|OBSERVATION|BLOCKED",
288
- actions: ["fill email", "click submit", "type OTP 999999"],
272
+ actions: ["fill email", "click submit", "type OTP"],
289
273
  url: "CURRENT_URL" }
290
274
  ```
291
275
 
@@ -315,7 +299,7 @@ Base URL: [BASE_URL]
315
299
 
316
300
  ## Environment
317
301
  App URL: [APP_URL]
318
- Login: [USERNAME] / [PASSWORD REDACTED]
302
+ Login: credentials in .env (never written here)
319
303
 
320
304
  ## Pages Visited
321
305
  | URL | Description |