@ia-qa/qa-discovery 0.2.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -243,7 +243,11 @@ The file it produces holds live cookies — whoever has it is logged in as you.
243
243
  npx ia-qa-discover coverage
244
244
  ```
245
245
 
246
- Reads local files only — no browser, no network, no argument. It compares the pages this scan found against the pages your suite was **observed** visiting, and ranks the gap by what each page takes as input: credentials, form submissions, required fields, API calls. The factors *are* the ranking — there is no score, because a single number invites tuning and hides that a page ranks high for a reason you may consider irrelevant.
246
+ Reads local files only — no browser, no network, no argument. It compares the pages this scan found against the pages your suite was **observed** visiting, and ranks the gap by what each page takes as input: credentials, form submissions, required fields. The factors *are* the ranking — there is no score, because a single number invites tuning and hides that a page ranks high for a reason you may consider irrelevant.
247
+
248
+ One factor comes from the other package: **how often a page has actually changed**, read from healing's run history. A page that changes every week and that no test visits is where bugs are born; a page untouched for six months does not need a new test — and no scan of an app can see the difference. Runs where more than half the mapped pages drifted at once are held out and counted: that describes a stale baseline or a changed capture, not volatile pages, and including them made every page carry the factor, which ranks nothing. Below three comparable runs the factor is simply absent, and the report says why.
249
+
250
+ How much a page *holds* — its field and call counts — is shown beside the factors and never counted with them. Describing a page and ranking it are two jobs: merged, `1 input · 1 API call` out-ranked a page that had actually changed three times.
247
251
 
248
252
  It also reports **depth**: how many of each visited page's contracted elements your tests actually name. Named is not asserted — a test that clicks a button names it without checking anything, and nothing on disk can tell the two apart, so this never says "tested".
249
253
 
@@ -261,6 +265,28 @@ Writes `.ia-qa-discovery/coverage-map.json` (committable, diffable) and refreshe
261
265
 
262
266
  They stay **counted and named** as out of scope, never silently dropped, and nothing is ever added to that list on its own.
263
267
 
268
+ ### `generate`
269
+
270
+ **A starting suite for the pages nothing tests — written so healing can repair it.**
271
+
272
+ ```bash
273
+ npx ia-qa-discover generate
274
+ ```
275
+
276
+ Writing test code is not the scarce thing; `playwright codegen` has done it for years. What it cannot do is decide *what* to record, and what nobody does is make the result survive the app changing. With no argument this generates one spec per page in the coverage gap — the pages that exist and that no test visits — and every locator it writes names an element the healing contract holds. So when a label changes, the file is **rewritten** instead of going red.
277
+
278
+ That loop is not a claim: it is executed on every commit, on this verb's own output — generated, drifted, repaired, resolving again, with no human edit.
279
+
280
+ **What it refuses to write, and why that is the feature.** Healing rewrites calls that state a role — `getByRole`, `getByLabel`, `getByPlaceholder`, `By.linkText` — and nothing else. `getByText` names a *string*, not an element, so nothing can prove the test meant the renamed button rather than a heading that never moved. And one such line does not merely stay unrepaired: it holds the verdict at BLOCK, which stops the repairable lines *beside* it from being repaired too. So a field that cannot be named by role, label or placeholder is left out, never written in a weaker form.
281
+
282
+ Left out for the same reason: a field with no test id, id or name. Its only selector is positional, and it addresses a different element the moment a field is inserted above it — untestable by anyone, not only by this tool. Each omission is named at the top of the file it was omitted from, because a silent gap reads as a finished test.
283
+
284
+ **The assertions are yours.** An application declares what it *accepts* — required, type, min, max — and never what it *promises*. "A refused card shows the right message" lives in someone's head, so the navigation and the actions are generated and what the app should *do* is a TODO with the question written out.
285
+
286
+ Files land in `.ia-qa-discovery/generated/` and nothing is added to your suite. An existing file is never replaced without `--force`. If the output directory is outside healing's `testPaths`, the verb says so and names both remedies — out of reach means never repaired, which would quietly make the whole promise false.
287
+
288
+ `--out <dir>` to write them where your suite lives, `--json` for a machine-readable summary, or name pages explicitly to generate for them anyway.
289
+
264
290
  ### `history`
265
291
 
266
292
  The trend no single scan can reconstruct: pages, forms, API surface, and what changed run over run.
package/ROADMAP.md CHANGED
@@ -245,6 +245,17 @@ by the classifier's intent", so the first half is not blocked on the second.
245
245
 
246
246
  ## Scenario generation (F3)
247
247
 
248
+ **Shipped, narrowly: `ia-qa-discover generate`.** Not scenario generation — *spec scaffolding
249
+ from the observed surface*. It writes one Playwright file per uncovered page, naming only
250
+ elements the healing contract holds, so the file is repaired rather than deleted when the app
251
+ moves; that loop runs on every commit against the verb's own output. It emits only calls
252
+ healing can rewrite (one `getByText` holds the verdict at BLOCK and blocks the repairable
253
+ lines beside it), skips fields with no durable identity and says so in the file, and writes no
254
+ assertion beyond what the app itself declares. What a submission *produces* stays a TODO.
255
+
256
+ That is the deterministic floor. Everything below — deriving *intent* rather than structure —
257
+ is still net-new, and still needs the grid.
258
+
248
259
  **The audit found the assumed inputs do not exist.** There is no closed grid of test
249
260
  patterns anywhere in the ecosystem to derive from — `QA_AGENT_RECIPES` and
250
261
  `AUGMENTED_QA_PLAYBOOK` are editorial content, not structured data. So the intent→scenario