Create an accessibility tree from the Document Object Model (DOM).
Closely modelled after:
// Create tree instance
const dom = document;
const accessibilityTree = new AccessibilityTree(dom);
// Build accessibility tree
accessibilityTree.build();
// Serialize accessibility tree
const treeStr = accessibilityTree.toString({
collapseEmptyProperties: true
});
const treeRoot = accessibilityTree.toObject();
// Find accessibility nodes in the tree
const bannerNodes = accessibilityTree.findByRole("banner");
const allAboutPastaNodes = accessibilityTree.findByName("All about Pasta");
// Update accessibility tree to reflect latest DOM state
accessibilityTree.build();
// ...type AccessibilityNode = {
children: AccessibilityNode[];
name: string;
properties: Record<string, unknown>;
role: string;
source: Element;
states: Record<string, boolean | undefined>;
description?: string;
value?: string;
};// Use a custom 'source' property
let i = 0;
accessibilityTree.toString({
sourceStringCb: element => `${element.tagName.toUpperCase()}-${i++}`
});The role of accessibility tree root nodes is
RootWebArea, which resembles Google Chrome's implementation.
<script src="https://cdn.jsdelivr.net/gh/webfuse-com/accessibility-tree@main/dist/api.browser.js"></script>// From string:
const dom = new DOMParser().parseFromString("<!DOCTYPE html><html>...</html>", "text/html");npm install webfuse-com/accessibility-treeInstall jsdom to use the library with Node.js:
npm install jsdom
import { AccessibilityTree, parseDOM } from "@webfuse-com/accessibility-tree";// From string:
const dom = await parseDOM("<!DOCTYPE html><html>...</html>");<html lang="en">
<head><title>Pasta Heaven</title></head>
<body>
<header>
<h1>Order a Pasta Dish</h1>
<nav aria-label="Main"><a href="#x">About Our Restaurant</a></nav>
</header>
<main>
<section aria-labelledby="t">
<h2 id="t">Place Your Order</h2>
<img src="p.jpg" alt="Bowl of pasta">
<span aria-hidden="true">No. 192128</span>
<form aria-describedby="hint">
<p id="hint">Pick your pasta dish:</p>
<label for="kind">Type</label>
<input id="kind" type="text" value="Penne" required>
<input type="range" min="0" max="10" value="7" aria-label="Servings">
<label>
<input type="checkbox" checked>
Spicy
</label>
<button aria-pressed="true" aria-controls="out">Save</button>
</form>
</section>
</main>
<footer aria-label="Site footer">© 2025 | Pasta Heaven</footer>
</body>
</html>{
"children": [
{
"children": [
{
"name": "Order a Pasta Dish",
"properties": {
"level": 1
},
"role": "heading",
"source": "html > body > header > h1"
},
{
"children": [
{
"name": "About Our Restaurant",
"role": "link",
"source": "html > body > header > nav > a"
}
],
"name": "Main",
"role": "navigation",
"source": "html > body > header > nav"
}
],
"role": "banner",
"source": "html > body > header"
},
{
"children": [
{
"children": [
{
"name": "Place Your Order",
"properties": {
"level": 2
},
"role": "heading",
"source": "#t"
},
{
"name": "Bowl of pasta",
"role": "img",
"source": "html > body > main > section > img"
},
{
"children": [
{
"name": "Pick your pasta dish:",
"role": "paragraph",
"source": "#hint"
},
{
"name": "Type",
"role": "generic",
"source": "html > body > main > section > form > label:nth-of-type(1)"
},
{
"name": "Type",
"properties": {
"required": true
},
"role": "textbox",
"source": "#kind",
"value": "Penne"
},
{
"name": "Servings",
"properties": {
"valuemin": 0,
"valuemax": 10,
"valuenow": 7
},
"role": "slider",
"source": "html > body > main > section > form > input:nth-of-type(2)",
"value": "7"
},
{
"children": [
{
"name": "Spicy",
"role": "checkbox",
"source": "html > body > main > section > form > label:nth-of-type(2) > input",
"states": {
"checked": true
}
}
],
"name": "Spicy",
"role": "generic",
"source": "html > body > main > section > form > label:nth-of-type(2)"
},
{
"name": "Save",
"properties": {
"controls": [
"out"
]
},
"role": "button",
"source": "html > body > main > section > form > button",
"states": {
"pressed": true
}
}
],
"role": "generic",
"source": "html > body > main > section > form",
"description": "Pick your pasta dish:"
}
],
"name": "Place Your Order",
"role": "region",
"source": "html > body > main > section"
}
],
"role": "main",
"source": "html > body > main"
},
{
"name": "Site footer",
"role": "contentinfo",
"source": "html > body > footer"
}
],
"name": "Pasta Heaven",
"role": "RootWebArea",
"source": "html"
}