webdriverio
Version:
Next-gen browser and mobile automation test framework for Node.js
62 lines (61 loc) • 1.69 kB
JavaScript
// src/scripts/findByRole.ts
var ACCESSIBILITY_API_MISSING = "__wdio_a11y_missing__";
function findByRole(role, name, at, root) {
const a11y = window.__wdioA11y;
if (!a11y) {
return "__wdio_a11y_missing__";
}
const normalize = (value) => value === "img" ? "image" : value;
const wanted = normalize(role);
const rendered = (el) => {
let current = el;
while (current?.parentElement) {
if (current.parentElement.shadowRoot && !current.assignedSlot) {
return false;
}
current = current.parentElement;
}
return true;
};
const inAccessibilityTree = (el) => {
let current = el;
while (current) {
if (!rendered(current) || a11y.isInaccessible(current)) {
return false;
}
const rootNode = current.getRootNode();
current = rootNode.host ?? null;
}
return true;
};
const nameOf = (el) => {
const computed = a11y.computeAccessibleName(el);
if (computed || !(el.tagName === "INPUT" || el.tagName === "TEXTAREA")) {
return computed;
}
return (el.getAttribute("placeholder") || "").replace(/\s+/g, " ").trim();
};
const matches = [];
const visit = (scope) => {
for (const el of scope.querySelectorAll("*")) {
if (normalize(a11y.getRole(el)) === wanted && inAccessibilityTree(el) && (name === null || nameOf(el) === name)) {
matches.push(el);
}
if (el.shadowRoot) {
visit(el.shadowRoot);
}
}
};
visit(root || document);
if (at === null) {
return matches.length;
}
if (at === -1) {
return matches;
}
return matches[at] || null;
}
export {
ACCESSIBILITY_API_MISSING,
findByRole as default
};