craftdriver 1.8.0 → 1.9.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 (108) hide show
  1. package/CHANGELOG.md +6 -5
  2. package/README.md +3 -2
  3. package/dist/cli/pageSemantics.d.ts +3 -39
  4. package/dist/cli/pageSemantics.d.ts.map +1 -1
  5. package/dist/cli/pageSemantics.js +3 -191
  6. package/dist/cli/pageSemantics.js.map +1 -1
  7. package/dist/cli/selector.d.ts +3 -3
  8. package/dist/cli/selector.d.ts.map +1 -1
  9. package/dist/cli/selector.js +6 -9
  10. package/dist/cli/selector.js.map +1 -1
  11. package/dist/cli/snapshot.d.ts +5 -6
  12. package/dist/cli/snapshot.d.ts.map +1 -1
  13. package/dist/cli/snapshot.js +59 -18
  14. package/dist/cli/snapshot.js.map +1 -1
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/lib/a11y.d.ts +6 -2
  20. package/dist/lib/a11y.d.ts.map +1 -1
  21. package/dist/lib/a11y.js +3 -1
  22. package/dist/lib/a11y.js.map +1 -1
  23. package/dist/lib/bidi/evaluate.d.ts +11 -0
  24. package/dist/lib/bidi/evaluate.d.ts.map +1 -0
  25. package/dist/lib/bidi/evaluate.js +25 -0
  26. package/dist/lib/bidi/evaluate.js.map +1 -0
  27. package/dist/lib/bidi/types.d.ts +2 -0
  28. package/dist/lib/bidi/types.d.ts.map +1 -1
  29. package/dist/lib/browser.d.ts +1 -1
  30. package/dist/lib/browser.d.ts.map +1 -1
  31. package/dist/lib/browser.js +46 -35
  32. package/dist/lib/browser.js.map +1 -1
  33. package/dist/lib/browserContext.d.ts +4 -6
  34. package/dist/lib/browserContext.d.ts.map +1 -1
  35. package/dist/lib/browserContext.js +5 -7
  36. package/dist/lib/browserContext.js.map +1 -1
  37. package/dist/lib/by.d.ts +65 -27
  38. package/dist/lib/by.d.ts.map +1 -1
  39. package/dist/lib/by.js +47 -20
  40. package/dist/lib/by.js.map +1 -1
  41. package/dist/lib/clearFastPath.d.ts.map +1 -1
  42. package/dist/lib/clearFastPath.js +2 -0
  43. package/dist/lib/clearFastPath.js.map +1 -1
  44. package/dist/lib/clickFastPath.d.ts.map +1 -1
  45. package/dist/lib/clickFastPath.js +2 -0
  46. package/dist/lib/clickFastPath.js.map +1 -1
  47. package/dist/lib/driver.d.ts +19 -0
  48. package/dist/lib/driver.d.ts.map +1 -1
  49. package/dist/lib/driver.js +111 -4
  50. package/dist/lib/driver.js.map +1 -1
  51. package/dist/lib/elementHandle.d.ts +13 -10
  52. package/dist/lib/elementHandle.d.ts.map +1 -1
  53. package/dist/lib/elementHandle.js +119 -50
  54. package/dist/lib/elementHandle.js.map +1 -1
  55. package/dist/lib/errors.d.ts +5 -1
  56. package/dist/lib/errors.d.ts.map +1 -1
  57. package/dist/lib/errors.js +5 -1
  58. package/dist/lib/errors.js.map +1 -1
  59. package/dist/lib/expect.d.ts +10 -0
  60. package/dist/lib/expect.d.ts.map +1 -1
  61. package/dist/lib/expect.js +76 -49
  62. package/dist/lib/expect.js.map +1 -1
  63. package/dist/lib/fillFastPath.d.ts.map +1 -1
  64. package/dist/lib/fillFastPath.js +2 -0
  65. package/dist/lib/fillFastPath.js.map +1 -1
  66. package/dist/lib/frame.d.ts.map +1 -1
  67. package/dist/lib/frame.js +29 -17
  68. package/dist/lib/frame.js.map +1 -1
  69. package/dist/lib/locator.d.ts +21 -54
  70. package/dist/lib/locator.d.ts.map +1 -1
  71. package/dist/lib/locator.js +165 -208
  72. package/dist/lib/locator.js.map +1 -1
  73. package/dist/lib/page.d.ts.map +1 -1
  74. package/dist/lib/page.js +23 -13
  75. package/dist/lib/page.js.map +1 -1
  76. package/dist/lib/pageSemantics.d.ts +42 -0
  77. package/dist/lib/pageSemantics.d.ts.map +1 -0
  78. package/dist/lib/pageSemantics.js +216 -0
  79. package/dist/lib/pageSemantics.js.map +1 -0
  80. package/dist/lib/query.d.ts +68 -0
  81. package/dist/lib/query.d.ts.map +1 -0
  82. package/dist/lib/query.js +590 -0
  83. package/dist/lib/query.js.map +1 -0
  84. package/dist/lib/shadowRoot.d.ts +21 -0
  85. package/dist/lib/shadowRoot.d.ts.map +1 -0
  86. package/dist/lib/shadowRoot.js +29 -0
  87. package/dist/lib/shadowRoot.js.map +1 -0
  88. package/dist/lib/shadowRootLocator.d.ts +31 -0
  89. package/dist/lib/shadowRootLocator.d.ts.map +1 -0
  90. package/dist/lib/shadowRootLocator.js +55 -0
  91. package/dist/lib/shadowRootLocator.js.map +1 -0
  92. package/dist/lib/timing.d.ts +2 -2
  93. package/dist/lib/timing.js +2 -2
  94. package/docs/accessibility.md +9 -1
  95. package/docs/api-reference.md +4 -1
  96. package/docs/browser-api.md +3 -3
  97. package/docs/browser-context.md +3 -3
  98. package/docs/cli.md +10 -7
  99. package/docs/error-codes.md +3 -1
  100. package/docs/getting-started.md +1 -1
  101. package/docs/mcp.md +9 -5
  102. package/docs/public/examples/iframe-child.html +12 -1
  103. package/docs/public/examples/shadow-dom.html +137 -0
  104. package/docs/recipes/login-once-reuse-session.md +1 -1
  105. package/docs/selectors.md +61 -0
  106. package/docs/session-management.md +17 -10
  107. package/package.json +3 -3
  108. package/skills/craftdriver/patterns.md +3 -0
package/CHANGELOG.md CHANGED
@@ -1,15 +1,16 @@
1
- # [1.8.0](https://github.com/dtopuzov/craftdriver/compare/v1.7.0...v1.8.0) (2026-07-21)
1
+ # [1.9.0](https://github.com/dtopuzov/craftdriver/compare/v1.8.0...v1.9.0) (2026-07-24)
2
2
 
3
3
 
4
4
  ### Features
5
5
 
6
- * **agent:** add AI tooling and reliable auth-state reuse ([2a0f079](https://github.com/dtopuzov/craftdriver/commit/2a0f079b327ffd1545fa0f1919e06045e89422dc))
6
+ * add open Shadow DOM support ([#49](https://github.com/dtopuzov/craftdriver/issues/49)) ([fadd962](https://github.com/dtopuzov/craftdriver/commit/fadd962c6d1a583501d9efb7c8117d42ce3710a6)), closes [#40](https://github.com/dtopuzov/craftdriver/issues/40)
7
+
8
+ # [1.8.0](https://github.com/dtopuzov/craftdriver/compare/v1.7.0...v1.8.0) (2026-07-21)
7
9
 
8
- ## Unreleased
9
10
 
10
11
  ### Features
11
12
 
12
- * **agent CLI:** add a persistent browser exploration workflow with semantic snapshots, safe temporary refs, live-validated durable locators, manual QA actions, console/network evidence, mocks, traces, and reusable login state
13
+ * **agent CLI:** add a persistent browser exploration workflow with semantic snapshots, safe temporary refs, live-validated durable locators, manual QA actions, console/network evidence, mocks, traces, and reusable login state ([2a0f079](https://github.com/dtopuzov/craftdriver/commit/2a0f079b327ffd1545fa0f1919e06045e89422dc))
13
14
  * **auth state:** restore cookies and multi-origin localStorage before the first navigation on BiDi launch and contexts, with path/object inputs and one-time hydration that preserves later application writes
14
15
  * **sessions:** isolate browsers, cookies, pages, refs, and artifacts in named sessions under a project-scoped daemon
15
16
  * **MCP:** add a validated stdio tool server with automatic post-action snapshot diffs, bounded responses, and quota-controlled file artifacts for token-efficient context
@@ -220,7 +221,7 @@ Fixes: https://github.com/dtopuzov/craftdriver/issues/20
220
221
 
221
222
  # [0.1.0](https://github.com/dtopuzov/craftdriver/compare/v0.0.3...v0.1.0) (2026-02-08)
222
223
 
223
- ## Unreleased
224
+ ### Changes
224
225
 
225
226
  - docs: refresh the README as a product front door, add a VitePress documentation site with GitHub Pages deployment, add proof pages/launch kit/social card, and add contribution files (issue forms, PR template, code of conduct).
226
227
  - **breaking** (pre-1.0): BiDi console/error log capture is lazy by default. Messages emitted before the first `browser.logs` / `onConsole` / `onError` / `waitForConsole` touch are no longer captured unless `Browser.launch({ captureLogs: true })` is used to arm logging at launch.
package/README.md CHANGED
@@ -89,11 +89,11 @@ await browser.network.mock('**/api/users', {
89
89
  });
90
90
 
91
91
  // Save and reuse login state
92
- await browser.saveState('./session.json');
92
+ await browser.saveState('.auth/session.json');
93
93
 
94
94
  await Browser.launch({
95
95
  browserName: 'chrome',
96
- storageState: './session.json',
96
+ storageState: '.auth/session.json',
97
97
  });
98
98
 
99
99
  // Built-in accessibility checks via axe-core
@@ -113,6 +113,7 @@ explicit single-active-origin fallback after navigation; see
113
113
  | Driver management | Zero-config driver resolution, cache behavior, env vars, offline mode | [Driver configuration](https://dtopuzov.github.io/craftdriver/driver-configuration) |
114
114
  | Browser control | Navigation, tabs, popups, iframes, content helpers, evaluate, init scripts | [Browser API](https://dtopuzov.github.io/craftdriver/browser-api) |
115
115
  | Locators | CSS, XPath, text, role, label, test id, and composable `locator()` chains | [Selectors](https://dtopuzov.github.io/craftdriver/selectors) |
116
+ | Open Shadow DOM | Explicit lazy `shadowRoot()` boundaries over WebDriver Classic and BiDi | [Shadow DOM](https://dtopuzov.github.io/craftdriver/selectors#open-shadow-dom) |
116
117
  | Element actions | Click, fill, upload, inspect, and interact through element handles | [Element API](https://dtopuzov.github.io/craftdriver/element-api) |
117
118
  | Assertions | Built-in `expect(...)`, retries, visibility, text, attributes, and timing behavior | [Assertions](https://dtopuzov.github.io/craftdriver/assertions) |
118
119
  | Input | Low-level key presses, mouse movement, hover, drag, and pointer input | [Keyboard and mouse](https://dtopuzov.github.io/craftdriver/keyboard-mouse) |
@@ -1,42 +1,6 @@
1
1
  /**
2
- * Page-side role and accessible-name extraction, shared by the snapshot and
3
- * the locator-candidate builder.
4
- *
5
- * These two surfaces must agree, and both must agree with `By.role` — that is
6
- * the whole point of the module. The snapshot tells an agent an element is a
7
- * `listbox`; the candidate builder proposes `role=listbox[name=Colors]`; and
8
- * `By.role('listbox', { name: 'Colors' })` has to actually resolve it in the
9
- * committed test. When those three drifted apart, the recommended locator for
10
- * a multi-select was a brittle `text=RedBlue`.
11
- *
12
- * So the mapping lives here once, `src/lib/by.ts` stays the resolution
13
- * authority, and `tests/cli/role-conformance.test.ts` pins the agreement
14
- * against a real browser.
15
- *
16
- * Emitted as JS **source text**: both callers assemble a body for
17
- * `page.evaluate`, and the build has no DOM lib. Keep it dependency-free and
18
- * side-effect-free — it is concatenated into larger scripts.
19
- *
20
- * ## The ARIA role / display token split
21
- *
22
- * `ariaRole` returns a real ARIA role or `null`. `null` is not a failure: an
23
- * `<input type="password">` genuinely has no ARIA role, and pretending it is a
24
- * `textbox` produces a `role=textbox[name=Password]` that resolves to nothing.
25
- * The snapshot falls back to `displayRole` (the tag name) so the element still
26
- * appears, while the candidate builder proposes a role locator only when
27
- * `ariaRole` is non-null. Honest over convenient.
2
+ * Compatibility re-export. The page-side semantic evaluator is shared by the
3
+ * public locator engine and CLI snapshot/candidate surfaces.
28
4
  */
29
- /**
30
- * Function declarations injected into a page-side script.
31
- *
32
- * Provides `firstRoleToken`, `hasSectioningAncestor`, `ariaRole`,
33
- * `displayRole`, `associatedLabel` and `accName`.
34
- */
35
- export declare const PAGE_SEMANTICS_JS = "\nfunction firstRoleToken(el) {\n const role = (el.getAttribute('role') || '').trim();\n return role ? role.split(/\\s+/)[0] : null;\n}\n// Mirrors HAS_SECTIONING_ANCESTOR in src/lib/by.ts: header/footer are only\n// banner/contentinfo when not nested in sectioning content.\nfunction hasSectioningAncestor(el) {\n for (let p = el.parentElement; p; p = p.parentElement) {\n const t = p.tagName.toLowerCase();\n if (t === 'article' || t === 'aside' || t === 'main' || t === 'nav' || t === 'section') {\n return true;\n }\n const role = firstRoleToken(p);\n if (\n role === 'article' ||\n role === 'complementary' ||\n role === 'main' ||\n role === 'navigation' ||\n role === 'region'\n ) {\n return true;\n }\n }\n return false;\n}\n// The ARIA role, or null when the element has none that By.role can resolve.\n// Every branch here must have a counterpart in IMPLICIT_ROLE_XPATH.\nfunction ariaRole(el) {\n const explicit = firstRoleToken(el);\n if (explicit) return explicit;\n const t = el.tagName.toLowerCase();\n if (t === 'a' || t === 'area') return el.hasAttribute('href') ? 'link' : null;\n if (t === 'button' || t === 'summary') return 'button';\n if (t === 'input') {\n const it = (el.getAttribute('type') || 'text').toLowerCase();\n if (it === 'submit' || it === 'button' || it === 'reset' || it === 'image') return 'button';\n if (it === 'checkbox') return 'checkbox';\n if (it === 'radio') return 'radio';\n if (it === 'search') return 'searchbox';\n if (it === 'number') return 'spinbutton';\n if (it === 'range') return 'slider';\n if (it === 'text' || it === 'email' || it === 'tel' || it === 'url') return 'textbox';\n // password, date, file, color, hidden\u2026 have no corresponding ARIA role.\n return el.hasAttribute('type') ? null : 'textbox';\n }\n if (t === 'textarea') return 'textbox';\n // multiple/size are reflected IDL attributes, so reading the properties\n // stays equivalent to the attribute test By.role compiles to XPath.\n if (t === 'select') return el.multiple || el.size > 1 ? 'listbox' : 'combobox';\n if (/^h[1-6]$/.test(t)) return 'heading';\n if (t === 'img') return 'img';\n if (t === 'ul' || t === 'ol') return 'list';\n if (t === 'li') return 'listitem';\n if (t === 'table') return 'table';\n if (t === 'tr') return 'row';\n if (t === 'td') return 'cell';\n if (t === 'th') return 'columnheader';\n if (t === 'nav') return 'navigation';\n if (t === 'main') return 'main';\n if (t === 'article') return 'article';\n if (t === 'form') return 'form';\n if (t === 'header') return hasSectioningAncestor(el) ? null : 'banner';\n if (t === 'footer') return hasSectioningAncestor(el) ? null : 'contentinfo';\n return null;\n}\n// What the snapshot prints. Falls back to the tag name so an element with no\n// ARIA role is still listed and still addressable by ref.\nfunction displayRole(el) {\n return ariaRole(el) || el.tagName.toLowerCase();\n}\n// The <label> a user reads for a form control, independent of accName \u2014\n// By.labelText resolves against exactly this.\nfunction associatedLabel(el) {\n const t = el.tagName;\n if (t !== 'INPUT' && t !== 'TEXTAREA' && t !== 'SELECT') return null;\n if (el.id) {\n const forLabel = document.querySelector('label[for=' + JSON.stringify(el.id) + ']');\n if (forLabel) return (forLabel.textContent || '').trim() || null;\n }\n const parentLabel = el.closest('label');\n if (parentLabel) return (parentLabel.textContent || '').trim() || null;\n return null;\n}\n// Approximates the accessible name, in the same source order By.role's name\n// predicate checks. Sources By.role cannot match must not appear here.\nfunction accName(el) {\n const aria = el.getAttribute('aria-label');\n if (aria && aria.trim()) return aria.trim();\n const labelledby = el.getAttribute('aria-labelledby');\n if (labelledby) {\n // Single id only \u2014 By.role's @aria-labelledby test is an equality match.\n const ref = document.getElementById(labelledby);\n if (ref) {\n const t = (ref.textContent || '').trim();\n if (t) return t;\n }\n }\n const label = associatedLabel(el);\n if (label) return label;\n const tag = el.tagName;\n if (tag === 'INPUT') {\n const it = (el.getAttribute('type') || 'text').toLowerCase();\n // Native buttons carry their name in value=, not in text content.\n if (it === 'submit' || it === 'button' || it === 'reset') {\n const v = el.getAttribute('value');\n if (v && v.trim()) return v.trim();\n }\n if (it === 'image') {\n const alt = el.getAttribute('alt');\n if (alt && alt.trim()) return alt.trim();\n }\n }\n if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') {\n const placeholder = el.getAttribute('placeholder');\n if (placeholder && placeholder.trim()) return placeholder.trim();\n }\n if (tag === 'IMG') {\n const alt = el.getAttribute('alt');\n if (alt && alt.trim()) return alt.trim();\n }\n const text = (el.textContent || '').trim().replace(/\\s+/g, ' ');\n if (text) return text;\n const title = el.getAttribute('title');\n if (title && title.trim()) return title.trim();\n return '';\n}\n";
36
- /**
37
- * Every role `ariaRole` can emit for a native element. The conformance test
38
- * walks this list, so a new branch above without a `By.role` counterpart
39
- * fails CI rather than shipping an unresolvable recommendation.
40
- */
41
- export declare const EMITTABLE_ROLES: readonly ["link", "button", "checkbox", "radio", "searchbox", "spinbutton", "slider", "textbox", "listbox", "combobox", "heading", "img", "list", "listitem", "table", "row", "cell", "columnheader", "navigation", "main", "article", "form", "banner", "contentinfo"];
5
+ export { PAGE_SEMANTICS_JS, EMITTABLE_ROLES } from '../lib/pageSemantics.js';
42
6
  //# sourceMappingURL=pageSemantics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pageSemantics.d.ts","sourceRoot":"","sources":["../../src/cli/pageSemantics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,+nKA+H7B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,yQAyBlB,CAAC"}
1
+ {"version":3,"file":"pageSemantics.d.ts","sourceRoot":"","sources":["../../src/cli/pageSemantics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
@@ -1,194 +1,6 @@
1
1
  /**
2
- * Page-side role and accessible-name extraction, shared by the snapshot and
3
- * the locator-candidate builder.
4
- *
5
- * These two surfaces must agree, and both must agree with `By.role` — that is
6
- * the whole point of the module. The snapshot tells an agent an element is a
7
- * `listbox`; the candidate builder proposes `role=listbox[name=Colors]`; and
8
- * `By.role('listbox', { name: 'Colors' })` has to actually resolve it in the
9
- * committed test. When those three drifted apart, the recommended locator for
10
- * a multi-select was a brittle `text=RedBlue`.
11
- *
12
- * So the mapping lives here once, `src/lib/by.ts` stays the resolution
13
- * authority, and `tests/cli/role-conformance.test.ts` pins the agreement
14
- * against a real browser.
15
- *
16
- * Emitted as JS **source text**: both callers assemble a body for
17
- * `page.evaluate`, and the build has no DOM lib. Keep it dependency-free and
18
- * side-effect-free — it is concatenated into larger scripts.
19
- *
20
- * ## The ARIA role / display token split
21
- *
22
- * `ariaRole` returns a real ARIA role or `null`. `null` is not a failure: an
23
- * `<input type="password">` genuinely has no ARIA role, and pretending it is a
24
- * `textbox` produces a `role=textbox[name=Password]` that resolves to nothing.
25
- * The snapshot falls back to `displayRole` (the tag name) so the element still
26
- * appears, while the candidate builder proposes a role locator only when
27
- * `ariaRole` is non-null. Honest over convenient.
2
+ * Compatibility re-export. The page-side semantic evaluator is shared by the
3
+ * public locator engine and CLI snapshot/candidate surfaces.
28
4
  */
29
- /**
30
- * Function declarations injected into a page-side script.
31
- *
32
- * Provides `firstRoleToken`, `hasSectioningAncestor`, `ariaRole`,
33
- * `displayRole`, `associatedLabel` and `accName`.
34
- */
35
- export const PAGE_SEMANTICS_JS = `
36
- function firstRoleToken(el) {
37
- const role = (el.getAttribute('role') || '').trim();
38
- return role ? role.split(/\\s+/)[0] : null;
39
- }
40
- // Mirrors HAS_SECTIONING_ANCESTOR in src/lib/by.ts: header/footer are only
41
- // banner/contentinfo when not nested in sectioning content.
42
- function hasSectioningAncestor(el) {
43
- for (let p = el.parentElement; p; p = p.parentElement) {
44
- const t = p.tagName.toLowerCase();
45
- if (t === 'article' || t === 'aside' || t === 'main' || t === 'nav' || t === 'section') {
46
- return true;
47
- }
48
- const role = firstRoleToken(p);
49
- if (
50
- role === 'article' ||
51
- role === 'complementary' ||
52
- role === 'main' ||
53
- role === 'navigation' ||
54
- role === 'region'
55
- ) {
56
- return true;
57
- }
58
- }
59
- return false;
60
- }
61
- // The ARIA role, or null when the element has none that By.role can resolve.
62
- // Every branch here must have a counterpart in IMPLICIT_ROLE_XPATH.
63
- function ariaRole(el) {
64
- const explicit = firstRoleToken(el);
65
- if (explicit) return explicit;
66
- const t = el.tagName.toLowerCase();
67
- if (t === 'a' || t === 'area') return el.hasAttribute('href') ? 'link' : null;
68
- if (t === 'button' || t === 'summary') return 'button';
69
- if (t === 'input') {
70
- const it = (el.getAttribute('type') || 'text').toLowerCase();
71
- if (it === 'submit' || it === 'button' || it === 'reset' || it === 'image') return 'button';
72
- if (it === 'checkbox') return 'checkbox';
73
- if (it === 'radio') return 'radio';
74
- if (it === 'search') return 'searchbox';
75
- if (it === 'number') return 'spinbutton';
76
- if (it === 'range') return 'slider';
77
- if (it === 'text' || it === 'email' || it === 'tel' || it === 'url') return 'textbox';
78
- // password, date, file, color, hidden… have no corresponding ARIA role.
79
- return el.hasAttribute('type') ? null : 'textbox';
80
- }
81
- if (t === 'textarea') return 'textbox';
82
- // multiple/size are reflected IDL attributes, so reading the properties
83
- // stays equivalent to the attribute test By.role compiles to XPath.
84
- if (t === 'select') return el.multiple || el.size > 1 ? 'listbox' : 'combobox';
85
- if (/^h[1-6]$/.test(t)) return 'heading';
86
- if (t === 'img') return 'img';
87
- if (t === 'ul' || t === 'ol') return 'list';
88
- if (t === 'li') return 'listitem';
89
- if (t === 'table') return 'table';
90
- if (t === 'tr') return 'row';
91
- if (t === 'td') return 'cell';
92
- if (t === 'th') return 'columnheader';
93
- if (t === 'nav') return 'navigation';
94
- if (t === 'main') return 'main';
95
- if (t === 'article') return 'article';
96
- if (t === 'form') return 'form';
97
- if (t === 'header') return hasSectioningAncestor(el) ? null : 'banner';
98
- if (t === 'footer') return hasSectioningAncestor(el) ? null : 'contentinfo';
99
- return null;
100
- }
101
- // What the snapshot prints. Falls back to the tag name so an element with no
102
- // ARIA role is still listed and still addressable by ref.
103
- function displayRole(el) {
104
- return ariaRole(el) || el.tagName.toLowerCase();
105
- }
106
- // The <label> a user reads for a form control, independent of accName —
107
- // By.labelText resolves against exactly this.
108
- function associatedLabel(el) {
109
- const t = el.tagName;
110
- if (t !== 'INPUT' && t !== 'TEXTAREA' && t !== 'SELECT') return null;
111
- if (el.id) {
112
- const forLabel = document.querySelector('label[for=' + JSON.stringify(el.id) + ']');
113
- if (forLabel) return (forLabel.textContent || '').trim() || null;
114
- }
115
- const parentLabel = el.closest('label');
116
- if (parentLabel) return (parentLabel.textContent || '').trim() || null;
117
- return null;
118
- }
119
- // Approximates the accessible name, in the same source order By.role's name
120
- // predicate checks. Sources By.role cannot match must not appear here.
121
- function accName(el) {
122
- const aria = el.getAttribute('aria-label');
123
- if (aria && aria.trim()) return aria.trim();
124
- const labelledby = el.getAttribute('aria-labelledby');
125
- if (labelledby) {
126
- // Single id only — By.role's @aria-labelledby test is an equality match.
127
- const ref = document.getElementById(labelledby);
128
- if (ref) {
129
- const t = (ref.textContent || '').trim();
130
- if (t) return t;
131
- }
132
- }
133
- const label = associatedLabel(el);
134
- if (label) return label;
135
- const tag = el.tagName;
136
- if (tag === 'INPUT') {
137
- const it = (el.getAttribute('type') || 'text').toLowerCase();
138
- // Native buttons carry their name in value=, not in text content.
139
- if (it === 'submit' || it === 'button' || it === 'reset') {
140
- const v = el.getAttribute('value');
141
- if (v && v.trim()) return v.trim();
142
- }
143
- if (it === 'image') {
144
- const alt = el.getAttribute('alt');
145
- if (alt && alt.trim()) return alt.trim();
146
- }
147
- }
148
- if (tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT') {
149
- const placeholder = el.getAttribute('placeholder');
150
- if (placeholder && placeholder.trim()) return placeholder.trim();
151
- }
152
- if (tag === 'IMG') {
153
- const alt = el.getAttribute('alt');
154
- if (alt && alt.trim()) return alt.trim();
155
- }
156
- const text = (el.textContent || '').trim().replace(/\\s+/g, ' ');
157
- if (text) return text;
158
- const title = el.getAttribute('title');
159
- if (title && title.trim()) return title.trim();
160
- return '';
161
- }
162
- `;
163
- /**
164
- * Every role `ariaRole` can emit for a native element. The conformance test
165
- * walks this list, so a new branch above without a `By.role` counterpart
166
- * fails CI rather than shipping an unresolvable recommendation.
167
- */
168
- export const EMITTABLE_ROLES = [
169
- 'link',
170
- 'button',
171
- 'checkbox',
172
- 'radio',
173
- 'searchbox',
174
- 'spinbutton',
175
- 'slider',
176
- 'textbox',
177
- 'listbox',
178
- 'combobox',
179
- 'heading',
180
- 'img',
181
- 'list',
182
- 'listitem',
183
- 'table',
184
- 'row',
185
- 'cell',
186
- 'columnheader',
187
- 'navigation',
188
- 'main',
189
- 'article',
190
- 'form',
191
- 'banner',
192
- 'contentinfo',
193
- ];
5
+ export { PAGE_SEMANTICS_JS, EMITTABLE_ROLES } from '../lib/pageSemantics.js';
194
6
  //# sourceMappingURL=pageSemantics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pageSemantics.js","sourceRoot":"","sources":["../../src/cli/pageSemantics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+HhC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,MAAM;IACN,QAAQ;IACR,UAAU;IACV,OAAO;IACP,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,SAAS;IACT,UAAU;IACV,SAAS;IACT,KAAK;IACL,MAAM;IACN,UAAU;IACV,OAAO;IACP,KAAK;IACL,MAAM;IACN,cAAc;IACd,YAAY;IACZ,MAAM;IACN,SAAS;IACT,MAAM;IACN,QAAQ;IACR,aAAa;CACL,CAAC"}
1
+ {"version":3,"file":"pageSemantics.js","sourceRoot":"","sources":["../../src/cli/pageSemantics.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
@@ -17,10 +17,10 @@
17
17
  * placeholder=Search… → By.placeholder('Search…')
18
18
  * alt=Logo → By.altText('Logo')
19
19
  * title=Help → By.title('Help')
20
- * ref=e5 → By.css('[data-craftdriver-ref="e5"]')
20
+ * ref=e5 → By.ref('e5') (resolved through the page identity registry)
21
21
  * (refs come from `craftdriver snapshot` /
22
- * browser_snapshot; invalidated by the next
23
- * snapshot or navigation)
22
+ * browser_snapshot; invalidated by detachment,
23
+ * navigation, or page replacement)
24
24
  */
25
25
  import { By } from '../lib/by.js';
26
26
  export declare function parseSelector(input: string): By;
@@ -1 +1 @@
1
- {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../src/cli/selector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAKlC,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,CA8E/C;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAE/C"}
1
+ {"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../src/cli/selector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAKlC,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,EAAE,CA2E/C;AAED,kEAAkE;AAClE,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,EAAE,GAAG,MAAM,CAE/C"}
@@ -17,10 +17,10 @@
17
17
  * placeholder=Search… → By.placeholder('Search…')
18
18
  * alt=Logo → By.altText('Logo')
19
19
  * title=Help → By.title('Help')
20
- * ref=e5 → By.css('[data-craftdriver-ref="e5"]')
20
+ * ref=e5 → By.ref('e5') (resolved through the page identity registry)
21
21
  * (refs come from `craftdriver snapshot` /
22
- * browser_snapshot; invalidated by the next
23
- * snapshot or navigation)
22
+ * browser_snapshot; invalidated by detachment,
23
+ * navigation, or page replacement)
24
24
  */
25
25
  import { By } from '../lib/by.js';
26
26
  import { CraftdriverError, ErrorCode } from '../lib/errors.js';
@@ -76,16 +76,13 @@ export function parseSelector(input) {
76
76
  case 'data-testid':
77
77
  return By.testId(valueRaw);
78
78
  case 'ref': {
79
- // Refs are stamped onto elements by the snapshot evaluator as
80
- // `data-craftdriver-ref="eN"`. They are stable until the next
81
- // snapshot or navigation. We resolve them as a plain CSS
82
- // attribute selector so all the usual auto-waiting paths work
83
- // unchanged.
79
+ // Refs resolve through the page's identity registry. The marker
80
+ // attribute is diagnostic only and cannot cross a shadow boundary.
84
81
  const v = valueRaw.trim();
85
82
  if (!/^e\d+$/.test(v)) {
86
83
  throw new CraftdriverError(ErrorCode.INVALID_ARGUMENT, `parseSelector: invalid ref "${valueRaw}"`, { hint: 'refs look like e1, e2, … (take a snapshot to see them)' });
87
84
  }
88
- return By.css(`[data-craftdriver-ref="${v}"]`);
85
+ return By.ref(v);
89
86
  }
90
87
  default:
91
88
  // Treat unknown prefix as part of a CSS selector (e.g. attribute
@@ -1 +1 @@
1
- {"version":3,"file":"selector.js","sourceRoot":"","sources":["../../src/cli/selector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"selector.js","sourceRoot":"","sources":["../../src/cli/selector.ts"],"names":[],"mappings":"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"}
@@ -27,17 +27,16 @@
27
27
  * makes every pre-navigation ref detectably stale instead of silently
28
28
  * rebound.
29
29
  *
30
- * The element marker attribute (`data-craftdriver-ref`) is kept so
31
- * `ref=eN` still resolves through the ordinary CSS auto-waiting path, but
32
- * the map not the attribute is the source of truth. An attribute that
33
- * the map does not corroborate (authored into the HTML, or duplicated by
34
- * `cloneNode`) never resolves.
30
+ * The element marker attribute (`data-craftdriver-ref`) is diagnostic only.
31
+ * Resolution goes directly through the registry, which works for elements
32
+ * inside open shadow trees and cannot be confused by authored or cloned
33
+ * marker attributes.
35
34
  */
36
35
  import type { Browser } from '../lib/browser.js';
37
36
  export interface SnapshotShape {
38
37
  url: string;
39
38
  title: string;
40
- /** One line per visible interactive node, prefixed with `eN: `. */
39
+ /** Visible semantic nodes plus indented open-shadow boundary lines. */
41
40
  lines: string[];
42
41
  /**
43
42
  * Identity of the document the refs belong to. Changes on navigation and
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/cli/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAYjD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+DAA+D;AAC/D,MAAM,MAAM,SAAS,GACjB,IAAI,GACJ,aAAa,GACb,aAAa,GACb,kBAAkB,GAClB,aAAa,GACb,UAAU,GACV,WAAW,CAAC;AAEhB,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,MAAM,SAAI,GACT,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAwB/B;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOzE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAChC,OAAO,CAAC,QAAQ,CAAC,CAgBnB;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAU3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,IAAI,EAAE,aAAa,GAAG,IAAI,GACzB,MAAM,CA8CR;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM,CAO7D;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAK;IAEtB,iEAAiE;IACjE,IAAI,UAAU,IAAI,MAAM,GAAG,IAAI,CAE9B;IAED,IAAI,OAAO,IAAI,aAAa,GAAG,IAAI,CAElC;IAED;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,yEAAyE;IACzE,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI;IAQxD,4DAA4D;IAC5D,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM;IAO3C,KAAK,IAAI,IAAI;CAGd"}
1
+ {"version":3,"file":"snapshot.d.ts","sourceRoot":"","sources":["../../src/cli/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAYjD,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IACnB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,+EAA+E;IAC/E,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,+DAA+D;AAC/D,MAAM,MAAM,SAAS,GACjB,IAAI,GACJ,aAAa,GACb,aAAa,GACb,kBAAkB,GAClB,aAAa,GACb,UAAU,GACV,WAAW,CAAC;AAEhB,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,MAAM,SAAI,GACT,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAwB/B;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOzE;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,EACX,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAChC,OAAO,CAAC,QAAQ,CAAC,CAgBnB;AAED,6DAA6D;AAC7D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAU3D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,aAAa,GAAG,IAAI,EAC1B,IAAI,EAAE,aAAa,GAAG,IAAI,GACzB,MAAM,CA8CR;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM,CAO7D;AAED;;;;;;GAMG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAA8B;IAC9C,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAK;IAEtB,iEAAiE;IACjE,IAAI,UAAU,IAAI,MAAM,GAAG,IAAI,CAE9B;IAED,IAAI,OAAO,IAAI,aAAa,GAAG,IAAI,CAElC;IAED;;;;;;OAMG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,yEAAyE;IACzE,MAAM,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,aAAa,GAAG,IAAI;IAQxD,4DAA4D;IAC5D,OAAO,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,GAAG,MAAM;IAO3C,KAAK,IAAI,IAAI;CAGd"}
@@ -117,7 +117,7 @@ export function renderDelta(prev, next) {
117
117
  if (prev.documentId !== next.documentId || prev.url !== next.url) {
118
118
  return `${header}\n${next.lines.join('\n')}`;
119
119
  }
120
- const strip = (l) => l.replace(/^e\d+:\s*/, '');
120
+ const strip = (l) => l.replace(/^(\s*)e\d+:\s*/, '$1');
121
121
  // Count occurrences rather than testing membership: a page with three
122
122
  // identical "Remove" buttons must still report a change when one of them
123
123
  // goes, and a set-difference silently calls that "no changes".
@@ -230,10 +230,13 @@ if (expected !== null && reg.doc !== expected) {
230
230
  }
231
231
  const el = reg.map.get(ref);
232
232
  if (!el) return { status: 'unknown-ref', documentId: reg.doc };
233
- if (!document.contains(el)) return { status: 'detached', documentId: reg.doc };
234
- const marked = document.querySelectorAll('[data-craftdriver-ref="' + ref + '"]');
235
- if (marked.length !== 1 || marked[0] !== el) {
236
- return { status: 'ambiguous', documentId: reg.doc, count: marked.length };
233
+ if (!el.isConnected || el.ownerDocument !== document) {
234
+ return { status: 'detached', documentId: reg.doc };
235
+ }
236
+ // The reverse map is the exact identity index. A mismatch is only possible for a
237
+ // corrupt/legacy registry; marker attributes deliberately do not participate.
238
+ if (reg.reverse && reg.reverse.get(el) !== ref) {
239
+ return { status: 'ambiguous', documentId: reg.doc };
237
240
  }
238
241
  return { status: 'ok', documentId: reg.doc };
239
242
  `;
@@ -243,7 +246,7 @@ return { status: 'ok', documentId: reg.doc };
243
246
  *
244
247
  * Strategy:
245
248
  * 1. Get or create the per-document ref registry.
246
- * 2. Walk a curated set of selectors (interactive + structural).
249
+ * 2. Walk the composed tree, entering open shadow roots and flattened slots.
247
250
  * 3. Skip nodes outside the viewport-ish bounds and zero-sized nodes.
248
251
  * 4. Reuse each node's existing ref, or issue the next unused one.
249
252
  * 5. Cap output at MAX_NODES so the snapshot stays bounded regardless
@@ -262,9 +265,18 @@ function newDocId(epoch) {
262
265
  function registry() {
263
266
  let reg = window.__craftdriverRefs;
264
267
  if (!reg || !reg.map) {
265
- reg = { doc: newDocId(1), epoch: 1, next: 1, issued: 0, map: new Map() };
268
+ reg = {
269
+ doc: newDocId(1), epoch: 1, next: 1, issued: 0,
270
+ map: new Map(), reverse: new WeakMap()
271
+ };
266
272
  window.__craftdriverRefs = reg;
267
273
  }
274
+ if (!reg.reverse) {
275
+ reg.reverse = new WeakMap();
276
+ reg.map.forEach(function (el, ref) {
277
+ if (el) reg.reverse.set(el, ref);
278
+ });
279
+ }
268
280
  // Never reissue a number the session has already handed out. A fresh
269
281
  // document starts its counter above the session high-water mark, so a
270
282
  // ref captured before a navigation can never match a new element.
@@ -278,24 +290,26 @@ function registry() {
278
290
  // re-key on every single snapshot — invalidating refs the instant they
279
291
  // were handed out.
280
292
  if (reg.issued >= MAX_REFS) {
281
- const marked = document.querySelectorAll('[data-craftdriver-ref]');
282
- for (let i = 0; i < marked.length; i++) marked[i].removeAttribute('data-craftdriver-ref');
293
+ reg.map.forEach(function (el) {
294
+ if (el && el.removeAttribute) el.removeAttribute('data-craftdriver-ref');
295
+ });
283
296
  reg.epoch += 1;
284
297
  reg.doc = newDocId(reg.epoch);
285
298
  reg.issued = 0;
286
299
  reg.map = new Map();
300
+ reg.reverse = new WeakMap();
287
301
  }
288
302
  return reg;
289
303
  }
290
304
  function refFor(reg, el) {
291
- const existing = el.getAttribute('data-craftdriver-ref');
292
- // Trust the attribute only when the registry agrees it names this node;
293
- // that rejects authored markup and cloneNode duplicates.
305
+ const existing = reg.reverse.get(el);
294
306
  if (existing && reg.map.get(existing) === el) return existing;
295
307
  const ref = 'e' + reg.next;
296
308
  reg.next += 1;
297
309
  reg.issued += 1;
298
310
  reg.map.set(ref, el);
311
+ reg.reverse.set(el, ref);
312
+ // Diagnostic only. Exact ref resolution never queries this attribute.
299
313
  el.setAttribute('data-craftdriver-ref', ref);
300
314
  return ref;
301
315
  }
@@ -323,22 +337,21 @@ const reg = registry();
323
337
  const sel = 'a,button,input,select,textarea,h1,h2,h3,h4,h5,h6,[role],nav,main,header,footer,form,img,label';
324
338
  const out = [];
325
339
  const refs = [];
326
- const nodes = document.querySelectorAll(sel);
327
- for (let i = 0; i < nodes.length && out.length < MAX_NODES; i++) {
328
- const el = nodes[i];
329
- if (!visible(el)) continue;
340
+ const seen = new WeakSet();
341
+ function emit(el, depth) {
342
+ if (out.length >= MAX_NODES || !visible(el)) return;
330
343
  // A <header>/<footer> inside sectioning content is not a landmark, and
331
344
  // listing it as a bare tag would be pure noise. Everything else keeps a
332
345
  // line even without an ARIA role, so controls stay addressable by ref.
333
346
  const tag = el.tagName.toLowerCase();
334
- if (!ariaRole(el) && (tag === 'header' || tag === 'footer')) continue;
347
+ if (!ariaRole(el) && (tag === 'header' || tag === 'footer')) return;
335
348
  const role = displayRole(el);
336
349
  let name = accName(el);
337
350
  if (name.length > MAX_NAME) name = name.slice(0, MAX_NAME - 1) + '…';
338
351
  const hint = locatorHint(el);
339
352
  const ref = refFor(reg, el);
340
353
  refs.push(ref);
341
- let line = ref + ': ' + role;
354
+ let line = ' '.repeat(depth) + ref + ': ' + role;
342
355
  if (name) line += ' "' + name + '"';
343
356
  if (hint) line += ' ' + hint;
344
357
  // Annotate disabled/checked state, agents need it.
@@ -346,6 +359,34 @@ for (let i = 0; i < nodes.length && out.length < MAX_NODES; i++) {
346
359
  if (el.checked) line += ' (checked)';
347
360
  out.push(line);
348
361
  }
362
+ function visitContainer(container, depth) {
363
+ const children = container && container.children ? Array.from(container.children) : [];
364
+ for (let i = 0; i < children.length && out.length < MAX_NODES; i++) {
365
+ visitElement(children[i], depth);
366
+ }
367
+ }
368
+ function visitElement(el, depth) {
369
+ if (!el || seen.has(el) || out.length >= MAX_NODES) return;
370
+ seen.add(el);
371
+ const openRoot = el.shadowRoot || null;
372
+ if (el.matches(sel) || openRoot) emit(el, depth);
373
+ if (openRoot) {
374
+ if (out.length < MAX_NODES) out.push(' '.repeat(depth + 1) + '#shadow-root (open)');
375
+ visitContainer(openRoot, depth + 2);
376
+ return;
377
+ }
378
+ if (el.tagName === 'SLOT') {
379
+ const assigned = el.assignedElements ? el.assignedElements({ flatten: true }) : [];
380
+ if (assigned.length) {
381
+ for (let i = 0; i < assigned.length && out.length < MAX_NODES; i++) {
382
+ visitElement(assigned[i], depth);
383
+ }
384
+ return;
385
+ }
386
+ }
387
+ visitContainer(el, depth);
388
+ }
389
+ visitContainer(document, 0);
349
390
  return { lines: out, refs: refs, documentId: reg.doc, nextRef: reg.next };
350
391
  `;
351
392
  }
@@ -1 +1 @@
1
- {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/cli/snapshot.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/cli/snapshot.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export { type RemoteWebDriverOptions, type RemoteAuth } from './lib/remote.js';
4
4
  export { Key } from './lib/keys.js';
5
5
  export { By } from './lib/by.js';
6
6
  export { Locator } from './lib/locator.js';
7
+ export { ShadowRootLocator } from './lib/shadowRootLocator.js';
7
8
  export { Frame } from './lib/frame.js';
8
9
  export { Page } from './lib/page.js';
9
10
  export { BrowserContext, type ClearCookiesFilter, type ContextStorageStateOptions, type BrowserContextConfig, type BrowserContextHooks, type InitScriptHandle, type RoutePattern, } from './lib/browserContext.js';
@@ -21,5 +22,5 @@ export { type ElectronMock, type ElectronMockCall } from './lib/electronMock.js'
21
22
  export { ElectronMainLogMonitor, type ElectronMainLog, type ElectronMainLogLevel, type ElectronMainLogHandler, } from './lib/electronMainLogs.js';
22
23
  export { Clock, type ClockTime, type ClockInstallOptions, } from './lib/clock.js';
23
24
  export { compareScreenshots, VisualMismatchError, type ScreenshotCompareOptions, type ExpectScreenshotOptions, type VisualScreenshotOptions, type VisualComparisonResult, type ScreenshotMatchResult, } from './lib/visual/index.js';
24
- export { A11y, A11yError, type A11yOptions, type A11yResult, type A11yViolation, type A11yViolationNode, type A11yImpact, } from './lib/a11y.js';
25
+ export { A11y, A11yError, type A11yOptions, type A11yResult, type A11yViolation, type A11yViolationNode, type A11yImpact, type A11yShadowSelector, type A11yTarget, } from './lib/a11y.js';
25
26
  //# sourceMappingURL=index.d.ts.map