@ia-qa/qa-discovery 0.1.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.
Files changed (84) hide show
  1. package/README.md +378 -0
  2. package/ROADMAP.md +321 -0
  3. package/dist/ai/classify.d.ts +170 -0
  4. package/dist/ai/classify.js +431 -0
  5. package/dist/ai/classify.js.map +1 -0
  6. package/dist/browser/extractPage.d.ts +41 -0
  7. package/dist/browser/extractPage.js +427 -0
  8. package/dist/browser/extractPage.js.map +1 -0
  9. package/dist/browser/openables.d.ts +19 -0
  10. package/dist/browser/openables.js +127 -0
  11. package/dist/browser/openables.js.map +1 -0
  12. package/dist/capture/page.d.ts +128 -0
  13. package/dist/capture/page.js +78 -0
  14. package/dist/capture/page.js.map +1 -0
  15. package/dist/citations.d.ts +80 -0
  16. package/dist/citations.js +197 -0
  17. package/dist/citations.js.map +1 -0
  18. package/dist/classificationView.d.ts +118 -0
  19. package/dist/classificationView.js +178 -0
  20. package/dist/classificationView.js.map +1 -0
  21. package/dist/cli/args.d.ts +3 -0
  22. package/dist/cli/args.js +38 -0
  23. package/dist/cli/args.js.map +1 -0
  24. package/dist/cli/history.d.ts +1 -0
  25. package/dist/cli/history.js +35 -0
  26. package/dist/cli/history.js.map +1 -0
  27. package/dist/cli/index.d.ts +5 -0
  28. package/dist/cli/index.js +172 -0
  29. package/dist/cli/index.js.map +1 -0
  30. package/dist/cli/login.d.ts +29 -0
  31. package/dist/cli/login.js +179 -0
  32. package/dist/cli/login.js.map +1 -0
  33. package/dist/cli/scan.d.ts +11 -0
  34. package/dist/cli/scan.js +246 -0
  35. package/dist/cli/scan.js.map +1 -0
  36. package/dist/cli-ai/index.d.ts +7 -0
  37. package/dist/cli-ai/index.js +360 -0
  38. package/dist/cli-ai/index.js.map +1 -0
  39. package/dist/config.d.ts +112 -0
  40. package/dist/config.js +178 -0
  41. package/dist/config.js.map +1 -0
  42. package/dist/diff.d.ts +12 -0
  43. package/dist/diff.js +43 -0
  44. package/dist/diff.js.map +1 -0
  45. package/dist/explore.d.ts +59 -0
  46. package/dist/explore.js +119 -0
  47. package/dist/explore.js.map +1 -0
  48. package/dist/healingLink.d.ts +30 -0
  49. package/dist/healingLink.js +127 -0
  50. package/dist/healingLink.js.map +1 -0
  51. package/dist/history.d.ts +38 -0
  52. package/dist/history.js +120 -0
  53. package/dist/history.js.map +1 -0
  54. package/dist/htmlReport.d.ts +2 -0
  55. package/dist/htmlReport.js +371 -0
  56. package/dist/htmlReport.js.map +1 -0
  57. package/dist/index.d.ts +24 -0
  58. package/dist/index.js +65 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/mcp/sandbox.d.ts +9 -0
  61. package/dist/mcp/sandbox.js +82 -0
  62. package/dist/mcp/sandbox.js.map +1 -0
  63. package/dist/mcp/server.d.ts +120 -0
  64. package/dist/mcp/server.js +315 -0
  65. package/dist/mcp/server.js.map +1 -0
  66. package/dist/network.d.ts +60 -0
  67. package/dist/network.js +99 -0
  68. package/dist/network.js.map +1 -0
  69. package/dist/overview.d.ts +40 -0
  70. package/dist/overview.js +370 -0
  71. package/dist/overview.js.map +1 -0
  72. package/dist/overviewFile.d.ts +31 -0
  73. package/dist/overviewFile.js +101 -0
  74. package/dist/overviewFile.js.map +1 -0
  75. package/dist/scan.d.ts +159 -0
  76. package/dist/scan.js +402 -0
  77. package/dist/scan.js.map +1 -0
  78. package/dist/sharedCalls.d.ts +28 -0
  79. package/dist/sharedCalls.js +61 -0
  80. package/dist/sharedCalls.js.map +1 -0
  81. package/dist/taxonomy.d.ts +77 -0
  82. package/dist/taxonomy.js +153 -0
  83. package/dist/taxonomy.js.map +1 -0
  84. package/package.json +61 -0
@@ -0,0 +1,427 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractPageInPage = extractPageInPage;
4
+ /**
5
+ * Page-structure extraction — meta, headings, forms.
6
+ *
7
+ * Self-contained (no imports, no closures over module scope, no TypeScript
8
+ * syntax) because Playwright serializes this via `toString()` and injects it
9
+ * into the page with `page.evaluate()`. Deliberately NOT the same extraction
10
+ * as `@ia-qa/self-healing`'s `browser/extract.js` (interactive elements for
11
+ * selector healing) — this reads what recon needs: what the page is about
12
+ * (title/description/headings) and what it can submit (forms + fields).
13
+ */
14
+ function extractPageInPage() {
15
+ function text(el) {
16
+ return (el && el.textContent ? el.textContent : '').replace(/\s+/g, ' ').trim();
17
+ }
18
+ /** Collapse whitespace in a raw string. `text()` does the same for an element. */
19
+ function clean(s) {
20
+ return (s || '').replace(/\s+/g, ' ').trim();
21
+ }
22
+ function meta() {
23
+ var descEl = document.querySelector('meta[name="description"]');
24
+ return {
25
+ title: text(document.querySelector('title')) || document.title || '',
26
+ description: descEl ? (descEl.getAttribute('content') || '').trim() : '',
27
+ lang: document.documentElement.getAttribute('lang') || '',
28
+ };
29
+ }
30
+ function headings() {
31
+ var out = [];
32
+ var nodes = document.querySelectorAll('h1, h2, h3, h4, h5, h6');
33
+ for (var i = 0; i < nodes.length; i++) {
34
+ var el = nodes[i];
35
+ var rect = el.getBoundingClientRect();
36
+ if (rect.width === 0 && rect.height === 0)
37
+ continue;
38
+ var t = text(el);
39
+ if (!t)
40
+ continue;
41
+ out.push({ level: Number(el.tagName.slice(1)), text: t.slice(0, 200) });
42
+ }
43
+ return out;
44
+ }
45
+ // Mirrors browser/extract.js's stableSelector priority (test-id > id > name),
46
+ // and — like it — never returns a selector that resolves to more than one
47
+ // element. A bare tag name ("input") looks like a locator and is a coin flip:
48
+ // the login form measured on a real app had two inputs, no id, no name, no
49
+ // test-id, and both fields would have carried the same "input".
50
+ //
51
+ // `stable` is the honest half: false means the field has NO durable identity,
52
+ // so the positional fallback works today and breaks the moment a field is
53
+ // inserted above it. A later stage must be able to tell the two apart rather
54
+ // than trusting every selector equally.
55
+ /** Position among same-tag siblings, for one step of a positional path. */
56
+ function nthOfType(el) {
57
+ var siblings = el.parentElement ? el.parentElement.children : [];
58
+ var nth = 0;
59
+ for (var i = 0; i < siblings.length; i++) {
60
+ if (siblings[i].tagName === el.tagName) {
61
+ nth++;
62
+ if (siblings[i] === el)
63
+ return nth;
64
+ }
65
+ }
66
+ return 1;
67
+ }
68
+ /**
69
+ * A full child-combinator path from `root` down to the element.
70
+ *
71
+ * The naive version — `form input:nth-of-type(1)` — is a DESCENDANT
72
+ * combinator, so it matches every input that happens to be first inside its
73
+ * own wrapper. Measured on a real login form (two inputs, each in its own
74
+ * div): both fields got the identical selector. Each step of the path has to
75
+ * be walked, or the position means nothing.
76
+ */
77
+ function pathWithin(el, root, rootSel) {
78
+ var steps = [];
79
+ var node = el;
80
+ while (node && node !== root) {
81
+ steps.unshift(node.tagName.toLowerCase() + ':nth-of-type(' + nthOfType(node) + ')');
82
+ // Stop at the SHORTEST chain that already resolves to this element and
83
+ // nothing else. Walking all the way to the root instead produced a
84
+ // 9-level selector on every field of a React app — the first ancestor
85
+ // carrying an id is `#root`, the mount point, so "anchoring" anchored to
86
+ // the top of the document. Unique but unreadable, and a selector nobody
87
+ // can read is one nobody will check.
88
+ var bare = steps.join(' > ');
89
+ if (resolvesToOne(bare, el))
90
+ return bare;
91
+ node = node.parentElement;
92
+ }
93
+ return rootSel + (steps.length ? ' > ' + steps.join(' > ') : '');
94
+ }
95
+ /**
96
+ * For a field outside any `<form>`, the closest ancestor that carries a
97
+ * durable identity — so a positional path is anchored to something named
98
+ * rather than walked all the way from `body`, which no refactor survives.
99
+ */
100
+ function anchorFor(el) {
101
+ var node = el.parentElement;
102
+ while (node && node !== document.body) {
103
+ var tid = node.getAttribute('data-testid') || node.getAttribute('data-test-id') || node.getAttribute('data-qa');
104
+ if (tid)
105
+ return { root: node, sel: '[data-testid="' + tid + '"]' };
106
+ if (node.id)
107
+ return { root: node, sel: '#' + CSS.escape(node.id) };
108
+ node = node.parentElement;
109
+ }
110
+ return { root: document.body, sel: 'body' };
111
+ }
112
+ /**
113
+ * What container a loose field sits in, for a human reading the capture:
114
+ * the nearest landmark and/or the heading above it. Same idea as the
115
+ * `context` field in self-healing's `browser/extract.js` — without it, 100
116
+ * loose inputs on one page are an undifferentiated blob.
117
+ */
118
+ function fieldContext(el) {
119
+ var parts = [];
120
+ var landmark = el.closest('main, nav, header, footer, aside, section[aria-label], [role="dialog"], [role="region"]');
121
+ if (landmark) {
122
+ var label = landmark.getAttribute('aria-label');
123
+ parts.push(label ? landmark.tagName.toLowerCase() + ': ' + label : landmark.tagName.toLowerCase());
124
+ }
125
+ var node = el;
126
+ while (node && node !== document.body) {
127
+ var prev = node.previousElementSibling;
128
+ while (prev) {
129
+ if (/^H[1-6]$/.test(prev.tagName)) {
130
+ var t = text(prev);
131
+ if (t) {
132
+ parts.push(t.slice(0, 80));
133
+ return parts.join(' › ');
134
+ }
135
+ }
136
+ prev = prev.previousElementSibling;
137
+ }
138
+ node = node.parentElement;
139
+ }
140
+ return parts.join(' › ');
141
+ }
142
+ function fieldSelector(el, root, rootSel) {
143
+ var candidate = null;
144
+ var stable = false;
145
+ var testId = el.getAttribute('data-testid') ||
146
+ el.getAttribute('data-test-id') ||
147
+ el.getAttribute('data-test') ||
148
+ el.getAttribute('data-cy') ||
149
+ el.getAttribute('data-qa');
150
+ var name = el.getAttribute('name');
151
+ if (testId) {
152
+ candidate = '[data-testid="' + testId + '"]';
153
+ stable = true;
154
+ }
155
+ else if (el.id) {
156
+ candidate = '#' + CSS.escape(el.id);
157
+ stable = true;
158
+ }
159
+ else if (name) {
160
+ candidate = el.tagName.toLowerCase() + '[name="' + name + '"]';
161
+ stable = true;
162
+ }
163
+ // Verify rather than assume: an id can be duplicated, a name can repeat
164
+ // across forms. A selector matching 2 elements is a coin flip, and the
165
+ // whole point of emitting one is that a later stage can act on it.
166
+ if (candidate && resolvesToOne(candidate, el))
167
+ return { selector: candidate, stable: stable };
168
+ var positional = pathWithin(el, root, rootSel);
169
+ return { selector: positional, stable: false, unique: resolvesToOne(positional, el) };
170
+ }
171
+ var FIELD_SELECTOR = 'input:not([type="hidden"]):not([type="submit"]):not([type="button"]), select, textarea';
172
+ /**
173
+ * The visible label of a field — what a human reads to know what it is.
174
+ *
175
+ * This was the single biggest gap in the capture, and it was found by running
176
+ * the classification stage against a real model: on a page of twelve fields it
177
+ * returned the same label for all twelve, because the capture gave it a `range`
178
+ * and a `text` with no name and no context. A human on that page reads
179
+ * "Temperature", "Max tokens", "API key". Nothing downstream — a model or a
180
+ * person — can distinguish what the capture never recorded.
181
+ *
182
+ * Priority mirrors the accessible-name order `@ia-qa/self-healing`'s
183
+ * `browser/extract.js` uses, so the two packages describe an element the same
184
+ * way: explicit ARIA first, then the markup's own association, then the weaker
185
+ * hints. `placeholder` is included but last — it is real signal, and often the
186
+ * only one a React app leaves behind.
187
+ */
188
+ function fieldLabel(el) {
189
+ var aria = clean(el.getAttribute('aria-label'));
190
+ if (aria)
191
+ return { text: aria, source: 'aria-label' };
192
+ var labelledBy = el.getAttribute('aria-labelledby');
193
+ if (labelledBy) {
194
+ var parts = [];
195
+ var ids = labelledBy.split(/\s+/);
196
+ for (var i = 0; i < ids.length; i++) {
197
+ var ref = document.getElementById(ids[i]);
198
+ if (ref)
199
+ parts.push(clean(ref.textContent));
200
+ }
201
+ var joined = clean(parts.join(' '));
202
+ if (joined)
203
+ return { text: joined, source: 'aria-labelledby' };
204
+ }
205
+ // <label for="…">, the explicit association.
206
+ if (el.id) {
207
+ try {
208
+ var forLabel = document.querySelector('label[for="' + CSS.escape(el.id) + '"]');
209
+ if (forLabel) {
210
+ var t = labelTextWithout(forLabel, el);
211
+ if (t)
212
+ return { text: t, source: 'label-for' };
213
+ }
214
+ }
215
+ catch (e) {
216
+ /* malformed id — fall through */
217
+ }
218
+ }
219
+ // A wrapping <label>: the field sits inside it, so its own text is the label.
220
+ var wrapping = el.closest('label');
221
+ if (wrapping) {
222
+ var wt = labelTextWithout(wrapping, el);
223
+ if (wt)
224
+ return { text: wt, source: 'label-wrapping' };
225
+ }
226
+ var placeholder = clean(el.getAttribute('placeholder'));
227
+ if (placeholder)
228
+ return { text: placeholder, source: 'placeholder' };
229
+ var title = clean(el.getAttribute('title'));
230
+ if (title)
231
+ return { text: title, source: 'title' };
232
+ // Last resort: the text sitting next to the field inside its own container.
233
+ // Measured on a real page — a `<span>Temperature</span>` in a sibling div,
234
+ // no <label> and no ARIA anywhere. That is the ordinary React shape, and
235
+ // without this the capture sees `range` where a human reads "Temperature".
236
+ //
237
+ // It is a guess from proximity, not a declaration, so it is recorded WITH
238
+ // its source: a later stage can weigh "the app says this is the label"
239
+ // differently from "something near it said this". Bounded to a short string
240
+ // — anything longer is a paragraph the field happens to sit in, not a name.
241
+ var near = nearbyText(el);
242
+ if (near)
243
+ return { text: near, source: 'proximity' };
244
+ return null;
245
+ }
246
+ /** Text inside the field's container, excluding the controls themselves. */
247
+ function nearbyText(el) {
248
+ var node = el.parentElement;
249
+ for (var depth = 0; node && depth < 2 && node !== document.body; depth++) {
250
+ var clone = node.cloneNode(true);
251
+ var controls = clone.querySelectorAll('input, select, textarea, button, svg');
252
+ for (var i = 0; i < controls.length; i++) {
253
+ if (controls[i].parentNode)
254
+ controls[i].parentNode.removeChild(controls[i]);
255
+ }
256
+ // Join text NODE by node rather than reading textContent: adjacent
257
+ // elements carry no whitespace between them, so `<span>Temperature</span>
258
+ // <span>0.7</span>` reads as "Temperature0.7".
259
+ var chunks = [];
260
+ var walker = document.createTreeWalker(clone, NodeFilter.SHOW_TEXT, null);
261
+ var n;
262
+ while ((n = walker.nextNode())) {
263
+ var chunk = clean(n.nodeValue);
264
+ if (chunk)
265
+ chunks.push(chunk);
266
+ }
267
+ var t = clean(chunks.join(' '));
268
+ if (t && t.length <= 60)
269
+ return t;
270
+ node = node.parentElement;
271
+ }
272
+ return '';
273
+ }
274
+ /**
275
+ * A label's text, minus anything the field itself contributes.
276
+ *
277
+ * A wrapping `<label>` contains the control, so `textContent` would fold in a
278
+ * `<select>`'s option list — turning "Model" into "ModelGPT-4oClaudeGemini".
279
+ */
280
+ function labelTextWithout(labelEl, fieldEl) {
281
+ var out = [];
282
+ var walker = labelEl.childNodes;
283
+ for (var i = 0; i < walker.length; i++) {
284
+ var node = walker[i];
285
+ if (node === fieldEl)
286
+ continue;
287
+ if (node.nodeType === 1 && (node === fieldEl || node.contains(fieldEl)))
288
+ continue;
289
+ out.push(node.textContent || '');
290
+ }
291
+ return clean(out.join(' ')).slice(0, 120);
292
+ }
293
+ /** One field object, from an element and the root its positional path hangs off. */
294
+ function describeField(el, root, rootSel) {
295
+ var sel = fieldSelector(el, root, rootSel);
296
+ var field = {
297
+ type: (el.getAttribute('type') || el.tagName.toLowerCase()).toLowerCase(),
298
+ name: el.getAttribute('name') || '',
299
+ selector: sel.selector,
300
+ stableSelector: sel.stable,
301
+ required: el.hasAttribute('required'),
302
+ };
303
+ // What a human reads to know what this field is — see fieldLabel().
304
+ var lbl = fieldLabel(el);
305
+ if (lbl) {
306
+ field.label = lbl.text;
307
+ field.labelSource = lbl.source;
308
+ }
309
+ // Stated only when it is FALSE: the selector could not be made to resolve
310
+ // to exactly one element, so nothing downstream may act on it.
311
+ if (sel.unique === false)
312
+ field.ambiguousSelector = true;
313
+ return field;
314
+ }
315
+ function resolvesToOne(selector, el) {
316
+ try {
317
+ var found = document.querySelectorAll(selector);
318
+ return found.length === 1 && found[0] === el;
319
+ }
320
+ catch (e) {
321
+ return false;
322
+ }
323
+ }
324
+ function formSelector(el) {
325
+ if (el.id)
326
+ return 'form#' + el.id;
327
+ var name = el.getAttribute('name');
328
+ if (name)
329
+ return 'form[name="' + name + '"]';
330
+ var forms = document.querySelectorAll('form');
331
+ for (var i = 0; i < forms.length; i++) {
332
+ if (forms[i] === el)
333
+ return 'form:nth-of-type(' + (i + 1) + ')';
334
+ }
335
+ return 'form';
336
+ }
337
+ // Only what the DOM actually states. A form with no `action` submits to the
338
+ // current URL per the HTML spec, but a React/Vue form usually has no action
339
+ // because submission is handled in JS and never reaches the network at all —
340
+ // reporting the page URL there invents a fact the app never stated, and a
341
+ // later stage would read it as a real POST target. Absent stays absent.
342
+ function resolveAction(el) {
343
+ var raw = el.getAttribute('action');
344
+ if (raw === null || raw === '')
345
+ return null;
346
+ try {
347
+ return new URL(raw, document.baseURI).toString();
348
+ }
349
+ catch (e) {
350
+ return raw;
351
+ }
352
+ }
353
+ function forms() {
354
+ var out = [];
355
+ var formEls = document.querySelectorAll('form');
356
+ for (var i = 0; i < formEls.length; i++) {
357
+ var form = formEls[i];
358
+ var formSel = formSelector(form);
359
+ var action = resolveAction(form);
360
+ var rawMethod = form.getAttribute('method');
361
+ var fields = [];
362
+ var fieldEls = form.querySelectorAll(FIELD_SELECTOR);
363
+ for (var j = 0; j < fieldEls.length; j++) {
364
+ fields.push(describeField(fieldEls[j], form, formSel));
365
+ }
366
+ var hasSubmit = !!form.querySelector('button:not([type="button"]):not([type="reset"]), input[type="submit"], button[type="submit"]');
367
+ var entry = {
368
+ selector: formSel,
369
+ // null when the DOM states neither — a JS-handled form, not a GET to self.
370
+ method: rawMethod ? rawMethod.toLowerCase() : null,
371
+ action: action,
372
+ hasSubmit: hasSubmit,
373
+ fields: fields,
374
+ };
375
+ // Only meaningful when there IS an action to classify.
376
+ if (action !== null) {
377
+ try {
378
+ entry.sameOriginAction = new URL(action).origin === window.location.origin;
379
+ }
380
+ catch (e) {
381
+ entry.sameOriginAction = true;
382
+ }
383
+ }
384
+ out.push(entry);
385
+ }
386
+ return out;
387
+ }
388
+ /**
389
+ * Input fields that live OUTSIDE any `<form>`.
390
+ *
391
+ * Not an edge case — it is the majority of modern React/Vue apps, which
392
+ * handle submission in JS and never wrap anything in a `<form>`. Measured on
393
+ * a real app: 464 `<input>/<select>/<textarea>` against 26 `<form>` tags, and
394
+ * a scan that only walked `document.querySelectorAll('form')` reported
395
+ * "0 forms · 0 fields" across nine authenticated pages. Reporting an absence
396
+ * that is not real is the same failure as the login wall and the href-blind
397
+ * crawl: a confident, wrong output on the field that matters most, since the
398
+ * input surface is where a test suite starts.
399
+ */
400
+ function looseFields() {
401
+ var out = [];
402
+ var els = document.querySelectorAll(FIELD_SELECTOR);
403
+ for (var i = 0; i < els.length; i++) {
404
+ var el = els[i];
405
+ if (el.closest('form'))
406
+ continue; // already reported under its form
407
+ if (!isVisible(el))
408
+ continue;
409
+ var anchor = anchorFor(el);
410
+ var field = describeField(el, anchor.root, anchor.sel);
411
+ var ctx = fieldContext(el);
412
+ if (ctx)
413
+ field.context = ctx;
414
+ out.push(field);
415
+ }
416
+ return out;
417
+ }
418
+ function isVisible(el) {
419
+ var rect = el.getBoundingClientRect();
420
+ if (rect.width === 0 && rect.height === 0)
421
+ return false;
422
+ var style = window.getComputedStyle(el);
423
+ return style.visibility !== 'hidden' && style.display !== 'none';
424
+ }
425
+ return { meta: meta(), headings: headings(), forms: forms(), looseFields: looseFields() };
426
+ }
427
+ //# sourceMappingURL=extractPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extractPage.js","sourceRoot":"","sources":["../../src/browser/extractPage.js"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Controls that might reveal more of the page when clicked.
3
+ *
4
+ * Self-contained (no imports, no TypeScript) — Playwright serializes this via
5
+ * `toString()` and injects it. Used two ways:
6
+ * 1. counted on every scan, so a page that hides most of its input surface
7
+ * behind clicks says so instead of reporting the loaded state as the app;
8
+ * 2. clicked one level deep by `--deep`, to capture what they reveal.
9
+ *
10
+ * SAFETY. The real guard is at the network layer — `explore.ts` aborts every
11
+ * non-GET request for the duration, so a click cannot mutate server state. This
12
+ * denylist is the second layer and is not redundant: a "log out" handler that
13
+ * clears storage and re-renders issues no request at all, so nothing at the
14
+ * network level would stop it.
15
+ */
16
+ export function findOpenablesInPage(): {
17
+ selector: string;
18
+ label: any;
19
+ }[];
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.findOpenablesInPage = findOpenablesInPage;
4
+ /**
5
+ * Controls that might reveal more of the page when clicked.
6
+ *
7
+ * Self-contained (no imports, no TypeScript) — Playwright serializes this via
8
+ * `toString()` and injects it. Used two ways:
9
+ * 1. counted on every scan, so a page that hides most of its input surface
10
+ * behind clicks says so instead of reporting the loaded state as the app;
11
+ * 2. clicked one level deep by `--deep`, to capture what they reveal.
12
+ *
13
+ * SAFETY. The real guard is at the network layer — `explore.ts` aborts every
14
+ * non-GET request for the duration, so a click cannot mutate server state. This
15
+ * denylist is the second layer and is not redundant: a "log out" handler that
16
+ * clears storage and re-renders issues no request at all, so nothing at the
17
+ * network level would stop it.
18
+ */
19
+ function findOpenablesInPage() {
20
+ var OPENABLE_SELECTOR = [
21
+ 'button',
22
+ '[role="button"]',
23
+ '[role="tab"]',
24
+ '[aria-expanded]',
25
+ '[aria-haspopup]',
26
+ 'summary',
27
+ '[onclick]',
28
+ ].join(', ');
29
+ /**
30
+ * A control whose LABEL names an action rather than a disclosure. Mirrors the
31
+ * spirit of `UNSAFE_URL_RE` in @ia-qa/self-healing's discovery/safety.ts, moved
32
+ * from the URL to the accessible name — deliberately broad, because a false
33
+ * positive costs one unopened panel while a false negative can delete data or
34
+ * end the session.
35
+ */
36
+ var UNSAFE_NAME_RE = /\b(log\s?out|sign\s?out|logout|signout|delete|destroy|remove|deactivate|disable|unsubscribe|revoke|cancel|purchase|checkout|payment|pay\b|buy|order|confirm|approve|reject|reset|submit|send|save|publish|deploy|archive|leave|quit|disconnect|déconnexion|supprimer|effacer|annuler|payer|acheter|confirmer|envoyer|enregistrer|valider)\b/i;
37
+ function clean(s) {
38
+ return (s || '').replace(/\s+/g, ' ').trim();
39
+ }
40
+ function label(el) {
41
+ var aria = clean(el.getAttribute('aria-label'));
42
+ if (aria)
43
+ return aria;
44
+ var title = clean(el.getAttribute('title'));
45
+ var text = clean(el.textContent);
46
+ if (text)
47
+ return text.slice(0, 80);
48
+ if (title)
49
+ return title.slice(0, 80);
50
+ return '';
51
+ }
52
+ function isVisible(el) {
53
+ var rect = el.getBoundingClientRect();
54
+ if (rect.width === 0 && rect.height === 0)
55
+ return false;
56
+ var style = window.getComputedStyle(el);
57
+ return style.visibility !== 'hidden' && style.display !== 'none' && style.opacity !== '0';
58
+ }
59
+ // Same shape as the field selectors: identity first, then the shortest
60
+ // positional path that resolves to exactly one element.
61
+ function nthOfType(el) {
62
+ var sib = el.parentElement ? el.parentElement.children : [];
63
+ var n = 0;
64
+ for (var i = 0; i < sib.length; i++) {
65
+ if (sib[i].tagName === el.tagName) {
66
+ n++;
67
+ if (sib[i] === el)
68
+ return n;
69
+ }
70
+ }
71
+ return 1;
72
+ }
73
+ function resolvesToOne(sel, el) {
74
+ try {
75
+ var f = document.querySelectorAll(sel);
76
+ return f.length === 1 && f[0] === el;
77
+ }
78
+ catch (e) {
79
+ return false;
80
+ }
81
+ }
82
+ function selectorFor(el) {
83
+ var tid = el.getAttribute('data-testid') || el.getAttribute('data-test-id') || el.getAttribute('data-qa');
84
+ if (tid) {
85
+ var s = '[data-testid="' + tid + '"]';
86
+ if (resolvesToOne(s, el))
87
+ return s;
88
+ }
89
+ if (el.id) {
90
+ var byId = '#' + CSS.escape(el.id);
91
+ if (resolvesToOne(byId, el))
92
+ return byId;
93
+ }
94
+ var steps = [];
95
+ var node = el;
96
+ while (node && node !== document.body) {
97
+ steps.unshift(node.tagName.toLowerCase() + ':nth-of-type(' + nthOfType(node) + ')');
98
+ var bare = steps.join(' > ');
99
+ if (resolvesToOne(bare, el))
100
+ return bare;
101
+ node = node.parentElement;
102
+ }
103
+ return steps.join(' > ');
104
+ }
105
+ var out = [];
106
+ var seen = {};
107
+ var found = document.querySelectorAll(OPENABLE_SELECTOR);
108
+ for (var i = 0; i < found.length; i++) {
109
+ var el = found[i];
110
+ if (!isVisible(el))
111
+ continue;
112
+ // A control inside a form is part of that form's own flow (submit, reset);
113
+ // clicking it is acting, not disclosing.
114
+ if (el.closest('form'))
115
+ continue;
116
+ var name = label(el);
117
+ if (name && UNSAFE_NAME_RE.test(name))
118
+ continue;
119
+ var sel = selectorFor(el);
120
+ if (!sel || seen[sel])
121
+ continue;
122
+ seen[sel] = true;
123
+ out.push({ selector: sel, label: name });
124
+ }
125
+ return out;
126
+ }
127
+ //# sourceMappingURL=openables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openables.js","sourceRoot":"","sources":["../../src/browser/openables.js"],"names":[],"mappings":"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"}