@ia-qa/self-healing 1.7.23 → 1.7.25
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 +42 -8
- package/dist/cli/ingest.js +21 -3
- package/dist/cli/ingest.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -24,7 +24,12 @@ Ships a **CLI**, a **local MCP server** for AI agents, and an accessibility-tree
|
|
|
24
24
|
|
|
25
25
|
## See it work
|
|
26
26
|
|
|
27
|
-
[](https://www.ia-qa.com/media/heal-demo.mp4)
|
|
28
|
+
|
|
29
|
+
▶ **[Watch the full 48-second video](https://www.ia-qa.com/media/heal-demo.mp4)** — the loop above
|
|
30
|
+
starts one step earlier, from a red build: `explain` tells you which failures are drift and which
|
|
31
|
+
one is **not**, then covers whether the app you mapped is sound at all, the MCP server answering
|
|
32
|
+
an agent, and the HTML report `--report` writes for a PR.
|
|
28
33
|
|
|
29
34
|
`ia-qa-heal run` runs your suite, watches it break, diffs the live app against your baseline,
|
|
30
35
|
rewrites the dead selectors, then **re-runs the suite to verify** and exits on that verdict.
|
|
@@ -33,15 +38,13 @@ style your suite already uses — CSS stays CSS. The demo adds `--locators`, whi
|
|
|
33
38
|
`getByRole(…, { exact: true })` where that is provably safe: a locator immune to the *next*
|
|
34
39
|
layout change.
|
|
35
40
|
|
|
36
|
-
▶ **[The full 48-second version](https://www.ia-qa.com/media/heal-demo.mp4)** starts one step
|
|
37
|
-
earlier — from a red build, with `explain` telling you which failures are drift and which one is
|
|
38
|
-
**not** — then covers whether the app you mapped is sound at all, the MCP server answering an
|
|
39
|
-
agent, and the HTML report `--report` writes for a PR.
|
|
40
|
-
|
|
41
41
|
**Prefer clicking to typing?** [`ia-qa-heal ui`](#the-console--ia-qa-heal-ui) opens a local
|
|
42
42
|
console — the rows waiting on you, the verbs as buttons, the history as charts.
|
|
43
43
|
|
|
44
|
-
[](https://www.ia-qa.com/media/heal-ui.mp4)
|
|
45
|
+
|
|
46
|
+
▶ **[Watch the console (32s)](https://www.ia-qa.com/media/heal-ui.mp4)** — buttons pressed,
|
|
47
|
+
results rendered, nothing written.
|
|
45
48
|
|
|
46
49
|
## Install
|
|
47
50
|
|
|
@@ -489,7 +492,10 @@ monorepo. Every field is documented in full in the tutorial
|
|
|
489
492
|
|
|
490
493
|
## The console — `ia-qa-heal ui`
|
|
491
494
|
|
|
492
|
-
|
|
495
|
+
[](https://www.ia-qa.com/media/heal-ui.mp4)
|
|
496
|
+
|
|
497
|
+
▶ **[Watch the console (32s)](https://www.ia-qa.com/media/heal-ui.mp4)** — buttons pressed,
|
|
498
|
+
results rendered, nothing written.
|
|
493
499
|
|
|
494
500
|
A local web console for the rows where the tool gave up: highlighted crops of each candidate,
|
|
495
501
|
the `file:line` of every test that breaks, the verbs as plain-language buttons, and the history
|
|
@@ -542,6 +548,34 @@ untrusted before feeding it to an LLM: the tool does not detect or strip instruc
|
|
|
542
548
|
|
|
543
549
|
**`.ia-qa/session.json` is a secret** — live cookies. Gitignored on creation.
|
|
544
550
|
|
|
551
|
+
## Don't have tests yet? — `@ia-qa/qa-discovery`
|
|
552
|
+
|
|
553
|
+
Everything here assumes a suite already exists: `map` records what your tests locate, `diff`
|
|
554
|
+
tells you when it moved. If you have been handed an app and no tests at all, that loop has
|
|
555
|
+
nothing to hold on to yet.
|
|
556
|
+
|
|
557
|
+
[`@ia-qa/qa-discovery`](https://www.npmjs.com/package/@ia-qa/qa-discovery) is the step before:
|
|
558
|
+
it crawls an app you can reach and writes down what is in it — every page, the headings that
|
|
559
|
+
say what each is for, every input it takes, every API call the browser really made. No verdict,
|
|
560
|
+
no LLM, same local-first promise as this package.
|
|
561
|
+
|
|
562
|
+
```bash
|
|
563
|
+
npx @ia-qa/qa-discovery scan https://your-app.example.com --save --report
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
⚠️ **`scan` and `map` are not the same operation.** `map` writes a page *contract* — every
|
|
567
|
+
interactive element by role and accessible name, for repairing broken locators. `scan` writes a
|
|
568
|
+
*surface* — pages, headings, inputs, API calls, for deciding what to test in the first place.
|
|
569
|
+
Neither produces the other.
|
|
570
|
+
|
|
571
|
+
They are built to hand off, though. `config.pages` has the same `{ name, url }` shape in both,
|
|
572
|
+
and both resolve page names through the *same* function, so a page called `checkout` in one is
|
|
573
|
+
`checkout` in the other — the artifacts line up 1:1. Sessions are interchangeable too, since
|
|
574
|
+
both consume a Playwright `storageState`: `ia-qa-heal map --session .ia-qa-discovery/session.json`.
|
|
575
|
+
|
|
576
|
+
And in the other direction: this package knows what your suite **covers**, discovery knows what
|
|
577
|
+
**exists**. The gap between the two is your real coverage, which neither can tell you alone.
|
|
578
|
+
|
|
545
579
|
## Going deeper
|
|
546
580
|
|
|
547
581
|
- **The tutorial** — the whole thing, step by step, no jargon:
|
package/dist/cli/ingest.js
CHANGED
|
@@ -135,9 +135,27 @@ async function runIngest(args) {
|
|
|
135
135
|
}
|
|
136
136
|
console.log(` A data-testid on those elements retires the risk.`);
|
|
137
137
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
138
|
+
// An empty inventory has TWO causes and they need opposite answers, which the
|
|
139
|
+
// single message here used to collapse: a suite whose locators are built at
|
|
140
|
+
// runtime is invisible to a static scan, and that is a limitation to work
|
|
141
|
+
// around; *no suite at all* is not a limitation, it is this whole package's
|
|
142
|
+
// premise being false. `scanned` separates them — it counts files found, not
|
|
143
|
+
// files that matched.
|
|
144
|
+
if (usage.scanned === 0) {
|
|
145
|
+
console.log(`\n No test files were found at all under ${paths.map((p) => `"${p}"`).join(', ')}.`);
|
|
146
|
+
console.log(` Nothing here is broken: this package repairs the locators of an existing suite, and`);
|
|
147
|
+
console.log(` there is no suite for it to hold on to yet.`);
|
|
148
|
+
// Named only in this branch. Everywhere else it would be advertising —
|
|
149
|
+
// here it is the answer to the situation the user is actually in.
|
|
150
|
+
console.log(`\n If you have been handed an app and no tests, \`@ia-qa/qa-discovery\` is the step before:`);
|
|
151
|
+
console.log(` it crawls the app and writes down what is in it — pages, inputs, API calls — so you know`);
|
|
152
|
+
console.log(` what there is to test. Then come back here to keep those tests alive.`);
|
|
153
|
+
console.log(` npx @ia-qa/qa-discovery scan <url> --save --report`);
|
|
154
|
+
}
|
|
155
|
+
else if (selectors.length === 0 && names.length === 0) {
|
|
156
|
+
console.log(`\n ${usage.scanned} file${usage.scanned === 1 ? '' : 's'} scanned, no locator literals found. ` +
|
|
157
|
+
`Selectors and names built dynamically\n (variables, concatenation, \${…}) are invisible to a ` +
|
|
158
|
+
`static scan — and to \`fix\`.`);
|
|
141
159
|
}
|
|
142
160
|
console.log('');
|
|
143
161
|
const positionalCount = positionalAll.length;
|
package/dist/cli/ingest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../src/cli/ingest.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,
|
|
1
|
+
{"version":3,"file":"ingest.js","sourceRoot":"","sources":["../../src/cli/ingest.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ia-qa/self-healing",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.25",
|
|
4
4
|
"description": "Your Playwright, Cypress or Selenium tests break when a selector moves — this finds the element again and rewrites the test. Deterministic: no LLM decides whether your build passes. Runs entirely on your machine, with a local MCP server for agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"self-healing",
|