@ia-qa/qa-discovery 0.5.2 → 0.6.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/dist/coverage.d.ts +10 -0
- package/dist/coverage.js +4 -1
- package/dist/coverage.js.map +1 -1
- package/dist/healingLink.js +55 -4
- package/dist/healingLink.js.map +1 -1
- package/package.json +2 -2
package/dist/coverage.d.ts
CHANGED
|
@@ -74,6 +74,16 @@ export interface CoverageMap {
|
|
|
74
74
|
uncovered: UncoveredPage[];
|
|
75
75
|
/** Pages the human declared out of scope — counted and named, never silently dropped. */
|
|
76
76
|
outOfScope: string[];
|
|
77
|
+
/**
|
|
78
|
+
* Pages the run MAY have visited, where the capture could not tell which.
|
|
79
|
+
*
|
|
80
|
+
* The third answer this map owed and did not give. Several views can share one URL
|
|
81
|
+
* (`config.pages[].steps`), the capture hooks refuse to guess between them, and until that
|
|
82
|
+
* refusal was recorded it read as an absence — so a project whose suite visits every one of
|
|
83
|
+
* those pages was told it visits none of them. They are held out of `uncovered` and named
|
|
84
|
+
* here: not tested is a claim, and this is not one.
|
|
85
|
+
*/
|
|
86
|
+
cannotTell: string[];
|
|
77
87
|
/**
|
|
78
88
|
* Pages a contract is held for that this scan never reached. A limit of the scan (`--max`,
|
|
79
89
|
* crawl reach, session), never evidence a page is gone.
|
package/dist/coverage.js
CHANGED
|
@@ -145,6 +145,8 @@ function matchesScope(page, scope) {
|
|
|
145
145
|
}
|
|
146
146
|
function buildCoverageMap(input) {
|
|
147
147
|
const visited = new Set(input.exercised.visited);
|
|
148
|
+
// Neither visited nor uncovered — see `cannotTell`.
|
|
149
|
+
const unsure = new Set(input.exercised.unattributed ?? []);
|
|
148
150
|
const scanned = new Map(input.pages.map((p) => [p.page, p]));
|
|
149
151
|
// A short history is not a wrong one, it is one that cannot rank yet — so the factor is
|
|
150
152
|
// simply absent rather than computed on two runs and presented as a signal.
|
|
@@ -157,7 +159,7 @@ function buildCoverageMap(input) {
|
|
|
157
159
|
const outOfScope = [];
|
|
158
160
|
const uncovered = [];
|
|
159
161
|
for (const page of input.pages) {
|
|
160
|
-
if (visited.has(page.page))
|
|
162
|
+
if (visited.has(page.page) || unsure.has(page.page))
|
|
161
163
|
continue;
|
|
162
164
|
if (matchesScope(page.page, input.scope)) {
|
|
163
165
|
outOfScope.push(page.page);
|
|
@@ -196,6 +198,7 @@ function buildCoverageMap(input) {
|
|
|
196
198
|
computedAt: new Date().toISOString(),
|
|
197
199
|
baseUrl: input.baseUrl,
|
|
198
200
|
visited: [...visited].sort(),
|
|
201
|
+
cannotTell: [...unsure].sort(),
|
|
199
202
|
uncovered,
|
|
200
203
|
outOfScope: outOfScope.sort(),
|
|
201
204
|
contractedNotFound: [...visited, ...input.exercised.notVisited].filter((p) => !scanned.has(p)).sort(),
|
package/dist/coverage.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"coverage.js","sourceRoot":"","sources":["../src/coverage.ts"],"names":[],"mappings":"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"}
|
package/dist/healingLink.js
CHANGED
|
@@ -79,15 +79,66 @@ function healingOverlap(pages, cwd = (0, config_1.baseDir)()) {
|
|
|
79
79
|
if (mapped.length === 0)
|
|
80
80
|
return null;
|
|
81
81
|
const scanned = pages.map((p) => p.page).sort();
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
// A contract is identified by the path its config declares, falling back to its filename
|
|
83
|
+
// when nothing declares it. A scanned page answers to **both** its path and its own name.
|
|
84
|
+
// Matching on either is what makes this work with a config and without one — keying only
|
|
85
|
+
// on paths broke every project that has no heal config at all.
|
|
86
|
+
const contractUrl = declaredUrls(cwd);
|
|
87
|
+
const contractKey = (name) => contractUrl.get(name) ?? `name:${name}`;
|
|
88
|
+
const pageKeys = (p) => [normalizePath(p.url), `name:${p.page}`];
|
|
89
|
+
const mappedKeys = new Set(mapped.map(contractKey));
|
|
90
|
+
const scannedKeys = new Set(pages.flatMap(pageKeys));
|
|
84
91
|
return {
|
|
85
92
|
mapped,
|
|
86
93
|
scanned,
|
|
87
|
-
uncovered:
|
|
88
|
-
unscanned: mapped.filter((
|
|
94
|
+
uncovered: pages.filter((p) => !pageKeys(p).some((k) => mappedKeys.has(k))).map((p) => p.page).sort(),
|
|
95
|
+
unscanned: mapped.filter((m) => !scannedKeys.has(contractKey(m))).sort(),
|
|
89
96
|
};
|
|
90
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Contract name → the path `config.pages` declares for it.
|
|
100
|
+
*
|
|
101
|
+
* **The bug this closes, and it is not an edge case.** `healingOverlap` compared contract
|
|
102
|
+
* *filenames* against scan page *names*. Healing writes `login.json` because somebody wrote
|
|
103
|
+
* `{ name: 'login', url: '/' }` into their config; discovery crawls `/` and calls it `home`,
|
|
104
|
+
* because `pageNameFromUrl` is all it has. One page, two names, counted on both sides — so
|
|
105
|
+
* the project's most-tested page came back as "exists, not tested", and a second page came
|
|
106
|
+
* back as "contracted, not reached".
|
|
107
|
+
*
|
|
108
|
+
* The module's own doc claimed the two were comparable *"because both resolve names through
|
|
109
|
+
* the same `pageNameFromUrl`"*. That is true only while nobody names a page — and naming
|
|
110
|
+
* pages is the ordinary case, not the exotic one.
|
|
111
|
+
*
|
|
112
|
+
* Reading heal's config here is not a new dependency: this function already reads heal's
|
|
113
|
+
* `mapping/` directory three lines above. A contract with no declared URL keeps the old
|
|
114
|
+
* name-based comparison rather than disappearing from the count.
|
|
115
|
+
*/
|
|
116
|
+
function declaredUrls(cwd) {
|
|
117
|
+
const out = new Map();
|
|
118
|
+
try {
|
|
119
|
+
const raw = fs.readFileSync(path.join(cwd, '.ia-qa', 'config.json'), 'utf8');
|
|
120
|
+
const config = JSON.parse(raw.replace(/^/, ''));
|
|
121
|
+
for (const p of config?.pages ?? []) {
|
|
122
|
+
if (typeof p?.name === 'string' && typeof p?.url === 'string')
|
|
123
|
+
out.set(p.name, normalizePath(p.url));
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
// No config, or one this tool cannot read — heal's own verbs will say so. Falling back
|
|
128
|
+
// to names keeps the previous behaviour instead of reporting an empty overlap.
|
|
129
|
+
}
|
|
130
|
+
return out;
|
|
131
|
+
}
|
|
132
|
+
/** The path, without host, trailing slash or query — the one shape both sides can produce. */
|
|
133
|
+
function normalizePath(url) {
|
|
134
|
+
try {
|
|
135
|
+
const u = new URL(url, 'http://overlap.invalid');
|
|
136
|
+
return u.pathname.replace(/\/+$/, '') || '/';
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
return url;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
91
142
|
/**
|
|
92
143
|
* The lines the CLI prints. Empty when there is nothing true to say.
|
|
93
144
|
*
|
package/dist/healingLink.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"healingLink.js","sourceRoot":"","sources":["../src/healingLink.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqDA,
|
|
1
|
+
{"version":3,"file":"healingLink.js","sourceRoot":"","sources":["../src/healingLink.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ia-qa/qa-discovery",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Deterministic surface reconnaissance for an unknown web app — crawl, capture, diff. No LLM, no hosting: runs entirely on your machine, with a local MCP server for agents.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"qa",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"node": ">=18.0.0"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@ia-qa/self-healing": "^1.
|
|
53
|
+
"@ia-qa/self-healing": "^1.24.0"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
56
|
"playwright": ">=1.40.0"
|