@wdio/mcp 2.2.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/snapshot.js CHANGED
@@ -1,214 +1,408 @@
1
- // src/scripts/get-browser-accessibility-tree.ts
2
- function flattenAccessibilityTree(node, result = []) {
3
- if (!node) return result;
4
- if (node.role !== "WebArea" || node.name) {
5
- const entry = {
6
- role: node.role || "",
7
- name: node.name || "",
8
- value: node.value ?? "",
9
- description: node.description || "",
10
- disabled: node.disabled ? "true" : "",
11
- focused: node.focused ? "true" : "",
12
- selected: node.selected ? "true" : "",
13
- checked: node.checked === true ? "true" : node.checked === false ? "false" : node.checked === "mixed" ? "mixed" : "",
14
- expanded: node.expanded === true ? "true" : node.expanded === false ? "false" : "",
15
- pressed: node.pressed === true ? "true" : node.pressed === false ? "false" : node.pressed === "mixed" ? "mixed" : "",
16
- readonly: node.readonly ? "true" : "",
17
- required: node.required ? "true" : "",
18
- level: node.level ?? "",
19
- valuemin: node.valuemin ?? "",
20
- valuemax: node.valuemax ?? "",
21
- autocomplete: node.autocomplete || "",
22
- haspopup: node.haspopup || "",
23
- invalid: node.invalid ? "true" : "",
24
- modal: node.modal ? "true" : "",
25
- multiline: node.multiline ? "true" : "",
26
- multiselectable: node.multiselectable ? "true" : "",
27
- orientation: node.orientation || "",
28
- keyshortcuts: node.keyshortcuts || "",
29
- roledescription: node.roledescription || "",
30
- valuetext: node.valuetext || ""
31
- };
32
- result.push(entry);
33
- }
34
- if (node.children && Array.isArray(node.children)) {
35
- for (const child of node.children) {
36
- flattenAccessibilityTree(child, result);
37
- }
38
- }
39
- return result;
40
- }
41
- async function getBrowserAccessibilityTree(browser) {
42
- const puppeteer = await browser.getPuppeteer();
43
- const pages = await puppeteer.pages();
44
- if (pages.length === 0) {
45
- return [];
46
- }
47
- const page = pages[0];
48
- const snapshot = await page.accessibility.snapshot({
49
- interestingOnly: true
50
- });
51
- if (!snapshot) {
52
- return [];
53
- }
54
- return flattenAccessibilityTree(snapshot);
55
- }
56
-
57
1
  // src/scripts/get-interactable-browser-elements.ts
58
- var elementsScript = (elementType = "interactable") => (function() {
2
+ var elementsScript = (includeBounds) => (function() {
59
3
  const interactableSelectors = [
60
4
  "a[href]",
61
- // Links with href
62
5
  "button",
63
- // Buttons
64
6
  'input:not([type="hidden"])',
65
- // Input fields (except hidden)
66
7
  "select",
67
- // Select dropdowns
68
8
  "textarea",
69
- // Text areas
70
9
  '[role="button"]',
71
- // Elements with button role
72
10
  '[role="link"]',
73
- // Elements with link role
74
11
  '[role="checkbox"]',
75
- // Elements with checkbox role
76
12
  '[role="radio"]',
77
- // Elements with radio role
78
13
  '[role="tab"]',
79
- // Elements with tab role
80
14
  '[role="menuitem"]',
81
- // Elements with menuitem role
82
15
  '[role="combobox"]',
83
- // Elements with combobox role
84
16
  '[role="option"]',
85
- // Elements with option role
86
17
  '[role="switch"]',
87
- // Elements with switch role
88
18
  '[role="slider"]',
89
- // Elements with slider role
90
19
  '[role="textbox"]',
91
- // Elements with textbox role
92
20
  '[role="searchbox"]',
93
- // Elements with searchbox role
21
+ '[role="spinbutton"]',
94
22
  '[contenteditable="true"]',
95
- // Editable content
96
23
  '[tabindex]:not([tabindex="-1"])'
97
- // Elements with tabindex
98
- ];
99
- const visualSelectors = [
100
- "img",
101
- // Images
102
- "picture",
103
- // Picture elements
104
- "svg",
105
- // SVG graphics
106
- "video",
107
- // Video elements
108
- "canvas",
109
- // Canvas elements
110
- '[style*="background-image"]'
111
- // Elements with background images
112
- ];
24
+ ].join(",");
113
25
  function isVisible(element) {
114
26
  if (typeof element.checkVisibility === "function") {
115
- return element.checkVisibility({
116
- opacityProperty: true,
117
- visibilityProperty: true,
118
- contentVisibilityAuto: true
119
- });
27
+ return element.checkVisibility({ opacityProperty: true, visibilityProperty: true, contentVisibilityAuto: true });
120
28
  }
121
29
  const style = window.getComputedStyle(element);
122
30
  return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0" && element.offsetWidth > 0 && element.offsetHeight > 0;
123
31
  }
124
- function getCssSelector(element) {
125
- if (element.id) {
126
- return `#${CSS.escape(element.id)}`;
32
+ function getAccessibleName(el) {
33
+ const ariaLabel = el.getAttribute("aria-label");
34
+ if (ariaLabel) return ariaLabel.trim();
35
+ const labelledBy = el.getAttribute("aria-labelledby");
36
+ if (labelledBy) {
37
+ const texts = labelledBy.split(/\s+/).map((id) => document.getElementById(id)?.textContent?.trim() || "").filter(Boolean);
38
+ if (texts.length > 0) return texts.join(" ").slice(0, 100);
39
+ }
40
+ const tag = el.tagName.toLowerCase();
41
+ if (tag === "img" || tag === "input" && el.getAttribute("type") === "image") {
42
+ const alt = el.getAttribute("alt");
43
+ if (alt !== null) return alt.trim();
44
+ }
45
+ if (["input", "select", "textarea"].includes(tag)) {
46
+ const id = el.getAttribute("id");
47
+ if (id) {
48
+ const label = document.querySelector(`label[for="${CSS.escape(id)}"]`);
49
+ if (label) return label.textContent?.trim() || "";
50
+ }
51
+ const parentLabel = el.closest("label");
52
+ if (parentLabel) {
53
+ const clone = parentLabel.cloneNode(true);
54
+ clone.querySelectorAll("input,select,textarea").forEach((n) => n.remove());
55
+ const lt = clone.textContent?.trim();
56
+ if (lt) return lt;
57
+ }
58
+ }
59
+ const ph = el.getAttribute("placeholder");
60
+ if (ph) return ph.trim();
61
+ const title = el.getAttribute("title");
62
+ if (title) return title.trim();
63
+ return (el.textContent?.trim().replace(/\s+/g, " ") || "").slice(0, 100);
64
+ }
65
+ function getSelector(element) {
66
+ const tag = element.tagName.toLowerCase();
67
+ const text = element.textContent?.trim().replace(/\s+/g, " ");
68
+ if (text && text.length > 0 && text.length <= 50) {
69
+ const sameTagElements = document.querySelectorAll(tag);
70
+ let matchCount = 0;
71
+ sameTagElements.forEach((el) => {
72
+ if (el.textContent?.includes(text)) matchCount++;
73
+ });
74
+ if (matchCount === 1) return `${tag}*=${text}`;
75
+ }
76
+ const ariaLabel = element.getAttribute("aria-label");
77
+ if (ariaLabel && ariaLabel.length <= 80) return `aria/${ariaLabel}`;
78
+ const testId = element.getAttribute("data-testid");
79
+ if (testId) {
80
+ const sel = `[data-testid="${CSS.escape(testId)}"]`;
81
+ if (document.querySelectorAll(sel).length === 1) return sel;
82
+ }
83
+ if (element.id) return `#${CSS.escape(element.id)}`;
84
+ const nameAttr = element.getAttribute("name");
85
+ if (nameAttr) {
86
+ const sel = `${tag}[name="${CSS.escape(nameAttr)}"]`;
87
+ if (document.querySelectorAll(sel).length === 1) return sel;
127
88
  }
128
89
  if (element.className && typeof element.className === "string") {
129
90
  const classes = element.className.trim().split(/\s+/).filter(Boolean);
130
- if (classes.length > 0) {
131
- const classSelector = classes.slice(0, 2).map((c) => `.${CSS.escape(c)}`).join("");
132
- const tagWithClass = `${element.tagName.toLowerCase()}${classSelector}`;
133
- if (document.querySelectorAll(tagWithClass).length === 1) {
134
- return tagWithClass;
135
- }
91
+ for (const cls of classes) {
92
+ const sel = `${tag}.${CSS.escape(cls)}`;
93
+ if (document.querySelectorAll(sel).length === 1) return sel;
94
+ }
95
+ if (classes.length >= 2) {
96
+ const sel = `${tag}${classes.slice(0, 2).map((c) => `.${CSS.escape(c)}`).join("")}`;
97
+ if (document.querySelectorAll(sel).length === 1) return sel;
136
98
  }
137
99
  }
138
100
  let current = element;
139
101
  const path = [];
140
102
  while (current && current !== document.documentElement) {
141
- let selector = current.tagName.toLowerCase();
103
+ let seg = current.tagName.toLowerCase();
142
104
  if (current.id) {
143
- selector = `#${CSS.escape(current.id)}`;
144
- path.unshift(selector);
105
+ path.unshift(`#${CSS.escape(current.id)}`);
145
106
  break;
146
107
  }
147
108
  const parent = current.parentElement;
148
109
  if (parent) {
149
- const siblings = Array.from(parent.children).filter(
150
- (child) => child.tagName === current.tagName
151
- );
152
- if (siblings.length > 1) {
153
- const index = siblings.indexOf(current) + 1;
154
- selector += `:nth-child(${index})`;
155
- }
110
+ const siblings = Array.from(parent.children).filter((c) => c.tagName === current.tagName);
111
+ if (siblings.length > 1) seg += `:nth-of-type(${siblings.indexOf(current) + 1})`;
156
112
  }
157
- path.unshift(selector);
113
+ path.unshift(seg);
158
114
  current = current.parentElement;
159
- if (path.length >= 4) {
115
+ if (path.length >= 4) break;
116
+ }
117
+ return path.join(" > ");
118
+ }
119
+ const elements = [];
120
+ const seen = /* @__PURE__ */ new Set();
121
+ document.querySelectorAll(interactableSelectors).forEach((el) => {
122
+ if (seen.has(el)) return;
123
+ seen.add(el);
124
+ const htmlEl = el;
125
+ if (!isVisible(htmlEl)) return;
126
+ const inputEl = htmlEl;
127
+ const rect = htmlEl.getBoundingClientRect();
128
+ const isInViewport = rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
129
+ const entry = {
130
+ tagName: htmlEl.tagName.toLowerCase(),
131
+ name: getAccessibleName(htmlEl),
132
+ type: htmlEl.getAttribute("type") || "",
133
+ value: inputEl.value || "",
134
+ href: htmlEl.getAttribute("href") || "",
135
+ selector: getSelector(htmlEl),
136
+ isInViewport
137
+ };
138
+ if (includeBounds) {
139
+ entry.boundingBox = {
140
+ x: rect.x + window.scrollX,
141
+ y: rect.y + window.scrollY,
142
+ width: rect.width,
143
+ height: rect.height
144
+ };
145
+ }
146
+ elements.push(entry);
147
+ });
148
+ return elements;
149
+ })();
150
+ async function getInteractableBrowserElements(browser, options = {}) {
151
+ const { includeBounds = false } = options;
152
+ return browser.execute(elementsScript, includeBounds);
153
+ }
154
+
155
+ // src/scripts/get-browser-accessibility-tree.ts
156
+ var accessibilityTreeScript = () => (function() {
157
+ const INPUT_TYPE_ROLES = {
158
+ text: "textbox",
159
+ search: "searchbox",
160
+ email: "textbox",
161
+ url: "textbox",
162
+ tel: "textbox",
163
+ password: "textbox",
164
+ number: "spinbutton",
165
+ checkbox: "checkbox",
166
+ radio: "radio",
167
+ range: "slider",
168
+ submit: "button",
169
+ reset: "button",
170
+ image: "button",
171
+ file: "button",
172
+ color: "button"
173
+ };
174
+ const LANDMARK_ROLES = /* @__PURE__ */ new Set([
175
+ "navigation",
176
+ "main",
177
+ "banner",
178
+ "contentinfo",
179
+ "complementary",
180
+ "form",
181
+ "dialog",
182
+ "region"
183
+ ]);
184
+ const CONTAINER_ROLES = /* @__PURE__ */ new Set([
185
+ "navigation",
186
+ "banner",
187
+ "contentinfo",
188
+ "complementary",
189
+ "main",
190
+ "form",
191
+ "region",
192
+ "group",
193
+ "list",
194
+ "listitem",
195
+ "table",
196
+ "row",
197
+ "rowgroup",
198
+ "generic"
199
+ ]);
200
+ function getRole(el) {
201
+ const explicit = el.getAttribute("role");
202
+ if (explicit) return explicit.split(" ")[0];
203
+ const tag = el.tagName.toLowerCase();
204
+ switch (tag) {
205
+ case "button":
206
+ return "button";
207
+ case "a":
208
+ return el.hasAttribute("href") ? "link" : null;
209
+ case "input": {
210
+ const type = (el.getAttribute("type") || "text").toLowerCase();
211
+ if (type === "hidden") return null;
212
+ return INPUT_TYPE_ROLES[type] || "textbox";
213
+ }
214
+ case "select":
215
+ return "combobox";
216
+ case "textarea":
217
+ return "textbox";
218
+ case "h1":
219
+ case "h2":
220
+ case "h3":
221
+ case "h4":
222
+ case "h5":
223
+ case "h6":
224
+ return "heading";
225
+ case "img":
226
+ return "img";
227
+ case "nav":
228
+ return "navigation";
229
+ case "main":
230
+ return "main";
231
+ case "header":
232
+ return !el.closest("article,aside,main,nav,section") ? "banner" : null;
233
+ case "footer":
234
+ return !el.closest("article,aside,main,nav,section") ? "contentinfo" : null;
235
+ case "aside":
236
+ return "complementary";
237
+ case "dialog":
238
+ return "dialog";
239
+ case "form":
240
+ return "form";
241
+ case "section":
242
+ return el.hasAttribute("aria-label") || el.hasAttribute("aria-labelledby") ? "region" : null;
243
+ case "summary":
244
+ return "button";
245
+ case "details":
246
+ return "group";
247
+ case "progress":
248
+ return "progressbar";
249
+ case "meter":
250
+ return "meter";
251
+ case "ul":
252
+ case "ol":
253
+ return "list";
254
+ case "li":
255
+ return "listitem";
256
+ case "table":
257
+ return "table";
258
+ }
259
+ if (el.contentEditable === "true") return "textbox";
260
+ if (el.hasAttribute("tabindex") && parseInt(el.getAttribute("tabindex") || "-1", 10) >= 0) return "generic";
261
+ return null;
262
+ }
263
+ function getAccessibleName(el, role) {
264
+ const ariaLabel = el.getAttribute("aria-label");
265
+ if (ariaLabel) return ariaLabel.trim();
266
+ const labelledBy = el.getAttribute("aria-labelledby");
267
+ if (labelledBy) {
268
+ const texts = labelledBy.split(/\s+/).map((id) => document.getElementById(id)?.textContent?.trim() || "").filter(Boolean);
269
+ if (texts.length > 0) return texts.join(" ").slice(0, 100);
270
+ }
271
+ const tag = el.tagName.toLowerCase();
272
+ if (tag === "img" || tag === "input" && el.getAttribute("type") === "image") {
273
+ const alt = el.getAttribute("alt");
274
+ if (alt !== null) return alt.trim();
275
+ }
276
+ if (["input", "select", "textarea"].includes(tag)) {
277
+ const id = el.getAttribute("id");
278
+ if (id) {
279
+ const label = document.querySelector(`label[for="${CSS.escape(id)}"]`);
280
+ if (label) return label.textContent?.trim() || "";
281
+ }
282
+ const parentLabel = el.closest("label");
283
+ if (parentLabel) {
284
+ const clone = parentLabel.cloneNode(true);
285
+ clone.querySelectorAll("input,select,textarea").forEach((n) => n.remove());
286
+ const lt = clone.textContent?.trim();
287
+ if (lt) return lt;
288
+ }
289
+ }
290
+ const ph = el.getAttribute("placeholder");
291
+ if (ph) return ph.trim();
292
+ const title = el.getAttribute("title");
293
+ if (title) return title.trim();
294
+ if (role && CONTAINER_ROLES.has(role)) return "";
295
+ return (el.textContent?.trim().replace(/\s+/g, " ") || "").slice(0, 100);
296
+ }
297
+ function getSelector(element) {
298
+ const tag = element.tagName.toLowerCase();
299
+ const text = element.textContent?.trim().replace(/\s+/g, " ");
300
+ if (text && text.length > 0 && text.length <= 50) {
301
+ const sameTagElements = document.querySelectorAll(tag);
302
+ let matchCount = 0;
303
+ sameTagElements.forEach((el) => {
304
+ if (el.textContent?.includes(text)) matchCount++;
305
+ });
306
+ if (matchCount === 1) return `${tag}*=${text}`;
307
+ }
308
+ const ariaLabel = element.getAttribute("aria-label");
309
+ if (ariaLabel && ariaLabel.length <= 80) return `aria/${ariaLabel}`;
310
+ const testId = element.getAttribute("data-testid");
311
+ if (testId) {
312
+ const sel = `[data-testid="${CSS.escape(testId)}"]`;
313
+ if (document.querySelectorAll(sel).length === 1) return sel;
314
+ }
315
+ if (element.id) return `#${CSS.escape(element.id)}`;
316
+ const nameAttr = element.getAttribute("name");
317
+ if (nameAttr) {
318
+ const sel = `${tag}[name="${CSS.escape(nameAttr)}"]`;
319
+ if (document.querySelectorAll(sel).length === 1) return sel;
320
+ }
321
+ if (element.className && typeof element.className === "string") {
322
+ const classes = element.className.trim().split(/\s+/).filter(Boolean);
323
+ for (const cls of classes) {
324
+ const sel = `${tag}.${CSS.escape(cls)}`;
325
+ if (document.querySelectorAll(sel).length === 1) return sel;
326
+ }
327
+ if (classes.length >= 2) {
328
+ const sel = `${tag}${classes.slice(0, 2).map((c) => `.${CSS.escape(c)}`).join("")}`;
329
+ if (document.querySelectorAll(sel).length === 1) return sel;
330
+ }
331
+ }
332
+ let current = element;
333
+ const path = [];
334
+ while (current && current !== document.documentElement) {
335
+ let seg = current.tagName.toLowerCase();
336
+ if (current.id) {
337
+ path.unshift(`#${CSS.escape(current.id)}`);
160
338
  break;
161
339
  }
340
+ const parent = current.parentElement;
341
+ if (parent) {
342
+ const siblings = Array.from(parent.children).filter((c) => c.tagName === current.tagName);
343
+ if (siblings.length > 1) seg += `:nth-of-type(${siblings.indexOf(current) + 1})`;
344
+ }
345
+ path.unshift(seg);
346
+ current = current.parentElement;
347
+ if (path.length >= 4) break;
162
348
  }
163
349
  return path.join(" > ");
164
350
  }
165
- function getElements() {
166
- const selectors = [];
167
- if (elementType === "interactable" || elementType === "all") {
168
- selectors.push(...interactableSelectors);
351
+ function isVisible(el) {
352
+ if (typeof el.checkVisibility === "function") {
353
+ return el.checkVisibility({ opacityProperty: true, visibilityProperty: true, contentVisibilityAuto: true });
169
354
  }
170
- if (elementType === "visual" || elementType === "all") {
171
- selectors.push(...visualSelectors);
355
+ const style = window.getComputedStyle(el);
356
+ return style.display !== "none" && style.visibility !== "hidden" && style.opacity !== "0" && el.offsetWidth > 0 && el.offsetHeight > 0;
357
+ }
358
+ function getLevel(el) {
359
+ const m = el.tagName.toLowerCase().match(/^h([1-6])$/);
360
+ if (m) return parseInt(m[1], 10);
361
+ const ariaLevel = el.getAttribute("aria-level");
362
+ if (ariaLevel) return parseInt(ariaLevel, 10);
363
+ return void 0;
364
+ }
365
+ function getState(el) {
366
+ const inputEl = el;
367
+ const isCheckable = ["input", "menuitemcheckbox", "menuitemradio"].includes(el.tagName.toLowerCase()) || ["checkbox", "radio", "switch"].includes(el.getAttribute("role") || "");
368
+ return {
369
+ disabled: el.getAttribute("aria-disabled") === "true" || inputEl.disabled ? "true" : "",
370
+ checked: isCheckable && inputEl.checked ? "true" : el.getAttribute("aria-checked") || "",
371
+ expanded: el.getAttribute("aria-expanded") || "",
372
+ selected: el.getAttribute("aria-selected") || "",
373
+ pressed: el.getAttribute("aria-pressed") || "",
374
+ required: inputEl.required || el.getAttribute("aria-required") === "true" ? "true" : "",
375
+ readonly: inputEl.readOnly || el.getAttribute("aria-readonly") === "true" ? "true" : ""
376
+ };
377
+ }
378
+ const result = [];
379
+ function walk(el, depth = 0) {
380
+ if (depth > 200) return;
381
+ if (!isVisible(el)) return;
382
+ const role = getRole(el);
383
+ if (!role) {
384
+ for (const child of Array.from(el.children)) {
385
+ walk(child, depth + 1);
386
+ }
387
+ return;
172
388
  }
173
- const allElements = [];
174
- selectors.forEach((selector) => {
175
- const elements = document.querySelectorAll(selector);
176
- elements.forEach((element) => {
177
- if (!allElements.includes(element)) {
178
- allElements.push(element);
179
- }
180
- });
181
- });
182
- const elementInfos = allElements.filter((element) => isVisible(element) && !element.disabled).map((element) => {
183
- const el = element;
184
- const inputEl = element;
185
- const rect = el.getBoundingClientRect();
186
- const isInViewport = rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && rect.right <= (window.innerWidth || document.documentElement.clientWidth);
187
- const info = {
188
- tagName: el.tagName.toLowerCase(),
189
- type: el.getAttribute("type") || "",
190
- id: el.id || "",
191
- className: (typeof el.className === "string" ? el.className : "") || "",
192
- textContent: el.textContent?.trim() || "",
193
- value: inputEl.value || "",
194
- placeholder: inputEl.placeholder || "",
195
- href: el.getAttribute("href") || "",
196
- ariaLabel: el.getAttribute("aria-label") || "",
197
- role: el.getAttribute("role") || "",
198
- src: el.getAttribute("src") || "",
199
- alt: el.getAttribute("alt") || "",
200
- cssSelector: getCssSelector(el),
201
- isInViewport
202
- };
203
- return info;
204
- });
205
- return elementInfos;
389
+ const name = getAccessibleName(el, role);
390
+ const isLandmark = LANDMARK_ROLES.has(role);
391
+ const hasIdentity = !!(name || isLandmark);
392
+ const selector = hasIdentity ? getSelector(el) : "";
393
+ const node = { role, name, selector, level: getLevel(el) ?? "", ...getState(el) };
394
+ result.push(node);
395
+ for (const child of Array.from(el.children)) {
396
+ walk(child, depth + 1);
397
+ }
398
+ }
399
+ for (const child of Array.from(document.body.children)) {
400
+ walk(child, 0);
206
401
  }
207
- return getElements();
402
+ return result;
208
403
  })();
209
- async function getBrowserInteractableElements(browser, options = {}) {
210
- const { elementType = "interactable" } = options;
211
- return browser.execute(elementsScript, elementType);
404
+ async function getBrowserAccessibilityTree(browser) {
405
+ return browser.execute(accessibilityTreeScript);
212
406
  }
213
407
 
214
408
  // src/locators/constants.ts
@@ -465,7 +659,7 @@ function checkXPathUniqueness(doc, xpathExpr, targetNode) {
465
659
  }
466
660
  if (targetNode) {
467
661
  for (let i = 0; i < nodes.length; i++) {
468
- if (nodes[i].isSameNode(targetNode) || isSameElement(nodes[i], targetNode)) {
662
+ if (nodes[i] === targetNode || isSameElement(nodes[i], targetNode)) {
469
663
  return {
470
664
  isUnique: false,
471
665
  index: i + 1,
@@ -1172,7 +1366,7 @@ async function getMobileVisibleElements(browser, platform, options = {}) {
1172
1366
  }
1173
1367
  export {
1174
1368
  getBrowserAccessibilityTree,
1175
- getBrowserInteractableElements,
1369
+ getInteractableBrowserElements,
1176
1370
  getMobileVisibleElements
1177
1371
  };
1178
1372
  //# sourceMappingURL=snapshot.js.map