Accessibility Tree & API Inspection
Permalink to "Accessibility Tree & API Inspection"Every screen reader announcement starts as markup, becomes a node in the browser’s accessibility tree, is mapped to a platform accessibility API and is finally interpreted by the screen reader. When an announcement is wrong — “blank”, the wrong header, a missing “expanded” — the fault lies at one of those layers. Teams that can only test by listening to a screen reader end up guessing: they add aria-labels, wrap things in role="presentation", change elements, and hope. Teams that can read the accessibility tree find causes in minutes.
This topic covers the inspection tools and the tests that build on them, applied to data grids and the controls around them. The users affected are, ultimately, all assistive technology users, because faster diagnosis means fewer regressions and quicker fixes. The failure this topic prevents is accessibility work driven by trial and error instead of evidence — slow, expensive, and prone to creating new problems while fixing old ones.
This topic belongs to testing & auditing accessible data interfaces.
WCAG criteria in scope
Permalink to "WCAG criteria in scope"| Criterion | Level | What inspection verifies |
|---|---|---|
| 1.3.1 Info and Relationships | A | Roles, headers and relationships in the tree |
| 2.1.1 Keyboard | A | Focusable elements and tab stops |
| 2.4.3 Focus Order | A | Tab order overlays |
| 2.5.3 Label in Name | A | Visible text contained in computed names |
| 4.1.2 Name, Role, Value | A | Computed names, roles and states |
| 4.1.3 Status Messages | AA | Live region nodes and their content |
Prerequisites
Permalink to "Prerequisites"- Familiarity with the patterns you are inspecting — composite widget roles & states and semantic HTML table construction.
- Basic screen reader use, from screen reader smoke testing.
- A test runner (Playwright) for snapshots and state-by-state checks.
ARIA & HTML spec reference
Permalink to "ARIA & HTML spec reference"| Concept | Where to see it | Why it matters for grids |
|---|---|---|
| Computed role | DevTools Accessibility pane | grid vs table decides reader mode |
| Computed name and source | DevTools name computation | Empty or duplicated cell names |
| Ignored nodes | DevTools, Firefox inspector | Content hidden by aria-hidden or presentation |
States (selected, expanded, sort) |
Both inspectors, ARIA snapshots | Missing or misplaced states |
Relations (labelledby, controls) |
Firefox inspector | Popovers, headers and descriptions |
| Platform patterns (UIA Table, AX headers) | Platform inspectors | Reader-specific header issues |
Step-by-step implementation
Permalink to "Step-by-step implementation"Step 1 — Reproduce and select (SC 4.1.2)
Permalink to "Step 1 — Reproduce and select (SC 4.1.2)"Reproduce the announcement, then select the same node in DevTools. See inspecting the accessibility tree in Chrome DevTools.
Accessibility pane → Computed properties → Name: "" (from content: aria-hidden child)
Step 2 — Compare with the pattern
Permalink to "Step 2 — Compare with the pattern"Check the node against the pattern’s requirements (role, name, states, position).
Step 3 — Cross-check in Firefox
Permalink to "Step 3 — Cross-check in Firefox"See the Firefox accessibility inspector for data grids.
Relations → controller for: dialog "Filter Amount"
Step 4 — FastPass per state (SC 2.1.1, 2.4.3)
Permalink to "Step 4 — FastPass per state (SC 2.1.1, 2.4.3)"See Accessibility Insights FastPass on data pages.
expect(await page.evaluate(() => [...document.querySelectorAll('[role="grid"] *')].filter(e => e.tabIndex === 0).length)).toBe(1);
Step 5 — Lock in with snapshots (SC 1.3.1)
Permalink to "Step 5 — Lock in with snapshots (SC 1.3.1)"See ARIA snapshot testing with Playwright.
await expect(page.getByRole('grid', { name: 'Invoices' })).toMatchAriaSnapshot(`- grid "Invoices"`);
Step 6 — Platform APIs for stubborn cases
Permalink to "Step 6 — Platform APIs for stubborn cases"See reading platform accessibility APIs for grids.
TableItemPattern.ColumnHeaderItems = [] ← why Narrator reads no headers
Keyboard interaction contract
Permalink to "Keyboard interaction contract"Inspection is driven by the same keys users press; reproduce issues by keyboard, not by clicking:
| Key | Inspect after pressing | Typical finding |
|---|---|---|
| Tab | Which node has focus; is it the grid’s single tab stop? | Every cell focusable |
| Arrows | Focused cell’s name and position | Empty names; wrong indices |
| Enter on a header | aria-sort on columnheader |
State on the inner button instead |
| Enter on an expandable row | aria-expanded and new rows |
State not updated |
| Shift+F10 | Menu role and items | Menu without role or names |
Screen reader compatibility matrix
Permalink to "Screen reader compatibility matrix"Inspection explains differences between readers:
| Symptom | Likely layer | Tool |
|---|---|---|
| Works in NVDA+Chrome, not NVDA+Firefox | Browser mapping | Firefox inspector |
| Works in NVDA, not Narrator | Platform patterns | Accessibility Insights for Windows |
| Works in Chrome, not Safari + VoiceOver | AX mapping | macOS Accessibility Inspector |
| Wrong in every reader | Markup | Chrome DevTools |
| Right in the tree, wrong in one reader only | Reader logic | Speech log and vendor report |
Edge cases & failure modes
Permalink to "Edge cases & failure modes"1. Fixing names with labels that hide visible text
Permalink to "1. Fixing names with labels that hide visible text"Diagnosis: aria-label added until DevTools looks right. Fix: let visible text name controls; check SC 2.5.3.
2. Snapshots updated without review
Permalink to "2. Snapshots updated without review"Diagnosis: regressions accepted as new baselines. Fix: review diffs like code.
3. Tools run on empty states
Permalink to "3. Tools run on empty states"Diagnosis: FastPass before data loads. Fix: stable, loaded states.
4. Platform debugging first
Permalink to "4. Platform debugging first"Diagnosis: hours in Inspect.exe on a markup bug. Fix: top-down diagnosis.
5. Missing versions in reports
Permalink to "5. Missing versions in reports"Diagnosis: “doesn’t work in JAWS”. Fix: reader, browser, OS versions and steps.
Inspecting the accessibility tree in Chrome DevTools
Permalink to "Inspecting the accessibility tree in Chrome DevTools"Computed roles, names and name sources, ignored nodes and the full-page tree — the first stop for any announcement bug. See inspecting the accessibility tree in Chrome DevTools.
Ignored: aria-hidden is true
Firefox accessibility inspector for data grids
Permalink to "Firefox accessibility inspector for data grids"Relations, states, tabbing order overlays, built-in checks and colour vision simulation, in the browser NVDA users often prefer. See the Firefox accessibility inspector for data grids.
Show tabbing order → 480 stops in the grid
Accessibility Insights FastPass on data pages
Permalink to "Accessibility Insights FastPass on data pages"Five-minute automated checks plus Tab stops, run on loaded, filtered, editing and dialog states. See Accessibility Insights FastPass on data pages.
new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa', 'wcag22aa']).analyze()
ARIA snapshot testing with Playwright
Permalink to "ARIA snapshot testing with Playwright"Readable YAML of a region’s roles, names and states that fails when structure changes. See ARIA snapshot testing with Playwright.
- grid "Invoices":
- row: [columnheader "Invoice", columnheader "Amount"]
Reading platform accessibility APIs for grids
Permalink to "Reading platform accessibility APIs for grids"UIA, IA2, AX and ATK inspectors for issues that differ between readers or browsers, with evidence for upstream reports. See reading platform accessibility APIs for grids.
AXSortDirection: AXDescendingSortDirection
Cross-cutting concerns
Permalink to "Cross-cutting concerns"Evidence in bug reports. A screenshot of the accessibility pane is often the most useful attachment a bug report can have; it shows exactly what was exposed.
Regression tests from fixes. Every inspection that leads to a fix should leave behind a test — an ARIA snapshot, a role query or an attribute assertion — so the bug cannot return.
Performance. Large trees slow screen readers. While inspecting, note node counts for grids; see measuring accessibility tree cost.
Team skills. Inspection is learnable in an afternoon. Teams that train every frontend developer on the DevTools accessibility pane fix issues faster and argue about ARIA less.
Worked example: a week of guessing, an hour of inspection
Permalink to "Worked example: a week of guessing, an hour of inspection"A support grid’s Status column was announced as “blank” by NVDA. Over a week, three developers tried fixes: an aria-label on the cell (which broke the visible text match), role="presentation" on the badge (which hid it), and a visually hidden duplicate (which caused double announcements in VoiceOver). An accessibility specialist then spent an hour with the DevTools accessibility pane: the badge text sat inside an aria-hidden wrapper added to suppress a tooltip. Removing the wrapper and the tooltip duplicate fixed every reader. The team added an ARIA snapshot for the row and a one-page internal guide to the accessibility pane; similar bugs since have taken minutes.
Who is affected, and how
Permalink to "Who is affected, and how"| Who | How inspection helps |
|---|---|
| Screen reader users | Bugs fixed at the cause, without side effects |
| Developers | Less guessing; reproducible evidence |
| QA and auditors | Precise reports with tree evidence |
| Library maintainers | Actionable upstream reports |
| Product teams | Fewer regressions thanks to snapshot tests |
Common mistakes
Permalink to "Common mistakes"- Testing only by ear. Listening to a screen reader shows symptoms; inspecting the tree shows causes.
- Treating the tree as the output. The tree shows what is exposed, not what readers say; confirm fixes with a reader.
- Inspecting the default state only. Many bugs appear only in focus, selection, expansion or dialog states.
- No regression guard. A fix without a test returns at the next refactor.
- Skipping Firefox. NVDA users often prefer Firefox; mapping differences are real.
Building team skills
Permalink to "Building team skills"A short internal session covers most of what developers need: open the Accessibility pane, read role, name and states, find the name source, spot ignored nodes, and toggle the full-page tree. Follow it with a practice bug — a cell announced as “blank” — and let developers find the cause. Add the Firefox tabbing order overlay and FastPass to the same session. Teams that do this report fewer speculative ARIA changes and faster fixes, and accessibility reviews shift from “try this” to “here is why”.
Measuring the effect
Permalink to "Measuring the effect"Track two things before and after introducing inspection practices: the median time from accessibility bug report to fix, and the number of reopened accessibility bugs (fixes that did not work or caused new problems). Both usually fall noticeably once teams diagnose with the tree and leave snapshot tests behind.
Design system integration
Permalink to "Design system integration"Document the expected accessibility tree for each component state (as ARIA snapshot templates), include them in component tests, and publish them in the component docs. When a product reports a bug, compare its tree with the reference first. Keep a shared log of platform-level findings and workarounds with links to upstream issues.
A reference session for new team members
Permalink to "A reference session for new team members"When onboarding developers to accessibility work on data UIs, one hour covers the essentials. Open any grid page. In Chrome, toggle the full-page accessibility tree and find the grid; read a header cell, a body cell and an icon button, noting role, name and name source. Break something on purpose — add aria-hidden to a cell’s content — and watch the name disappear. In Firefox, show the tabbing order and count the stops. Run FastPass on the same page. Finally, write a three-line ARIA snapshot for the header row. By the end, each developer has seen every layer of the stack and owns a regression test.
Testing checklist
Permalink to "Testing checklist"Automated
Permalink to "Automated"Manual
Permalink to "Manual"Reporting
Permalink to "Reporting"FAQ
Permalink to "FAQ"Do developers need screen readers if they can read the tree?
Yes. The tree shows what is exposed; readers show what users experience. Use both.
Which tool should a team learn first?
The Chrome DevTools accessibility pane. It solves most issues.
Are ARIA snapshots better than axe?
They check different things. Snapshots verify structure you expect; axe checks rules you might not think of.
How do I convince a browser vendor a bug is theirs?
Provide a minimal HTML reproduction, the expected mapping from the AAM spec and the platform inspector output showing the difference.
Can inspection find live region problems?
It shows live region nodes and their content but not whether announcements fired; use speech logs for timing.
Should QA include inspection in test plans?
For complex widgets, yes — attaching tree screenshots to failed test cases speeds up fixes considerably.
How often do platform-level bugs occur?
Rarely compared with markup bugs, but they cluster around complex widgets like grids and treegrids.
Is there a single view of all layers?
No single tool shows every layer; that is why the top-down sequence matters.
How do we keep inspection knowledge from living in one person's head?
Write short internal runbooks with screenshots for each tool, link them from your bug template, and rotate who leads accessibility investigations so several people build the skill.
Should product managers see tree evidence?
A screenshot of an empty name next to the visible text is often what makes the cost of a bug obvious to non-specialists. Include it in tickets.
Which single habit makes the biggest difference?
Opening the accessibility pane before changing any ARIA. It turns every fix into a diagnosis first.
Related
Permalink to "Related"- Screen reader smoke testing — the output layer
- Assistive technology behaviour differences — known differences
- Accessibility testing recipes — tests built on inspection
- Automated accessibility testing pipelines — running checks in CI
- Accessibility governance for data products — turning findings into process