@ia-qa/self-healing 1.7.10 → 1.7.13

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.
Files changed (58) hide show
  1. package/README.md +38 -2
  2. package/dist/aom.d.ts +36 -0
  3. package/dist/aom.js.map +1 -1
  4. package/dist/browser/match.d.ts +10 -0
  5. package/dist/browser/match.js +16 -6
  6. package/dist/browser/match.js.map +1 -1
  7. package/dist/browser/openables.d.ts +45 -0
  8. package/dist/browser/openables.js +128 -0
  9. package/dist/browser/openables.js.map +1 -0
  10. package/dist/captureState.d.ts +66 -0
  11. package/dist/captureState.js +149 -0
  12. package/dist/captureState.js.map +1 -0
  13. package/dist/cli/args.js +5 -4
  14. package/dist/cli/args.js.map +1 -1
  15. package/dist/cli/baseline.js +22 -0
  16. package/dist/cli/baseline.js.map +1 -1
  17. package/dist/cli/diff.d.ts +50 -0
  18. package/dist/cli/diff.js +114 -11
  19. package/dist/cli/diff.js.map +1 -1
  20. package/dist/cli/emit.d.ts +17 -0
  21. package/dist/cli/emit.js +25 -0
  22. package/dist/cli/emit.js.map +1 -1
  23. package/dist/cli/exitCodes.d.ts +29 -0
  24. package/dist/cli/exitCodes.js +41 -0
  25. package/dist/cli/exitCodes.js.map +1 -0
  26. package/dist/cli/explain.js +11 -2
  27. package/dist/cli/explain.js.map +1 -1
  28. package/dist/cli/fix.d.ts +16 -0
  29. package/dist/cli/fix.js +85 -11
  30. package/dist/cli/fix.js.map +1 -1
  31. package/dist/cli/index.js +56 -3
  32. package/dist/cli/index.js.map +1 -1
  33. package/dist/cli/init.d.ts +39 -1
  34. package/dist/cli/init.js +216 -12
  35. package/dist/cli/init.js.map +1 -1
  36. package/dist/cli/map.d.ts +2 -0
  37. package/dist/cli/map.js +126 -4
  38. package/dist/cli/map.js.map +1 -1
  39. package/dist/cli/run.js +8 -26
  40. package/dist/cli/run.js.map +1 -1
  41. package/dist/config.d.ts +45 -0
  42. package/dist/config.js.map +1 -1
  43. package/dist/explain.d.ts +27 -0
  44. package/dist/explain.js +88 -7
  45. package/dist/explain.js.map +1 -1
  46. package/dist/explore.d.ts +138 -0
  47. package/dist/explore.js +224 -0
  48. package/dist/explore.js.map +1 -0
  49. package/dist/nextStep.d.ts +79 -0
  50. package/dist/nextStep.js +107 -0
  51. package/dist/nextStep.js.map +1 -0
  52. package/dist/systemicDelta.d.ts +129 -0
  53. package/dist/systemicDelta.js +164 -0
  54. package/dist/systemicDelta.js.map +1 -0
  55. package/dist/ui/server.js +5 -1
  56. package/dist/ui/server.js.map +1 -1
  57. package/package.json +1 -1
  58. package/skills/ia-qa-heal/SKILL.md +56 -2
package/dist/cli/init.js CHANGED
@@ -3,10 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseInitFlags = parseInitFlags;
6
7
  exports.runInit = runInit;
8
+ exports.assertUsablePages = assertUsablePages;
7
9
  const prompts_1 = __importDefault(require("prompts"));
8
10
  const config_1 = require("../config");
9
11
  const ui_1 = require("./ui");
12
+ const map_1 = require("./map");
13
+ const baseline_1 = require("./baseline");
14
+ const ingest_1 = require("./ingest");
15
+ const sitemap_1 = require("../discovery/sitemap");
10
16
  /**
11
17
  * `ia-qa-heal init` — interactive wizard.
12
18
  *
@@ -26,12 +32,37 @@ function assertInteractive() {
26
32
  if (process.stdin.isTTY)
27
33
  return;
28
34
  throw new Error(`\`ia-qa-heal init\` is an interactive wizard and stdin is not a terminal, so it would ` +
29
- `hang here rather than ask you anything.\n` +
30
- `Write ${config_1.CONFIG_DIR}/config.json directly instead it needs "baseUrl" and "pages" ` +
35
+ `hang here rather than ask you anything.\n\n` +
36
+ `Non-interactive setupno questions, nothing to hang on:\n` +
37
+ ` ia-qa-heal init --yes --base-url https://app.example --discover\n` +
38
+ ` ia-qa-heal init --yes --base-url https://app.example --pages "home=/,cart=/cart"\n\n` +
39
+ ` --discover reads the sitemap (plain fetch, no browser) and fills "pages" from it.\n` +
40
+ ` --tests <paths> feeds \`ingest\`; --bootstrap also runs ingest → map → baseline.\n\n` +
41
+ `Or write ${config_1.CONFIG_DIR}/config.json directly — it needs "baseUrl" and "pages" ` +
31
42
  `([{ name, url }]), plus optional "auth" + "secrets" for a login.\n` +
32
43
  `\`ia-qa-heal map\` prints a filled-in "auth" block if it hits a login wall.`);
33
44
  }
34
- async function runInit() {
45
+ function parseInitFlags(args) {
46
+ const value = (name) => {
47
+ const i = args.indexOf(name);
48
+ return i >= 0 ? args[i + 1] : undefined;
49
+ };
50
+ return {
51
+ yes: args.includes('--yes'),
52
+ baseUrl: value('--base-url'),
53
+ pagesRaw: value('--pages'),
54
+ discover: args.includes('--discover'),
55
+ testsRaw: value('--tests'),
56
+ testCommand: value('--test-command'),
57
+ bootstrap: args.includes('--bootstrap'),
58
+ };
59
+ }
60
+ async function runInit(args = []) {
61
+ const flags = parseInitFlags(args);
62
+ if (flags.yes) {
63
+ await runInitNonInteractive(flags);
64
+ return;
65
+ }
35
66
  assertInteractive();
36
67
  console.log('\n🔧 ia-qa self-healing — project setup\n');
37
68
  const onCancel = () => {
@@ -160,14 +191,46 @@ async function runInit() {
160
191
  ...(form.successSelector ? { successSelector: form.successSelector } : {}),
161
192
  };
162
193
  }
163
- const pagesAnswer = await (0, prompts_1.default)({
164
- type: 'text',
165
- name: 'pagesRaw',
166
- message: 'Pages to map — comma-separated "name=path" pairs',
167
- initial: 'home=/',
168
- validate: (v) => parsePages(v).length > 0 || 'Expected format: home=/,dashboard=/dashboard',
194
+ const how = await (0, prompts_1.default)({
195
+ type: 'select',
196
+ name: 'source',
197
+ message: 'Pages to map',
198
+ choices: [
199
+ { title: 'Find them for me (reads the sitemap no browser, no login)', value: 'discover' },
200
+ { title: 'I will type them', value: 'manual' },
201
+ ],
202
+ initial: 0,
169
203
  }, { onCancel });
170
- const pages = parsePages(pagesAnswer.pagesRaw);
204
+ let pages = [];
205
+ if (how.source === 'discover') {
206
+ const found = await discoverPages(base.baseUrl);
207
+ if (found.length > 0) {
208
+ const preview = found.slice(0, 8).map((p) => `${p.name}=${p.url}`).join(', ');
209
+ console.log(` ${preview}${found.length > 8 ? `, +${found.length - 8} more` : ''}`);
210
+ const ok = await (0, prompts_1.default)({
211
+ type: 'confirm',
212
+ name: 'yes',
213
+ message: `Use these ${found.length} page${found.length === 1 ? '' : 's'}?`,
214
+ initial: true,
215
+ }, { onCancel });
216
+ if (ok.yes)
217
+ pages = found;
218
+ }
219
+ if (pages.length === 0) {
220
+ console.log(' Falling back to typing them — `ia-qa-heal discover` can add more later.\n');
221
+ }
222
+ }
223
+ if (pages.length === 0) {
224
+ const pagesAnswer = await (0, prompts_1.default)({
225
+ type: 'text',
226
+ name: 'pagesRaw',
227
+ message: 'Pages to map — comma-separated "name=path" pairs',
228
+ initial: 'home=/',
229
+ validate: (v) => parsePages(v).length > 0 || 'Expected format: home=/,dashboard=/dashboard',
230
+ }, { onCancel });
231
+ pages = parsePages(pagesAnswer.pagesRaw);
232
+ }
233
+ assertUsablePages(pages);
171
234
  const suite = await (0, prompts_1.default)([
172
235
  {
173
236
  type: 'text',
@@ -200,9 +263,16 @@ async function runInit() {
200
263
  const usesEnvSecrets = Object.values(secrets).some((s) => s.source === 'env');
201
264
  console.log(`\n✅ Wrote ${file}`);
202
265
  console.log(` Secrets are stored as references only — values stay in ${auth ? describeStore(secrets) : 'your environment'}.`);
266
+ // The two steps that produce a working gate, in the order that produces it. The old
267
+ // second step pointed at `aiClick` — the optional AI runtime — and never mentioned
268
+ // `baseline`, so following the wizard literally ended with mapped pages, nothing to
269
+ // compare them against, and an import from the one layer that is explicitly not the
270
+ // gate. `map` alone is half a contract; the reference is what makes drift a question.
203
271
  console.log('\nNext steps:');
204
- console.log(' 1. ia-qa-heal map # map every configured page');
205
- console.log(' 2. import { aiClick } from "@ia-qa/self-healing" in your Playwright tests');
272
+ console.log(` 1. ia-qa-heal ingest # inventory the locators your tests write${testPaths.length > 0 ? '' : ' (needs "testPaths")'}`);
273
+ console.log(' 2. ia-qa-heal map # capture every configured page');
274
+ console.log(' 3. ia-qa-heal baseline # promote that capture to the reference');
275
+ console.log(' …then change the app, `map` again, and `diff --dir` has two moments.');
206
276
  // Wiring is where projects actually go wrong, and the mistake is silent: scripts get
207
277
  // written uniformly, which works from a shell that happens to carry the variables and
208
278
  // breaks from a clean one. Printed, never written — this wizard does not edit a file it
@@ -224,6 +294,17 @@ async function runInit() {
224
294
  }
225
295
  console.log('\nPages with live content (feeds, article lists)? Keep it out of the contracts so it');
226
296
  console.log('never gates as drift: "volatile": ["href:*source=rss*"] in config.json (see README).\n');
297
+ // Offered, not done: it opens a browser and walks every configured page, which is
298
+ // minutes and real traffic against someone's app. `--yes --bootstrap` is the same
299
+ // consent for anyone who wants it in one line.
300
+ const go = await (0, prompts_1.default)({
301
+ type: 'confirm',
302
+ name: 'yes',
303
+ message: `Run those now? (${testPaths.length > 0 ? 'ingest → ' : ''}map → baseline — opens a browser, visits ${pages.length} page${pages.length === 1 ? '' : 's'})`,
304
+ initial: true,
305
+ }, { onCancel: () => ({ yes: false }) });
306
+ if (go.yes)
307
+ await bootstrap(testPaths.length > 0);
227
308
  await offerShortcut();
228
309
  }
229
310
  /**
@@ -256,6 +337,129 @@ async function offerShortcut() {
256
337
  }
257
338
  await (0, ui_1.runUi)(['--shortcut']);
258
339
  }
340
+ /**
341
+ * Ask the app which pages it has, instead of asking the person.
342
+ *
343
+ * `init` used to prompt for `name=path` pairs with `home=/` as the default. On any real
344
+ * application that is the wall: a newcomer either types a handful of pages and gets a
345
+ * contract that covers almost nothing, or gives up. `discover` has been able to answer
346
+ * this from the sitemap since 1.5 — a plain fetch, no browser, no login — and `init`
347
+ * never called it.
348
+ *
349
+ * It only ever *proposes*: the caller confirms (or passes `--yes`, which is the same
350
+ * consent given once, up front). That is the same restraint `discover --apply` observes,
351
+ * and it is why this reads a sitemap rather than crawling — a crawl behind a login is a
352
+ * bigger promise than a setup wizard should make on its own.
353
+ */
354
+ async function discoverPages(baseUrl) {
355
+ console.log(`\n🔍 Reading ${baseUrl} for a sitemap — plain fetch, no browser, no login…`);
356
+ try {
357
+ const { candidates, stats } = await (0, sitemap_1.discoverFromSitemap)(baseUrl, {});
358
+ if (candidates.length === 0) {
359
+ // Absence is reported as absence, with the reason the discovery layer already
360
+ // computed — never as "your app has no pages".
361
+ for (const line of (0, sitemap_1.emptySitemapReason)(stats))
362
+ console.log(` ${line}`);
363
+ return [];
364
+ }
365
+ console.log(` Found ${candidates.length} page${candidates.length === 1 ? '' : 's'}.`);
366
+ return candidates.map((c) => ({ name: c.name, url: c.url }));
367
+ }
368
+ catch (err) {
369
+ console.log(` Could not read a sitemap: ${err instanceof Error ? err.message : String(err)}`);
370
+ return [];
371
+ }
372
+ }
373
+ /**
374
+ * From a written config to a gate that works, in one confirmation.
375
+ *
376
+ * The wizard used to end on "Next steps: 1. map, 2. import aiClick" — two lines that
377
+ * leave a newcomer with mapped pages, no baseline, and a pointer at the optional AI
378
+ * runtime rather than at the deterministic loop. `diff` recovers well from the gap (it
379
+ * names `baseline` and the whole sequence), but only after the person has already been
380
+ * sent the wrong way.
381
+ *
382
+ * `ingest` first, and that order is load-bearing: `map` binds the suite's own selector
383
+ * strings to real elements while the browser is open, and with no inventory there is
384
+ * nothing to bind — running it second costs a second full `map`.
385
+ */
386
+ async function bootstrap(hasTests) {
387
+ console.log('\n🚀 Setting up the gate — this opens a browser and visits every configured page.\n');
388
+ if (hasTests) {
389
+ console.log('── ia-qa-heal ingest ───────────────────────────────────');
390
+ await (0, ingest_1.runIngest)([]);
391
+ }
392
+ console.log('\n── ia-qa-heal map ─────────────────────────────────────');
393
+ await (0, map_1.runMap)();
394
+ console.log('\n── ia-qa-heal baseline ────────────────────────────────');
395
+ await (0, baseline_1.runBaseline)([]);
396
+ console.log(`\n✅ The gate is live. From here:\n` +
397
+ ` change the app, then ia-qa-heal map && ia-qa-heal diff --dir\n` +
398
+ ` red build? ia-qa-heal explain --junit <report.xml>\n` +
399
+ ` repairs offered? ia-qa-heal fix --dir --dry-run then drop --dry-run\n`);
400
+ }
401
+ async function runInitNonInteractive(flags) {
402
+ if (!flags.baseUrl) {
403
+ throw new Error(`--yes needs --base-url <url>: where the app lives has no safe default.\n` +
404
+ ` ia-qa-heal init --yes --base-url https://app.example --discover`);
405
+ }
406
+ let pages = flags.pagesRaw ? parsePages(flags.pagesRaw) : [];
407
+ if (pages.length === 0 && flags.discover)
408
+ pages = await discoverPages(flags.baseUrl);
409
+ if (pages.length === 0) {
410
+ throw new Error(`No pages to map. Pass --pages "home=/,cart=/cart", or --discover to read them from ` +
411
+ `the sitemap.\nA config with no pages would let \`map\` exit 0 having captured nothing, ` +
412
+ `which reads as success.`);
413
+ }
414
+ assertUsablePages(pages);
415
+ const testPaths = splitList(flags.testsRaw);
416
+ const config = {
417
+ framework: 'playwright',
418
+ baseUrl: flags.baseUrl,
419
+ secrets: {},
420
+ pages,
421
+ ...(testPaths.length > 0 ? { testPaths } : {}),
422
+ ...(flags.testCommand ? { testCommand: flags.testCommand } : {}),
423
+ };
424
+ const file = (0, config_1.saveConfig)(config);
425
+ console.log(`\n✅ Wrote ${file} — ${pages.length} page${pages.length === 1 ? '' : 's'}.`);
426
+ if (flags.bootstrap)
427
+ await bootstrap(testPaths.length > 0);
428
+ else {
429
+ console.log('\nNext: ia-qa-heal ingest → ia-qa-heal map → ia-qa-heal baseline');
430
+ console.log(' (or re-run with --bootstrap to chain them now)');
431
+ }
432
+ }
433
+ /**
434
+ * Catch the shell before it reaches `map`.
435
+ *
436
+ * Git Bash on Windows rewrites an argument that looks like a POSIX path, so
437
+ * `--pages "home=/,cart=/cart"` arrives as `home=C:/Program Files/Git/` — silently, with
438
+ * a zero exit. Written to config it is not a page but a local directory, and the failure
439
+ * surfaces two verbs later as a browser navigating somewhere absurd, which is a long way
440
+ * from the cause.
441
+ *
442
+ * A drive letter is never a page path, so it can be named for what it is. The remedy is
443
+ * the environment variable rather than "quote it differently", because quoting does not
444
+ * help — MSYS converts inside quotes too.
445
+ */
446
+ function assertUsablePages(pages) {
447
+ const mangled = pages.filter((p) => /^[A-Za-z]:[\\/]/.test(p.url));
448
+ if (mangled.length === 0)
449
+ return;
450
+ throw new Error(`"${mangled[0].name}" has a local path as its URL (${mangled[0].url}), not a page.\n` +
451
+ `That is Git Bash rewriting a leading "/" into a Windows path before this CLI saw it — ` +
452
+ `it happens inside quotes too, so quoting differently will not help.\n\n` +
453
+ ` MSYS2_ARG_CONV_EXCL="*" ia-qa-heal init --yes --base-url … --pages "home=/,cart=/cart"\n` +
454
+ ` …or use PowerShell / cmd, where the conversion does not happen.\n` +
455
+ ` …or drop --pages and use --discover, which reads the paths from your sitemap.`);
456
+ }
457
+ function splitList(raw) {
458
+ return String(raw || '')
459
+ .split(',')
460
+ .map((p) => p.trim())
461
+ .filter(Boolean);
462
+ }
259
463
  function parsePages(raw) {
260
464
  return raw
261
465
  .split(',')
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
package/dist/cli/map.d.ts CHANGED
@@ -27,6 +27,8 @@ export interface MapResult {
27
27
  export declare function runMap(pageNameArg?: string, opts?: {
28
28
  screenshots?: boolean;
29
29
  session?: string;
30
+ deep?: number;
31
+ deepBudget?: number;
30
32
  }): Promise<MapResult>;
31
33
  /**
32
34
  * Walk a target's `steps` to reach a view the URL cannot name.
package/dist/cli/map.js CHANGED
@@ -57,6 +57,8 @@ const fixEngine_1 = require("../fixEngine");
57
57
  const config_2 = require("../config");
58
58
  const resolution_1 = require("../resolution");
59
59
  const config_3 = require("../config");
60
+ const captureState_1 = require("../captureState");
61
+ const explore_1 = require("../explore");
60
62
  /**
61
63
  * `ia-qa-heal map [pageName]` — scraping & DOM compression engine.
62
64
  *
@@ -68,6 +70,50 @@ const config_3 = require("../config");
68
70
  * After all pages are mapped, if `config.layouts` is defined, extracts shared
69
71
  * elements into `_layouts/<name>.json` and strips them from per-page mappings.
70
72
  */
73
+ /**
74
+ * Seed the declared browser state, once per context, before any page loads.
75
+ *
76
+ * `addInitScript` rather than a `page.evaluate` after `goto`, and that is the whole
77
+ * correctness of it: the banner logic this exists to silence runs on page load, so state
78
+ * written afterwards arrives too late and the banner is in the contract anyway. An init
79
+ * script runs before the page's own scripts, on every navigation, for free.
80
+ *
81
+ * A failure to seed is loud but not fatal — the capture that follows is then taken in a
82
+ * state nobody declared, which the fingerprint records faithfully, so the worst case is a
83
+ * `diff` that reports a divergence rather than one that hides it.
84
+ */
85
+ async function applyPrepare(context, config) {
86
+ const prep = config.prepare;
87
+ if (!prep)
88
+ return;
89
+ const entries = Object.entries(prep.localStorage ?? {});
90
+ const cookies = prep.cookies ?? [];
91
+ if (entries.length === 0 && cookies.length === 0)
92
+ return;
93
+ try {
94
+ if (entries.length > 0) {
95
+ await context.addInitScript((pairs) => {
96
+ try {
97
+ for (const [k, v] of pairs)
98
+ localStorage.setItem(k, v);
99
+ }
100
+ catch {
101
+ // A page served from about:blank or with storage blocked — the seeding is
102
+ // best-effort per document, never a reason to abort a 142-page walk.
103
+ }
104
+ }, entries);
105
+ }
106
+ if (cookies.length > 0) {
107
+ const { hostname } = new URL(config.baseUrl);
108
+ await context.addCookies(cookies.map((c) => ({ name: c.name, value: c.value, domain: hostname, path: '/' })));
109
+ }
110
+ console.log(`🧪 prepare — seeded ${entries.length} localStorage key${entries.length === 1 ? '' : 's'}` +
111
+ ` and ${cookies.length} cookie${cookies.length === 1 ? '' : 's'} before capture.`);
112
+ }
113
+ catch (err) {
114
+ console.warn(` ⚠ prepare could not be applied: ${err instanceof Error ? err.message : String(err)}`);
115
+ }
116
+ }
71
117
  /**
72
118
  * One viewport JPEG per page, next to the contract, for the HTML report to show
73
119
  * what the page looked like. JPEG at quality 60 rather than PNG: the report
@@ -237,6 +283,12 @@ async function capturePageRects(page, pageName, selectors) {
237
283
  }
238
284
  /** Elements in the viewport but not on screen, across this run. Reset by `runMap`. */
239
285
  const obscuredThisRun = [];
286
+ /**
287
+ * Pages whose deep walk ran out of budget. Run-scoped like `obscuredThisRun`, and for the
288
+ * same reason: the fact belongs in the final verdict, not only in the line that scrolled past
289
+ * forty pages ago.
290
+ */
291
+ const deepTruncated = [];
240
292
  /**
241
293
  * The half of the hit test that is worth more than the picture it replaced.
242
294
  *
@@ -421,6 +473,7 @@ function reportBindingTotals() {
421
473
  }
422
474
  async function runMap(pageNameArg, opts = {}) {
423
475
  obscuredThisRun.length = 0;
476
+ deepTruncated.length = 0;
424
477
  const config = (0, config_1.loadConfig)();
425
478
  if (config.pages.length === 0 && !pageNameArg) {
426
479
  throw new Error('No pages configured — nothing to map.\n' +
@@ -456,6 +509,7 @@ async function runMap(pageNameArg, opts = {}) {
456
509
  ...(locale ? { locale } : {}),
457
510
  ...(session ? { storageState: session.file } : {}),
458
511
  });
512
+ await applyPrepare(context, config);
459
513
  const page = await context.newPage();
460
514
  if (session) {
461
515
  console.log(sessionLine(session));
@@ -559,13 +613,21 @@ async function runMap(pageNameArg, opts = {}) {
559
613
  reportBindingTotals();
560
614
  if (opts.screenshots)
561
615
  reportObscured();
616
+ if (deepTruncated.length > 0) {
617
+ console.error(`\n⚠ ${deepTruncated.length} ${deepTruncated.length === 1 ? 'page' : 'pages'} only PARTLY explored ` +
618
+ `(deep budget reached): ${deepTruncated.slice(0, 8).join(', ')}` +
619
+ (deepTruncated.length > 8 ? `, +${deepTruncated.length - 8} more` : '') +
620
+ `\n Their contracts describe part of the reachable surface, so drift in the rest is ungated.\n` +
621
+ ` Raise the ceiling with --deep-budget <n>, or narrow the walk with --depth 1.`);
622
+ }
562
623
  console.log('');
563
- (0, summary_1.summaryLine)('map', failed.length > 0 ? 'warn' : 'ok', failed.length > 0
624
+ (0, summary_1.summaryLine)('map', failed.length > 0 || deepTruncated.length > 0 ? 'warn' : 'ok', failed.length > 0
564
625
  ? `${mapped} of ${targets.length} pages mapped`
565
626
  : `${mapped} ${mapped === 1 ? 'page' : 'pages'} mapped`, [
566
627
  `${totalElements} ${totalElements === 1 ? 'selector' : 'selectors'} under contract`,
567
628
  anonymous > 0 ? `${anonymous} without a11y name` : undefined,
568
629
  volatileExcluded > 0 ? `${volatileExcluded} volatile excluded` : undefined,
630
+ deepTruncated.length > 0 ? `${deepTruncated.length} partly explored` : undefined,
569
631
  failed.length > 0 ? `${failed.length} failed` : undefined,
570
632
  ]);
571
633
  return { mapped, attempted: targets.length, failed };
@@ -577,30 +639,90 @@ async function runMap(pageNameArg, opts = {}) {
577
639
  * nothing to the totals rather than half of itself.
578
640
  */
579
641
  async function mapOnePage(page, target, url, config, opts, volatilePatterns, session, tally) {
642
+ const land = async () => {
643
+ await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 });
644
+ await runSteps(page, target);
645
+ };
580
646
  await page.goto(url, { waitUntil: 'networkidle', timeout: 30000 });
581
647
  await assertLanded(page, target, url, config, session);
582
648
  await runSteps(page, target);
583
649
  if (opts.screenshots)
584
650
  await capturePageShot(page, target.name);
585
651
  const extracted = await (0, aom_1.extractInteractiveElements)(page);
586
- const { kept: elements, excluded } = (0, volatile_1.filterVolatile)(extracted, volatilePatterns);
652
+ const { kept: loaded, excluded } = (0, volatile_1.filterVolatile)(extracted, volatilePatterns);
653
+ let elements = loaded;
587
654
  if (opts.screenshots)
588
- await capturePageRects(page, target.name, elements.map((e) => e.selector));
655
+ await capturePageRects(page, target.name, loaded.map((e) => e.selector));
589
656
  // The binding half of the capture: which literal selectors in the suite reach which
590
657
  // contracted elements, on this page, right now. Without an inventory there is nothing
591
658
  // to resolve — and, exactly like `nameDrift`, no inventory means no escalation later.
592
- await resolvePageSelectors(page, target.name, elements.map((e) => e.selector));
659
+ await resolvePageSelectors(page, target.name, loaded.map((e) => e.selector));
660
+ // Exploration goes LAST, and the order is load-bearing. It clicks, so it leaves the page in
661
+ // whatever state the walk ended on; anything above that reads the live DOM — the rect
662
+ // capture, and above all `resolvePageSelectors` — must have already run against the state
663
+ // the page actually loads in. Reversing these two would resolve the suite's selectors
664
+ // against an open modal and call a working binding broken.
665
+ let explored = null;
666
+ let collidedSelectors = 0;
667
+ if (opts.deep) {
668
+ explored = await (0, explore_1.explorePage)(page, {
669
+ depth: opts.deep,
670
+ budget: opts.deepBudget,
671
+ restore: land,
672
+ });
673
+ const { kept: revealed } = (0, volatile_1.filterVolatile)(explored.revealed, volatilePatterns);
674
+ const merged = (0, explore_1.mergeExplored)(loaded, revealed);
675
+ elements = merged.elements;
676
+ collidedSelectors = merged.collided;
677
+ }
593
678
  const mapping = {
594
679
  page: target.name,
595
680
  url: target.url,
596
681
  capturedAt: new Date().toISOString(),
597
682
  elements,
683
+ // Which *kind* of browser state this page was read under — origins, storage keys
684
+ // and cookie names, hashed; never a value. It is the only thing that can later
685
+ // separate "the app removed this control" from "this capture was taken after a
686
+ // banner had been dismissed", two situations whose rows are identical.
687
+ captureState: (0, captureState_1.captureStateFor)(session?.file ?? null, config.prepare),
688
+ ...(opts.deep ? { exploredDepth: opts.deep } : {}),
598
689
  };
599
690
  const file = (0, aom_1.saveMapping)(mapping);
600
691
  const md = (0, markdown_1.saveMarkdown)(mapping);
601
692
  console.log(` ✔ ${elements.length} interactive elements → ` +
602
693
  `${path.relative(process.cwd(), file)} + ${path.relative(process.cwd(), md)}` +
603
694
  (excluded > 0 ? ` · ${excluded} volatile excluded` : ''));
695
+ if (explored) {
696
+ const gained = elements.length - loaded.length;
697
+ console.log(` 🔍 deep: +${gained} behind interaction ` +
698
+ `(${loaded.length} on load) · ${explored.states} state${explored.states === 1 ? '' : 's'} · ` +
699
+ `${explored.clicks} clicks, ${explored.reloads} reload${explored.reloads === 1 ? '' : 's'}`);
700
+ // Reached, and deliberately not contracted: a positional selector captured in one state can
701
+ // address a different element in another, and a contract holding the same selector twice
702
+ // makes `diffMappings` pair rows arbitrarily — which returned BLOCK on an unchanged app.
703
+ // Dropping them is right; hiding the drop would be the coverage lie this package refuses.
704
+ if (collidedSelectors > 0) {
705
+ console.log(` ↩ ${collidedSelectors} revealed element${collidedSelectors === 1 ? '' : 's'} left out — ` +
706
+ `selector already names another element (unusable for healing)`);
707
+ }
708
+ // Never silent. Exploration ran with every non-GET request aborted, so a page that
709
+ // blocked many of them was read while the app was being told "no" — usually analytics,
710
+ // occasionally an error state that belongs in the contract's interpretation, not hidden.
711
+ if (explored.blockedMutations > 0) {
712
+ console.log(` 🛡 ${explored.blockedMutations} non-GET request${explored.blockedMutations === 1 ? '' : 's'} ` +
713
+ `blocked during exploration (nothing mutating left the browser)`);
714
+ }
715
+ // A truncated deep contract is the one failure this feature can produce that *looks* like
716
+ // success: more elements than yesterday, a green diff, and an unexplored remainder nobody
717
+ // can see. It is stated on the page, counted in the summary, and it is a warning rather
718
+ // than a note for the same reason a page left out of `run`'s coverage is `stale` and never
719
+ // a pass — the contract does not describe the surface it claims to.
720
+ if (explored.truncated) {
721
+ deepTruncated.push(target.name);
722
+ console.warn(` ⚠ deep budget of ${opts.deepBudget ?? 150} clicks reached — states left unexplored. ` +
723
+ `This contract covers PART of "${target.name}". Raise it with --deep-budget <n>.`);
724
+ }
725
+ }
604
726
  // A page behind a login that comes back empty is almost never an empty page — it is a
605
727
  // session that never fully established for this domain. assertLanded catches the loud
606
728
  // case (a redirect to a password field); this catches the silent one (a shell that