@vijaypjavvadi/bdd2pw 4.3.2 → 4.4.1

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/CHANGELOG.md CHANGED
@@ -9,6 +9,229 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  _Nothing yet._
11
11
 
12
+ ## [4.4.1] — 2026-10-11
13
+
14
+ ### Theme: in-spec provenance comments + SemVer-covered contract
15
+
16
+ v4.4.0 recorded per-step provenance in the `*.spec.meta.json` sidecar.
17
+ v4.4.1 lifts that provenance into the emitted spec itself, so a reader
18
+ can tell at a glance (or a `grep`) which lane bound each step without
19
+ cross-referencing the sidecar.
20
+
21
+ ### Added — `// @bdd2pw` provenance comments
22
+
23
+ Every emitted step gets exactly one provenance comment as the first
24
+ line inside its `test.step` body:
25
+
26
+ ```typescript
27
+ await test.step("When I enter my ssn", async () => {
28
+ // @bdd2pw lane=rule rule=domain-03 pack=banking
29
+ await loginPage.ssnField.fill("123-45-6789");
30
+ });
31
+
32
+ await test.step("When I confirm with my recovery phrase", async () => {
33
+ // @bdd2pw lane=llm provider=anthropic model=claude-sonnet-4-6 cached=false governance=sanitised
34
+ await loginPage.recoveryField.fill("...");
35
+ });
36
+
37
+ await test.step("Then I should see a success animation", async () => {
38
+ // @bdd2pw lane=todo
39
+ // TODO: no rule matched: "Then I should see a success animation"
40
+ });
41
+ ```
42
+
43
+ ### Added — SemVer-covered grammar
44
+
45
+ The grammar is documented as a public contract in the new
46
+ `docs/PROVENANCE_CONTRACT.md`:
47
+
48
+ - One line per step. `// @bdd2pw` always starts the comment.
49
+ - Field order is fixed: `lane=` first, then (rule/pack) for the rule
50
+ lane, or (provider/model/cached/governance) for the llm lane.
51
+ - Field keys never change spelling.
52
+ - New fields may be appended at the end of their lane's block in a
53
+ minor release but never prepended or inserted.
54
+ - Removing a field is a major-version change.
55
+ - `cached` is lowercase `true`/`false`; `governance` is `sanitised`
56
+ (British spelling, matching the sidecar from v4.4.0).
57
+
58
+ ### Added — CLI + API
59
+
60
+ - `--no-provenance-comments` CLI flag suppresses the comments for
61
+ byte-stable comparison against pre-v4.4.1 output. Default: comments
62
+ are on.
63
+ - `ScaffoldOptions.provenanceComments?: boolean` programmatic
64
+ equivalent. Default: `true`.
65
+
66
+ ### Added — tests
67
+
68
+ - 11-case vitest suite in `tests/unit/v441ProvenanceComments.test.ts`
69
+ pinning the grammar: rule / llm / todo lanes, field ordering,
70
+ opt-out, one-comment-per-step on multi-step scenarios, legacy
71
+ binding fallback.
72
+ - 8-case Node.js smoke runner in `scripts/smoke-v441-provenance.mjs`.
73
+ - The new `docs/PROVENANCE_CONTRACT.md` describes the identical
74
+ schema for the sidecar's `rule` + `llm` blocks so parsers have one
75
+ reference for both forms.
76
+
77
+ ### No breaking changes
78
+
79
+ Additive-only. Scenarios scaffolded without `--llm` still emit
80
+ `// @bdd2pw lane=rule rule=...` for each rule-bound step; no sidecar
81
+ or spec-wide behaviour changes.
82
+
83
+ Users targeting byte-stable pre-v4.4.1 output (bench harness diffs,
84
+ golden file tests) pass `--no-provenance-comments` or
85
+ `provenanceComments: false` to opt out.
86
+
87
+ ### Contract note for upstream consumers
88
+
89
+ Per the attestqa integration reply dated 2026-10-11, the contents of
90
+ `docs/PROVENANCE_CONTRACT.md` are the authoritative schema for both
91
+ the in-spec comment and the `*.spec.meta.json` sidecar. Changes to
92
+ either are reflected in that document and announced in CHANGELOG.
93
+
94
+ ## [4.4.0] — 2026-09-26
95
+
96
+ ### Theme: legible provenance — which lane, which rule, which pack
97
+
98
+ v4.3 made the LLM fallback safe (governance sidecar, cache, three
99
+ providers, in-process healing). v4.4 makes it **legible**. A reader
100
+ of a generated suite should be able to tell — per scenario, per
101
+ step — where each line came from: a deterministic rule (with which
102
+ rule id and which pack), the LLM fallback (with which provider and
103
+ which model), or a person's hand-edit.
104
+
105
+ Two new CLIs land here:
106
+
107
+ - `bdd2pw quarantine-stats <repo>` splits the suite into a trusted
108
+ lane (only rule-bound scenarios) and a review lane (`@llm-generated`
109
+ scenarios) and reports both. Slice 1.
110
+ - `bdd2pw coverage <repo>` turns the same provenance data into
111
+ decisions — which rules earned their place in the table, which
112
+ packs pulled their weight, which locators keep needing to heal.
113
+ Slice 2.
114
+
115
+ Both write JSON sidecars (`artefacts/quarantine-stats.json`,
116
+ `artefacts/coverage.json`) with a shared shape on the fields they
117
+ have in common, so a dashboard can consume either without switching
118
+ schemas. Both are reports, not gates — they exit non-zero only on a
119
+ real I/O error against the repo root.
120
+
121
+ ### Added — `--spec-name <stem>` for consumer-controlled spec filenames
122
+
123
+ Upstream consumers (attestqa, custom orchestrators) that keep one
124
+ feature file per epic and expect `tests/<feature-stem>.spec.ts`
125
+ regardless of which POM the feature targets can now override the
126
+ emitted spec filename.
127
+
128
+ ```bash
129
+ bdd2pw scaffold features/epic-scrum-5-customer-account-access.feature \
130
+ --url https://... \
131
+ --page LoginPage \
132
+ --repo ./out \
133
+ --spec-name epic-scrum-5-customer-account-access
134
+ # → tests/epic-scrum-5-customer-account-access.spec.ts
135
+ ```
136
+
137
+ Programmatic API: `ScaffoldOptions.specName?: string`. When set, the
138
+ spec file is written to `tests/<specName>.spec.ts` and the
139
+ `*.spec.meta.json` sidecar follows the same stem. The POM filename,
140
+ class name, and `../pages/<pomStem>` import path are unaffected.
141
+
142
+ Trailing `.spec.ts` / `.spec` suffixes are tolerated so callers can
143
+ pass either form. Empty / whitespace-only values fall back to the
144
+ historical POM-derived default. Default behavior (`specName` unset
145
+ or omitted) is byte-identical to v4.3 — zero risk to existing users.
146
+
147
+ ### Added — Slice 1: LLM quarantine lane
148
+
149
+ - **`@llm-generated` scenario tag.** Any scenario whose emission
150
+ used the LLM for at least one step is emitted with the tag next to
151
+ its existing tags. That's all the wiring needed to filter runs
152
+ with Playwright's own `--grep-invert @llm-generated` (trusted lane)
153
+ or `--grep @llm-generated` (review lane).
154
+ - **Per-step provenance in `*.spec.meta.json`.** Rule-bound steps
155
+ carry `"rule": { "ruleId", "pack"? }`. LLM-bound steps carry
156
+ `"rule": null` plus `"llm": { provider, model, cached, governance,
157
+ at }`. Nothing about a scenario's binding is guessed from text
158
+ anymore; it's recorded at the source.
159
+ - **`bdd2pw quarantine-stats <repo>` CLI.** Reports per feature and
160
+ per repo: scenarios (total / `@llm-generated` / deterministic),
161
+ steps (by rule / by LLM), LLM cache-hit share, and promotions
162
+ (candidate step-texts recorded in `candidate-rules.jsonl` that
163
+ are no longer LLM-bound because a rule now covers them). `--json`
164
+ for CI, human table by default.
165
+
166
+ ### Added — Slice 2: Rule + pack coverage
167
+
168
+ - **`bdd2pw coverage <repo>` CLI.** Reads sidecars +
169
+ `candidate-rules.jsonl` + `heal-events.jsonl` (both v4.2
170
+ `artefacts/` and v4.3 `.pwheal/` locations). Reports:
171
+ - **rule hit rate** — per rule, how many steps it bound, plus up
172
+ to 3 sample step texts.
173
+ - **dead rules** — every registry rule that did NOT fire in this
174
+ repo. Repo-scoped observation, not a global verdict.
175
+ - **per-pack hit rate** — which domain packs pulled their weight;
176
+ packs whose rules all died appear under `packs.dead`.
177
+ - **promotion trail** — same shape as `quarantine-stats.promotions`.
178
+ - **heal pressure** — top locators from the heal-events log; a
179
+ rule that binds and then always needs healing is worse than no
180
+ rule.
181
+ - **`--suggest-retire`** prints a copyable stanza listing dead
182
+ packs and dead rules. Never edits `stepMatcher.ts` or any config.
183
+ - **`--domains <list>`** matches the scaffold's flag so the
184
+ ruleId ↔ pack mapping the coverage report uses agrees with what
185
+ the sidecar would have written.
186
+ - **Cross-report agreement** — `coverage.totals` and
187
+ `coverage.promotions` are byte-identical to the same-named blocks
188
+ in `quarantine-stats.json` on the same repo. Locked by a property
189
+ test.
190
+
191
+ ### Added — provenance surface (foundation for both slices)
192
+
193
+ - **`StepBinding.provenance?: { source: "rule" \| "llm", ... }`.**
194
+ New optional field on the internal binding shape. Rule provenance
195
+ carries `ruleId` (matches `ruleIdFor()` — e.g. `"rule-14"`,
196
+ `"domain-03"`) and `pack` when the rule is domain-scoped. LLM
197
+ provenance carries provider / model / cached / governance / at.
198
+ - **`matchStep()` decorates every rule-produced binding** with its
199
+ ruleId + pack on the way out. No rule build() callback had to
200
+ change.
201
+ - **`llmStepMatcher.matchStepWithLLM` and `matchScenarioWithLLM`
202
+ decorate every LLM binding** (both per-step and batch paths)
203
+ with the same shape. The candidate-rules writer's hard-coded
204
+ `provider: "anthropic"` is fixed — it now reflects the actual
205
+ client used.
206
+ - **`LLMClient.providerName()` + `governanceSkipped()`** accessors
207
+ on the client interface, implemented for all three providers
208
+ (Anthropic, OpenAI, Gemini). Optional for backwards compat.
209
+ - **`listAllRuleIds()`** — new public export from
210
+ `transformers/stepMatcher.ts`. Returns the ordered registry list
211
+ (core + active domain packs) so the coverage CLI can compute the
212
+ dead-rule set.
213
+
214
+ ### Added — tests
215
+
216
+ - 7-case vitest suite in `tests/unit/v440QuarantineLane.test.ts`
217
+ covering all five Slice 1 acceptance criteria plus a malformed-
218
+ sidecar bonus.
219
+ - 5-case vitest suite in `tests/unit/v440Coverage.test.ts` covering
220
+ all four Slice 2 acceptance criteria plus a heal-pressure sort case.
221
+ - 6-case Node.js smoke runner in `scripts/smoke-v440-quarantine.mjs`.
222
+ - 5-case Node.js smoke runner in `scripts/smoke-v440-coverage.mjs`.
223
+
224
+ ### No breaking changes
225
+
226
+ Additive-only. Users NOT using `--llm` see identical scaffold output
227
+ to v4.3 (no provenance block, no `@llm-generated` tag, no `llm`
228
+ entries in the sidecar). Users NOT calling `quarantine-stats` or
229
+ `coverage` see no change. Existing consumers of the meta-sidecar
230
+ tolerate the new optional `rule` and `llm` fields; the shape is
231
+ strictly a superset of v4.3.
232
+
233
+ Slice 3 (mobile dialect domain pack) moves to v4.5.0.
234
+
12
235
  ## [4.3.2] — 2026-09-18
13
236
 
14
237
  ### Fixed
package/README.md CHANGED
@@ -25,7 +25,7 @@ Most teams writing BDD test cases (via Cucumber `.feature` files, possibly autho
25
25
 
26
26
  Point it at a `.feature` file and a URL. It parses the Gherkin, scans the live page with Chromium, picks the most stable locator for every interactive element, matches each step to a POM method call, and emits a runnable Playwright TypeScript repo — including `playwright.config.ts`, `pages/login.page.ts`, `tests/login.spec.ts`, and a `BDD_REVIEW.md` listing anything a human still needs to look at.
27
27
 
28
- ## What `bdd2pw` is and isn't (as of v4.3.0)
28
+ ## What `bdd2pw` is and isn't (as of v4.4.0)
29
29
 
30
30
  `bdd2pw` is a **deterministic scaffolder with an optional governed LLM fallback across three providers**. The output is honest about its limits:
31
31
 
@@ -41,6 +41,7 @@ Point it at a `.feature` file and a URL. It parses the Gherkin, scans the live p
41
41
  - **Six-pattern LLM-binding rewriter** (v4.1) — mechanically transforms common LLM emission mistakes (invented-helper shapes, bare-field args, unquoted string values, CSS-selector args, `page.<method>` invented-helpers in customBody, Locator-only matchers hallucinated on `page`, bare-identifier assertion locators) into valid Playwright-idiomatic code. Runs *before* the v4.0.1 gates; if a rewrite would still produce broken code, the binding is rejected and lands as TODO. Bench result: 3/8 → **8/8 apps produce specs that pass `tsc --noEmit`**. Locked by 35 unit tests.
42
42
  - **DOM-drift detection via POM header hash** (v4.2) — every emitted POM carries a `@bdd2pw dom-hash` comment with a stable sha256 of the page's accessibility tree. On re-scaffold, bdd2pw diffs the new snapshot against the stored hash. Silent UI changes surface as a `DOM DRIFT` warning in `BDD_REVIEW.md` with both hashes and a suggested triage path. `--fail-on-drift` turns it into a non-zero exit code so CI can gate merges on silent UI regressions.
43
43
  - **In-process self-healing locators via `@vijaypjavvadi/pw-self-heal`** (v4.3) — `--self-healing` emits a 3-line `tests/fixtures.ts` that wraps the base `test` with `withSelfHealing({ mode })`. Every spec's top-of-file import auto-rewrites to pull `test` + `expect` from `./fixtures` instead of `@playwright/test` directly. POM classes are unchanged; healing is transparent. Ranker: trained ONNX model with a published Zenodo DOI ([10.5281/zenodo.19684439](https://doi.org/10.5281/zenodo.19684439)), GB AUC 0.9993, three modes (`heuristic` / `ml` / `hybrid`). No server, no API key, no Python — the DOM never leaves the machine.
44
+ - **Legible provenance — `@llm-generated` tag + rule attribution + two report CLIs** (v4.4) — every emitted step records which rule (or which LLM provider + model) produced it in `*.spec.meta.json`. A scenario with an LLM-bound step gets the `@llm-generated` tag so `npx playwright test --grep-invert @llm-generated` runs the trusted lane. `bdd2pw quarantine-stats` reports scenarios / steps / cache-hit share / promotions per lane. `bdd2pw coverage` turns the same data into decisions: rule hit rate, dead rules, dead packs, promotion trail (candidate → rule → firing), and heal pressure. Both write JSON sidecars with a shared shape. Both are reports, not gates.
44
45
  - **Data-driven scaffolds** (v4.0.0) — `--data <path>` injects CSV / JSON / XLSX rows into every Scenario Outline's `Examples:` table; `--gen-data --schema <path> --rows N` generates synthetic rows via Faker + optional per-column LLM calls (`llm:auto insurance claim description`); seeded (`--seed 42`) for reproducibility.
45
46
  - **`updatePom` is append-only by construction.** Re-scanning a page that already has a Page Object adds new locators only. Hand-edited method bodies, custom helper methods, custom imports are all preserved byte-identical.
46
47
  - **`--merge` mode** (v3.2) preserves `// bdd2pw:user-block id="..."` sections across regenerations so iterative locator tuning doesn't lose work.
@@ -121,6 +122,62 @@ bdd2pw scaffold ./my.feature \
121
122
 
122
123
  Every successful LLM-binding is appended to `<repo>/artefacts/candidate-rules.jsonl` so an offline review pipeline can propose new deterministic rules. Auto-write back to `stepMatcher.ts` is deferred to v2.1+ — for v2.0 the LLM is a runtime overlay, never a code generator for the matcher itself.
123
124
 
125
+ ### Two-lane runs — trusted vs review (v4.4+)
126
+
127
+ A scenario in which at least one step was bound by the LLM fallback is emitted with a `@llm-generated` tag next to its existing tags. That lets Playwright's own `--grep`/`--grep-invert` filter split every run into two lanes with zero framework wiring:
128
+
129
+ ```bash
130
+ # Trusted lane — only scenarios whose every step was rule-bound
131
+ npx playwright test --grep-invert @llm-generated
132
+
133
+ # Review lane — only the scenarios that used the LLM fallback
134
+ npx playwright test --grep @llm-generated
135
+ ```
136
+
137
+ Per-step provenance lives in the sidecar `<spec>.spec.meta.json` next to the emitted spec. LLM-bound steps carry `"rule": null` plus an `"llm": { provider, model, cached, governance, at }` block; rule-bound steps carry neither field. Everything the tag hides at scenario level is inspectable at step level.
138
+
139
+ Aggregate a scaffolded repo with:
140
+
141
+ ```bash
142
+ npx bdd2pw quarantine-stats ./my-tests # table + writes artefacts/quarantine-stats.json
143
+ npx bdd2pw quarantine-stats ./my-tests --json # machine-readable, same shape as the file
144
+ ```
145
+
146
+ Sample table output:
147
+
148
+ ```
149
+ scenarios: 24 total · 21 deterministic · 3 @llm-generated
150
+ steps: 58 total · 55 by rule · 3 by LLM
151
+ LLM cache hit share: 66.7%
152
+
153
+ promotions: 2/9 candidate step(s) now rule-bound
154
+ ```
155
+
156
+ The `promotions` line is the story: candidate step-texts recorded in `artefacts/candidate-rules.jsonl` from earlier runs that no longer need the LLM because a deterministic rule now covers them. That number going up is the point of running the LLM at all — a scaffold, then a rule, then no LLM.
157
+
158
+ `quarantine-stats` is a report, not a gate. It exits 0 on every clean read and only fails with a non-zero code on a real I/O error against the repo root. Wire it into your CI dashboard, don't wire it into your merge gate.
159
+
160
+ ### Rule + pack coverage (v4.4+)
161
+
162
+ Slice 1 tells you which lane a step is in. Coverage tells you which rules earned their place in the table:
163
+
164
+ ```bash
165
+ npx bdd2pw coverage ./my-tests --domains banking,retail
166
+ npx bdd2pw coverage ./my-tests --json
167
+ npx bdd2pw coverage ./my-tests --suggest-retire
168
+ ```
169
+
170
+ The report answers four things:
171
+
172
+ - **rule hit rate** — for every rule that fired, how many steps it bound, plus up to 3 sample step texts.
173
+ - **dead rules / dead packs** — every rule in the current registry that did NOT fire in this repo, and every domain pack whose rules were all dead. "Dead here" is a repo-scoped observation, not a global verdict on the rule.
174
+ - **promotion trail** — same field as `quarantine-stats`. Candidate steps recorded by past LLM fallbacks that are now bound by a rule.
175
+ - **heal pressure** — top locators from `artefacts/heal-events.jsonl` (or `.pwheal/heal-events.jsonl` when running with the v4.3 in-process healer). A rule that binds and then always needs healing is worse than no rule.
176
+
177
+ `--suggest-retire` prints a copyable stanza listing the dead packs and dead rules; it never edits `stepMatcher.ts` or your bdd2pw config. Paste the parts you want to apply.
178
+
179
+ The `totals` and `promotions` blocks in `coverage.json` are byte-identical to the same-named blocks in `quarantine-stats.json`, so a dashboard reading either one gets the same numbers.
180
+
124
181
  ### Governance sanitization (mandatory by default)
125
182
 
126
183
  Per the platform contract, **every prompt passes through the `ai-governance` sidecar's `/sanitize` endpoint** before reaching Anthropic. This scrubs API keys, JWTs, AWS creds, and other secrets that might leak via test data in the `.feature` file. **Fail-closed** — if the sidecar is unreachable, the LLM call is REFUSED and the step falls back to TODO.
@@ -368,20 +425,19 @@ output/
368
425
  | v4.0.1 | LLM hallucination gates | Three-layer rejector for invented POM helpers — bindings that would compile-fail land as TODO instead of broken code. 19 unit tests lock the behaviour. |
369
426
  | v4.1.0 | LLM binding rewriter | Six-pattern rewriter that mechanically fixes common LLM emission mistakes (invented helpers, bare-field args, CSS-selector args, `page.<method>` in customBody, hallucinated Page matchers, bare-identifier assertion locators). Bench result: 3/8 → **8/8 apps produce specs that pass `tsc --noEmit`**. Peer-reviewed publication in Elsevier SoftwareX. |
370
427
  | v4.2.0 | DOM-drift detection | Every emitted POM carries a `@bdd2pw dom-hash` header (sha256 of the accessibility tree). Re-scaffold diffs against the stored hash and surfaces silent UI changes in `BDD_REVIEW.md`. `--fail-on-drift` CLI flag exits non-zero when drift is detected (CI merge gate). |
371
- | **v4.3.0 (current)** | pw-self-heal integration | `--self-healing` swaps the v4.2 lib/heal.ts + external service shim for `@vijaypjavvadi/pw-self-heal` — trained ONNX ranker (Zenodo DOI 10.5281/zenodo.19684439), in-process, no server. Emits a 3-line `tests/fixtures.ts`; POM classes unchanged. `--legacy-healing` keeps v4.2 behaviour for one release. |
428
+ | v4.3.0 | pw-self-heal integration | `--self-healing` swaps the v4.2 lib/heal.ts + external service shim for `@vijaypjavvadi/pw-self-heal` — trained ONNX ranker (Zenodo DOI 10.5281/zenodo.19684439), in-process, no server. Emits a 3-line `tests/fixtures.ts`; POM classes unchanged. `--legacy-healing` keeps v4.2 behaviour for one release. |
429
+ | **v4.4.0 (current)** | Legible provenance | `@llm-generated` scenario tag + rule/pack attribution recorded in `*.spec.meta.json`. Two report CLIs: `bdd2pw quarantine-stats` splits the suite into trusted vs review lanes; `bdd2pw coverage` reports rule hit rate, dead rules, dead packs, promotion trail, and heal pressure. Reports, not gates. |
372
430
 
373
431
  ### Next 6 months (Oct 2026 → Mar 2027, ~1 release/month)
374
432
 
375
433
  | Target | Version | Theme | Headline |
376
434
  |---|---|---|---|
377
- | Oct 2026 | **v4.4.0** | LLM quarantine lane | `@llm-generated` Playwright tag on every LLM-derived scenario + `bdd2pw quarantine-stats` CLI that reports pass rate for the LLM-fallback lane separately from the deterministic lane. Teams can filter runs with `--grep-invert @llm-generated` for a "trusted only" execution. |
378
- | Nov 2026 | **v4.5.0** | sel2pw merge | sel2pw migrated onto `@vijaypjavvadi/pw-emit` — three packages share one emitter. All future emitter improvements automatically flow to Selenium users. |
379
- | Oct 2026 | **v4.5.0** | Auto-rules | `bdd2pw apply-proposals --interactive` — walks the human through each v3.6 proposal, validates the regex compiles + matches the sample texts, optionally appends to `stepMatcher.ts`. Closes the propose-rules loop. |
380
- | Nov 2026 | **v4.6.0** | Domain packs | Three more opt-in packs: **fintech** (KYC, AML, trading desks), **real-estate** (MLS, listings, escrow), **hospitality** (PMS, reservations, OTA). ~60 more rules. |
381
- | Nov 2026 | **v4.7.0** | API v2 | WebSocket assertion rules, multipart file-upload patterns, GraphQL query / mutation / subscription rules. Extends v3.0's API testing surface. |
382
- | Dec 2026 | **v4.8.0** | Coverage analyzer | `bdd2pw coverage` CLI: which deterministic rules fired on which features across a fleet, per-pack hit rate, dead-rule report, suggestion to retire unused rules. |
383
- | Jan 2027 | **v4.9.0** | CI/CD templates | Optional scaffolder output: GitHub Actions / GitLab CI / Azure Pipelines / CircleCI starter workflows wired to run the generated specs. Opt-in via `--ci <provider>`. |
384
- | Feb 2027 | **v5.0.0** | Mobile dialect | Touch / swipe / scroll-into-view rules + responsive viewport assertions. Reuses the same emitter pipeline; opt-in via `domains: ["mobile"]`. Bumps to v5 alongside a small set of default flips (llm-stats + healing become opt-out). Migration guide ships alongside. |
435
+ | Oct 2026 | **v4.5.0** | Mobile dialect | New `mobile` domain pack. Touch / swipe / scroll-into-view rules + responsive viewport assertions. Reuses the existing emitter pipeline; opt-in via `domains: ["mobile"]`. Scenarios tagged `@mobile` scaffold against a mobile device descriptor (Pixel 7 by default). |
436
+ | Nov 2026 | **v4.6.0** | sel2pw merge | sel2pw migrated onto `@vijaypjavvadi/pw-emit` — three packages share one emitter. All future emitter improvements automatically flow to Selenium users. |
437
+ | Nov 2026 | **v4.7.0** | Auto-rules | `bdd2pw apply-proposals --interactive` — walks the human through each v3.6 proposal, validates the regex compiles + matches the sample texts, optionally appends to `stepMatcher.ts`. Closes the propose-rules loop. |
438
+ | Dec 2026 | **v4.8.0** | Domain packs (3 more) | **fintech** (KYC, AML, trading desks), **real-estate** (MLS, listings, escrow), **hospitality** (PMS, reservations, OTA). ~60 more rules. |
439
+ | Jan 2027 | **v4.9.0** | API v2 | WebSocket assertion rules, multipart file-upload patterns, GraphQL query / mutation / subscription rules. Extends v3.0's API testing surface. |
440
+ | Feb 2027 | **v5.0.0** | CI/CD templates + default flips | Optional scaffolder output: GitHub Actions / GitLab CI / Azure Pipelines / CircleCI starter workflows wired to run the generated specs (opt-in via `--ci <provider>`). Bumps to v5 alongside a small set of default flips (llm-stats + healing become opt-out). Migration guide ships alongside. |
385
441
 
386
442
  Each release is shaped to be self-contained, ship in ~2 weeks, and keep `domains: []` byte-stable for existing users so the upgrade path stays painless.
387
443
 
package/dist/cli.js CHANGED
@@ -43,6 +43,9 @@ const path = __importStar(require("path"));
43
43
  const index_1 = require("./index");
44
44
  const llm_1 = require("./llm");
45
45
  const healStats_1 = require("./reports/healStats");
46
+ const quarantineStats_1 = require("./reports/quarantineStats");
47
+ const coverage_1 = require("./reports/coverage");
48
+ const stepMatcher_1 = require("./transformers/stepMatcher");
46
49
  const logger_1 = require("./utils/logger");
47
50
  const program = new commander_1.Command();
48
51
  program
@@ -57,6 +60,8 @@ program
57
60
  .requiredOption("--page <Name>", "Page Object class name (PascalCase)")
58
61
  .requiredOption("--repo <dir>", "Target Playwright TS repo (created if missing)")
59
62
  .option("--pages <list>", "Comma-separated list of additional Page Object names")
63
+ .option("--spec-name <stem>", "v4.4.0 — override the emitted spec filename stem. Writes `tests/<stem>.spec.ts` instead of the default POM-derived name (e.g. `login.spec.ts` from `LoginPage`). Useful when one feature file maps to one spec regardless of which POM it targets (attestqa, epic-per-feature layouts).")
64
+ .option("--no-provenance-comments", "v4.4.1 — suppress the per-step `// @bdd2pw lane=... [...]` provenance comments. Default: provenance comments are ON. Only disable for byte-stable pre-v4.4.1 output comparisons.")
60
65
  .option("--storage-state <path>", "Pre-authenticated storage state JSON")
61
66
  .option("--headed", "Show browser during MCP scan", false)
62
67
  .option("--snapshot-file <path>", "Read elements from a JSON file instead of launching a browser")
@@ -135,6 +140,11 @@ program
135
140
  page: opts.page,
136
141
  repo: path.resolve(opts.repo),
137
142
  pages: opts.pages?.split(",").map((s) => s.trim()),
143
+ // v4.4.0 — attestqa integration: let the caller name the spec file.
144
+ specName: typeof opts.specName === "string" ? opts.specName : undefined,
145
+ // v4.4.1 — attestqa provenance contract. Commander negates
146
+ // `--no-provenance-comments` into `opts.provenanceComments=false`.
147
+ provenanceComments: opts.provenanceComments !== false,
138
148
  storageState: opts.storageState,
139
149
  headed: opts.headed,
140
150
  llm: opts.llm,
@@ -311,6 +321,79 @@ program
311
321
  * and the candidate selectors that got promoted. Run after
312
322
  * `npx playwright test` in CI to track self-healing ROI per test run.
313
323
  */
324
+ program
325
+ .command("quarantine-stats")
326
+ .description("v4.4.0 Slice 1 — aggregate LLM-provenance data (spec.meta.json sidecars + candidate-rules.jsonl) into a per-feature quarantine-lane report. Writes <repo>/artefacts/quarantine-stats.json.")
327
+ .argument("<repo>", "Path to the scaffolded test repo (contains tests/ and artefacts/).")
328
+ .option("--out <path>", "Where to write quarantine-stats.json. Defaults to <repo>/artefacts/quarantine-stats.json.")
329
+ .option("--json", "Print the report as JSON to stdout instead of the table.", false)
330
+ .action(async (repo, raw) => {
331
+ try {
332
+ const pkgVersion = require("../package.json").version;
333
+ const { stats, outputPath } = await (0, quarantineStats_1.analyseQuarantineStats)({
334
+ repo: path.resolve(repo),
335
+ version: pkgVersion,
336
+ outputPath: raw.out,
337
+ });
338
+ if (raw.json === true) {
339
+ process.stdout.write(JSON.stringify(stats, null, 2) + "\n");
340
+ }
341
+ else {
342
+ process.stdout.write((0, quarantineStats_1.renderQuarantineStatsTable)(stats));
343
+ process.stdout.write(`\nquarantine-stats: wrote ${outputPath}\n`);
344
+ }
345
+ }
346
+ catch (err) {
347
+ logger_1.logger.error({ err }, "quarantine-stats: read error");
348
+ process.exit(1);
349
+ }
350
+ });
351
+ program
352
+ .command("coverage")
353
+ .description("v4.4.0 Slice 2 — rule + pack hit rate, dead rules, promotion trail, heal pressure. Reads spec.meta.json + candidate-rules.jsonl + heal-events.jsonl. Writes <repo>/artefacts/coverage.json.")
354
+ .argument("<repo>", "Path to the scaffolded test repo (contains tests/ and artefacts/).")
355
+ .option("--out <path>", "Where to write coverage.json. Defaults to <repo>/artefacts/coverage.json.")
356
+ .option("--json", "Print the report as JSON to stdout instead of the table.", false)
357
+ .option("--suggest-retire", "Print a copyable stanza listing dead packs + rules for this repo. Never edits anything.", false)
358
+ .option("--domains <list>", "Comma-separated domain packs to consider active (matches the scaffold's --domains flag). Empty = core rules only. Affects the dead-rules calculation.")
359
+ .action(async (repo, raw) => {
360
+ try {
361
+ // Match the scaffold's --domains behaviour so the ruleId ↔ pack
362
+ // mapping the coverage report uses agrees with what the sidecar
363
+ // would have written.
364
+ const domainList = raw.domains
365
+ ? raw.domains
366
+ .split(",")
367
+ .map((s) => s.trim())
368
+ .filter(Boolean)
369
+ : undefined;
370
+ if (domainList) {
371
+ // Best-effort — invalid names are silently dropped by setActiveDomains.
372
+ (0, stepMatcher_1.setActiveDomains)(domainList);
373
+ }
374
+ const pkgVersion = require("../package.json").version;
375
+ const { coverage, outputPath } = await (0, coverage_1.analyseCoverage)({
376
+ repo: path.resolve(repo),
377
+ version: pkgVersion,
378
+ outputPath: raw.out,
379
+ registryRuleIds: (0, stepMatcher_1.listAllRuleIds)(),
380
+ });
381
+ if (raw.json === true) {
382
+ process.stdout.write(JSON.stringify(coverage, null, 2) + "\n");
383
+ }
384
+ else if (raw.suggestRetire === true) {
385
+ process.stdout.write((0, coverage_1.renderSuggestRetire)(coverage));
386
+ }
387
+ else {
388
+ process.stdout.write((0, coverage_1.renderCoverageTable)(coverage));
389
+ process.stdout.write(`\ncoverage: wrote ${outputPath}\n`);
390
+ }
391
+ }
392
+ catch (err) {
393
+ logger_1.logger.error({ err }, "coverage: read error");
394
+ process.exit(1);
395
+ }
396
+ });
314
397
  program
315
398
  .command("heal-stats")
316
399
  .description("Aggregate <repo>/artefacts/heal-events.jsonl into a heal-stats.json sidecar.")
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -63,6 +63,17 @@ export interface EmitTestFileInput {
63
63
  * see optional-chained no-ops. See TestForge handoff Issue 4.
64
64
  */
65
65
  stepHooks?: boolean;
66
+ /**
67
+ * v4.4.1 — emit a one-line `// @bdd2pw` provenance comment above
68
+ * every binding statement inside each `test.step` body. The comment
69
+ * grammar is documented in `docs/PROVENANCE_CONTRACT.md` and
70
+ * SemVer-covered — field names and order are stable; adding fields
71
+ * is a minor bump, removing fields is a major bump.
72
+ *
73
+ * Default: true. Opt-out by passing false here or `--no-provenance-comments`
74
+ * at the CLI.
75
+ */
76
+ provenanceComments?: boolean;
66
77
  /**
67
78
  * v3.1.0 — opt-in step boundary markers. When true, each `test.step` is
68
79
  * bracketed by `// bdd2pw:step-open id="NNNN" title="..."` and
@@ -119,6 +119,9 @@ function emitTestFile(input) {
119
119
  stepHooks: input.stepHooks === true,
120
120
  stepMarkers: input.stepMarkers === true,
121
121
  fixtures: defaultFixtures,
122
+ // v4.4.1 — provenance comments default ON. Callers that need
123
+ // byte-stable pre-v4.4.1 output pass `false`.
124
+ provenanceComments: input.provenanceComments !== false,
122
125
  };
123
126
  const ir = {
124
127
  describeName: input.describeName,
@@ -215,6 +218,15 @@ function bindingsToBody(bindings, prelude = [], options = {}) {
215
218
  // buffer is wrapped in try/catch/finally below; otherwise it's
216
219
  // emitted directly inside the test.step arrow.
217
220
  const bodyLines = [];
221
+ // v4.4.1 — provenance comment. Emitted ONCE per step as the first
222
+ // body line, directly before the binding statement(s). Grammar is
223
+ // SemVer-locked (see docs/PROVENANCE_CONTRACT.md). The comment is
224
+ // always present when provenanceComments is on, even for TODO
225
+ // steps — attestqa and other orchestrators rely on being able to
226
+ // grep every step's lane.
227
+ if (options.provenanceComments) {
228
+ bodyLines.push(formatProvenanceComment(b, isTodo));
229
+ }
218
230
  if (b.customBody) {
219
231
  // Compound step — body has multiple statements pre-rendered.
220
232
  // v2.2.5 — sanitize digit-leading POM references that may have been
@@ -297,4 +309,64 @@ function bindingsToBody(bindings, prelude = [], options = {}) {
297
309
  lines.pop();
298
310
  return lines.join("\n");
299
311
  }
312
+ /**
313
+ * v4.4.1 — format the per-step `// @bdd2pw` provenance comment.
314
+ *
315
+ * Grammar (SemVer-covered — see `docs/PROVENANCE_CONTRACT.md`):
316
+ *
317
+ * provenance-comment = "// @bdd2pw" SP field *(SP field)
318
+ * field = lane-field | rule-field | pack-field
319
+ * | provider-field | model-field | cached-field | governance-field
320
+ * lane-field = "lane=" ( "rule" | "llm" | "todo" )
321
+ * rule-field = "rule=" ident ; required when lane=rule
322
+ * pack-field = "pack=" pack-name ; present iff rule came from a domain pack
323
+ * provider-field = "provider=" ( "anthropic" | "openai" | "gemini" ) ; required when lane=llm
324
+ * model-field = "model=" ident
325
+ * cached-field = "cached=" ( "true" | "false" )
326
+ * governance-field = "governance=" ( "sanitised" | "skipped" )
327
+ *
328
+ * Rules the parser can rely on:
329
+ * - One line per step; `// @bdd2pw` is always first on the line.
330
+ * - Field order fixed: lane first; then rule/pack for the rule lane,
331
+ * or provider/model/cached/governance for the llm lane.
332
+ * - Field keys never change spelling.
333
+ * - New fields may be appended at the end of their lane's block in a
334
+ * minor release but never prepended or inserted.
335
+ * - Removing a field is a major-version change.
336
+ * - `lane=todo` has no other fields.
337
+ *
338
+ * Fallbacks:
339
+ * - A binding with no `provenance` is treated as `lane=rule` with no
340
+ * rule id (unknown rule, pre-v4.4 cached binding, etc.) — the comment
341
+ * line is just `// @bdd2pw lane=rule` which still records the lane.
342
+ * - A TODO step always serialises as `lane=todo` regardless of what
343
+ * stale provenance a half-filled binding carries.
344
+ */
345
+ function formatProvenanceComment(b, isTodo) {
346
+ if (isTodo)
347
+ return "// @bdd2pw lane=todo";
348
+ const prov = b.provenance;
349
+ if (!prov)
350
+ return "// @bdd2pw lane=rule";
351
+ if (prov.source === "llm" && prov.llm) {
352
+ const parts = [
353
+ "// @bdd2pw",
354
+ "lane=llm",
355
+ `provider=${prov.llm.provider}`,
356
+ `model=${prov.llm.model}`,
357
+ `cached=${prov.llm.cached ? "true" : "false"}`,
358
+ `governance=${prov.llm.governance}`,
359
+ ];
360
+ return parts.join(" ");
361
+ }
362
+ if (prov.source === "rule") {
363
+ const parts = ["// @bdd2pw", "lane=rule"];
364
+ if (prov.ruleId)
365
+ parts.push(`rule=${prov.ruleId}`);
366
+ if (prov.pack)
367
+ parts.push(`pack=${prov.pack}`);
368
+ return parts.join(" ");
369
+ }
370
+ return "// @bdd2pw lane=rule";
371
+ }
300
372
  //# sourceMappingURL=facade.js.map