Every web page has a hidden structure that assistive technologies depend on: the accessibility tree. Browsers build it from your HTML and ARIA attributes, and screen readers, switch devices, and voice control software use it to let people navigate and interact with your content. When a deployment silently breaks that tree — removing a landmark, stripping a button label, or collapsing a navigation region — users who rely on assistive technology hit a wall. Accessibility tree monitoring catches those regressions automatically, before they reach production.

What Is the Accessibility Tree?

The accessibility tree is a parallel representation of the DOM that browsers expose to assistive technologies through platform accessibility APIs (MSAA/UIA on Windows, AXAccessibility on macOS, AT-SPI on Linux). Each node in the tree carries a role (such asbutton, navigation, or heading), an accessible name (computed from text content, aria-label, or aria-labelledby), an optional description, and a set of states and properties like expanded, checked, or disabled.

Standard automated accessibility scanners like Axe or Lighthouse evaluate individual rules — is there alt text, is the contrast ratio sufficient, are ARIA roles valid? These tools are essential, but they operate on a snapshot of individual rule violations. They do not tell you whether the overall structure of the accessibility tree has changed between deployments. That is where tree monitoring comes in.

Why Tree Diffing Matters

Consider a common scenario: a developer refactors a header component, switching from a semantic <nav> element to a generic <div> with the same visual styles. Axe will not flag this as a violation — the page still has valid HTML. But the accessibility tree has lost its navigation landmark, and screen reader users who relied on landmark navigation to jump to the main menu can no longer find it.

Tree diffing solves this by comparing the full accessibility tree of a page against a known-good baseline. When the structure changes, each difference is classified by severity:

  • Critical: A landmark or interactive element was removed, or a button or link lost its accessible name. These changes break assistive technology workflows immediately.
  • Warning: State properties changed (such as an element becoming disabled or expandedchanging), or a role changed on a non-landmark element. These deserve investigation.
  • Info: New nodes were added to the tree. These are typically harmless — new content or interactive elements — but should be reviewed for proper labelling.

How Accessibility Tree Capture Works

Modern browser automation tools like Playwright provide direct access to the accessibility tree through APIs like page.accessibility.snapshot(). A capture service launches a headless browser, navigates to the target URL, waits for the page to settle (allowing JavaScript to render dynamic content), and then extracts the full accessibility tree as a JSON structure.

Each captured node is normalised into a consistent format containing the role, name, description, state properties, and child nodes in document order. The resulting snapshot also records metadata such as the browser engine, viewport dimensions, and wait duration, so you can reproduce the exact conditions of the capture.

The Diff Algorithm

The tree diff engine walks both trees recursively, matching nodes by a composite key of role and name. This key-based matching means that if a button named “Submit” exists in both trees, the engine compares their properties in place. If the key disappears from one tree or appears in another, it is flagged as a removal or addition.

Within matched node pairs, the engine compares:

  • Role changes:Did the node’s role change? A navigation becoming a generic is critical.
  • Name changes: Did the accessible name change? A button losing its label is critical because assistive technology users cannot identify it.
  • State changes: Did any ARIA state or property change? These are tracked individually (for example, checked going from true to false).
  • Child changes: The engine recurses into child nodes, building a full change log down to the leaf level.

Severity Classification

Not all changes are equal. The diff engine uses role-based classification to determine severity automatically:

  • Landmarks (main, navigation, banner, contentinfo, complementary, search, form, dialog) are treated as critical infrastructure. Removing or changing the role of a landmark is always flagged as critical.
  • Interactive elements (button, link, textbox, checkbox, radio, combobox, tab, switch, slider) are essential for user interaction. Removing one or stripping its name is critical.
  • State changes and non-landmark role changes are classified as warnings, since they may or may not represent a regression depending on context.
  • Added nodes are classified as informational. New content is typically positive, but should be reviewed to ensure it has proper roles and labels.

Setting Up Continuous Monitoring

A practical tree monitoring workflow has four stages:

  1. Establish baselines. For each page you want to monitor, capture the accessibility tree and mark it as the approved baseline. This is your known-good state.
  2. Schedule regular scans. Run captures on a schedule — daily for critical pages, weekly for lower-traffic pages. Each scan compares the current tree against the baseline.
  3. Triage diffs. When changes are detected, review them in a dashboard that colour-codes changes by severity. Focus on critical and warning changes first.
  4. Approve or fix. If a change is intentional (for example, a redesigned navigation), approve the new snapshot as the baseline. If it is a regression, fix the code and re-scan.

What Tree Monitoring Catches That Scanners Miss

To illustrate the value, here are real-world regressions that tree monitoring detects but rule-based scanners typically do not:

  • A component library update replaces <button> elements with styled <div onClick> elements. The visual appearance is identical, but the accessibility tree loses all button roles.
  • A CMS content update removes a heading that screen reader users relied on for navigation. The heading was not required by any WCAG rule, but its removal breaks the document outline.
  • A third-party script injects an overlay that adds aria-hidden="true" to the main content area, effectively hiding the entire page from assistive technology.
  • A React key change causes a form to remount, losing the association between labels and inputs. The inputs still have id attributes, but the for attributes on the labels now point to stale IDs.

Integrating with Your CI/CD Pipeline

For teams that want to shift tree monitoring left, you can integrate accessibility tree captures into your continuous integration pipeline. After deploying to a preview environment, run a tree capture and diff it against the baseline for that page. If the diff contains critical regressions, fail the build or add a comment to the pull request with the change summary.

This approach works well with tools like Playwright, which can run in CI environments and provide the page.accessibility.snapshot() API. The captured tree is a lightweight JSON object — typically under 100KB even for complex pages — so storing baselines and diffs adds negligible overhead to your pipeline.

Getting Started

If you are new to accessibility tree monitoring, start with your most critical pages — the homepage, primary navigation flows, and any pages with complex interactive widgets (forms, data tables, modal dialogs). Capture baselines for each, set up weekly scans, and review the first round of diffs to calibrate your expectations. Most teams find a handful of surprises in their first scan — landmarks that were not as robust as assumed, labels that were computed from tooltip text rather than visible content, or state properties that were never properly managed.

The goal is not zero changes — it is awareness. Every change to the accessibility tree is a change to the experience of people using assistive technology. Tree monitoring makes those changes visible so your team can make informed decisions about what ships.