GUIDE / accessibility
How to Test ARIA Labels
Learn how to test ARIA labels: accessible names, aria-label vs aria-labelledby, roles, states, screen reader checks, and common ARIA mistakes.
Accessible names decide whether an icon button is announced as "Close dialog" or as a mysterious unlabeled control. Testing ARIA labels means verifying that controls and regions expose the right name and role to assistive technologies before users hit dead ends in forms, menus, and modals.
This guide shows how to test ARIA labels in practice: accessible name fundamentals, aria-label vs aria-labelledby, roles and states, DevTools inspection, screen reader validation, dynamic UI checks, test cases, and common mistakes. You will get tables, examples, and a workflow QA engineers can reuse on real product UIs.
What ARIA Labels Testing Actually Covers
ARIA labels testing is broader than hunting for the string aria-label in HTML. It covers the accessible name computation that screen readers and other AT use.
You are validating that interactive elements and important regions have names that are:
- Present
- Correct for the task
- Programmatically associated
- Updated when the UI state changes
- Compatible with the element role
ARIA stands for Accessible Rich Internet Applications. It can add missing semantics to custom widgets. It can also create serious bugs when misused. Testing must treat ARIA as behavior, not decoration.
If you need the larger journey process around keyboard and SR testing, pair this article with screen reader testing and the WCAG accessibility testing checklist.
Accessible Name Basics
The accessible name is what AT uses to describe an element. Sources can include:
- Visible text content inside a control (
<button>Save</button>) <label for="...">associated with a form controlaria-labelledbyreferencesaria-labelalton images used as controlstitlein some fallback cases (often fragile and incomplete)- Other naming patterns depending on role
Rough priority idea for many controls:
- Prefer native labeling with visible text
- Prefer
aria-labelledbywhen reusing on-screen text - Use
aria-labelwhen there is no suitable visible text - Do not rely on placeholder or title as the only name
Name vs description
- Name: primary identity ("Delete invoice")
- Description: extra help (
aria-describedbyfor hint or error text)
Both matter. A field can have a correct name and still fail users if the error description is not associated.
aria-label vs aria-labelledby
| Attribute | How it works | Best when | Risks |
|---|---|---|---|
aria-label | String name on the element | Icon only button, unnamed control | Can override visible text; translations need care; easy to drift from UI copy |
aria-labelledby | Name built from referenced element IDs | Visible heading/label already on screen | Broken if IDs missing or duplicated; order of IDs matters |
Examples
Icon button with aria-label:
<button type="button" aria-label="Close dialog">
<svg aria-hidden="true" focusable="false">...</svg>
</button>
Dialog titled with aria-labelledby:
<div role="dialog" aria-modal="true" aria-labelledby="invite-title">
<h2 id="invite-title">Invite teammate</h2>
...
</div>
Input with visible label (often no ARIA needed):
<label for="email">Email</label>
<input id="email" name="email" type="email" autocomplete="email" />
Testing question is not "is there ARIA?" The question is "is the accessible name correct?"
The First Rule of ARIA in Testing Language
Native HTML elements already expose roles and names when used correctly.
Prefer:
<button>over<div role="button"><a href>for navigation links- Real headings for section titles
- Associated
<label>for inputs
When you see ARIA on a native element, ask whether it is necessary or conflicting. Extra role and aria-label on a perfectly good button can override useful text or confuse AT.
How to Test ARIA Labels: Step by Step Workflow
Step 1: Inventory interactive elements on the page
List buttons, links, inputs, selects, checkboxes, radios, tabs, menu items, toggles, dialogs, and custom widgets. Include icon only controls and inline actions in tables.
Step 2: Inspect accessible name in DevTools
In Chromium DevTools:
- Select the element.
- Open the Accessibility pane.
- Read Computed Name and Role.
- Check states such as focusable, expanded, checked.
In Firefox, use the Accessibility Inspector to similar effect.
Document mismatches between visible purpose and computed name.
Step 3: Compare name to visible UI and task language
Good names are specific and purposeful:
| Control | Weak name | Better name |
|---|---|---|
| Trash icon in row | button | Delete order 1842 |
| Header X | button | Close settings dialog |
| Search field | edit | Search help articles |
| Heart icon | heart | Save course to favorites |
| Pagination chevron | next | Next page of results |
Context matters. "Delete" may be enough when the dialog title already says which object. "Button" is never enough.
Step 4: Validate with keyboard focus
A correct name on an element that cannot receive focus is still a functional accessibility failure. Confirm tab order reaches the control and activation works. See keyboard navigation testing.
Step 5: Validate with a screen reader
Use a realistic pair:
- NVDA + Chrome/Firefox
- VoiceOver + Safari
For each important control, confirm:
- Role announced as expected
- Name announced as expected
- State announced (expanded/collapsed, checked, selected, pressed)
- Description announced when relevant (errors, hints)
Step 6: Test dynamic updates
Change the UI and re-check names and states:
- Menu expands
- Tab selection changes
- Toggle switches
- Cart count updates
- Sort button changes sort direction
- Validation errors appear
- Async content replaces a skeleton
Stale ARIA is a frequent production bug.
Step 7: Run an automated assist
Use axe or similar to catch missing names and invalid aria-labelledby references. Automation is a partner, not the judge of meaningful wording. See automated accessibility testing with axe.
Accessible Name Testing for Common Widgets
Icon only buttons
Checks:
aria-labelor visually hidden text present- SVG marked
aria-hidden="true"when decorative - Tooltip not the only accessible name source
- Duplicate icons in a list include distinguishing context
Form controls
Checks:
- Visible label exists
- Programmatic association exists
aria-labeldoes not unnecessarily override visible label text in a conflicting way- Required state exposed if used
- Error linked with
aria-describedbyor equivalent - Placeholder is not the only label
Dialogs
Checks:
- Dialog has a name via
aria-labelledbyoraria-label - Focus moves inside on open
- Name is announced when the dialog opens
- Close button is named
Tabs
Checks:
- Tab role and selected state
- Tab name clear
- Tabpanel labeled by the tab when appropriate
- Keyboard arrow patterns work if you claim tabs semantics
Custom dropdowns
Checks:
- Combobox/listbox/option roles only if implemented fully
- Expanded state
- Active option communicated
- Input field name remains clear
If a custom widget is incomplete, file both labeling and interaction bugs.
ARIA Role, State, and Value Testing
WCAG 4.1.2 Name, Role, Value is the core criterion family here.
| Aspect | Question | Example failure |
|---|---|---|
| Name | What is this called? | Unnamed icon button |
| Role | What kind of control is this? | Clickable div announced as text/group |
| State | What is its current condition? | Expanded menu not announced expanded |
| Value | What value does it hold when relevant? | Slider value not exposed |
A perfect aria-label on a div that is not keyboard operable still fails users. Labels and operability travel together.
Useful state attributes to verify
aria-expandedaria-selectedaria-checkedaria-pressedaria-invalidaria-currentaria-disabled(and whether the control is truly not operable)aria-busyduring loading when used
Test state flips, not only the initial render.
aria-labelledby Reference Testing
Broken references are easy to ship.
Checklist:
- Every ID in
aria-labelledbyexists exactly once. - Referenced elements are not accidentally empty.
- Order of IDs produces a natural name.
- Hidden content is intentionally included or excluded.
- Conditional rendering does not remove the labeled node while the control remains.
Example failure:
<!-- Bug: title id changed, labelledby left behind -->
<div role="dialog" aria-labelledby="old-title-id">
<h2 id="new-title-id">Confirm delete</h2>
</div>
DevTools and axe often catch this. Still verify with SR because naming computation can surprise you with whitespace and hidden nodes.
When Visible Text and ARIA Disagree
If a button shows "Continue" but aria-label="Submit payment", many AT users hear "Submit payment" and sighted users see "Continue". That mismatch is a problem for voice control users and for cognitive consistency.
Testing rule:
- Accessible name should usually match or reasonably include the visible name.
- If product needs extra context, add it carefully ("Continue to payment") rather than a totally different phrase.
This is a high value manual judgment that scanners rarely enforce well.
Test Cases for ARIA Labels
| ID | Title | Steps | Expected |
|---|---|---|---|
| ARIA-01 | Icon close button has name | Focus close icon in modal with SR | Announces meaningful close name and button role |
| ARIA-02 | Input uses visible label | Focus email field | Announces Email (or equivalent), not only "edit text" |
| ARIA-03 | aria-labelledby resolves | Inspect dialog name in DevTools and SR | Name equals dialog title text |
| ARIA-04 | Expandable filter state | Activate Filters button | Announces expanded/collapsed correctly before and after |
| ARIA-05 | Error description linked | Submit invalid field | Error text is associated and announced appropriately |
| ARIA-06 | Row action context | Activate Delete in table row 3 with SR | Name includes enough context to know what is deleted |
| ARIA-07 | Dynamic label update | Toggle sort direction | Announced name/state reflects new sort order |
| ARIA-08 | No conflicting role | Inspect custom card button | Role and name match actual behavior |
Worked Example: Table Row Actions
Visual UI:
Invoices
[ Download ] [ Delete ] for each row
Broken implementation:
<button><svg>...</svg></button>
<button><svg>...</svg></button>
SR output: "button", "button".
Fixed implementation options:
<button type="button" aria-label="Download invoice 1842">...</button>
<button type="button" aria-label="Delete invoice 1842">...</button>
Or visually hidden text:
<button type="button">
<span class="sr-only">Delete invoice 1842</span>
<svg aria-hidden="true" focusable="false">...</svg>
</button>
Testing notes:
- Confirm unique names per row.
- Confirm keyboard reachability.
- Confirm delete confirmation dialog is also named.
- Confirm after deletion, focus lands somewhere sensible.
How Automation Helps ARIA Labels Testing
Automation can flag:
- Buttons without accessible names
aria-labelledbyandaria-describedbyinvalid references- Certain invalid ARIA attribute values
- Some role conflicts
Automation generally cannot fully judge:
- Whether "Click here" is good enough in context
- Whether two different buttons named "More" are confusing
- Whether a label matches business language
- Whether a state change is announced at the right moment
Use both. Start with axe on the page, then manually inspect critical controls and SR output.
Reporting ARIA Label Bugs Clearly
Weak:
ARIA is wrong on checkout.
Strong:
Title: Payment method icon buttons announce as unlabeled buttons
Environment: NVDA + Chrome, Windows, staging
Steps:
1. Open checkout
2. Move to payment method group
3. Focus the card brand icon buttons
Actual: "button" announced with no name
Expected: Each method announces a clear name such as "Pay with Visa"
Impact: High - SR users cannot distinguish payment methods
WCAG: 4.1.2 Name, Role, Value
Evidence: short audio note + DevTools Accessibility pane screenshot
Common Mistakes in ARIA Labels Testing
Mistake 1: Checking source HTML only
Accessible name is computed. Pseudo content, referenced nodes, and overrides matter. Use DevTools computed name.
Mistake 2: Assuming aria-label is always best
It can hide visible text and drift out of sync.
Mistake 3: Ignoring role and state
A great name on a non button div is incomplete.
Mistake 4: One static snapshot
Labels and states change after interaction.
Mistake 5: Tool score equals done
Meaningful naming needs human review.
Mistake 6: Placeholder as label
Placeholders disappear and are unreliable as the only name.
Mistake 7: Duplicate generic names in lists
Multiple "Edit" buttons without context hurt efficiency and accuracy.
Mistake 8: Leaving SVG focusable and announced
Decorative SVG can add noise unless handled carefully.
Mistake 9: Fixing labels but not focus order
Users still cannot reach the control.
Mistake 10: No translation test
aria-label strings hard coded in one language break i18n.
Practical QA Workflow You Can Reuse
- Identify critical controls in the changed UI.
- Inspect computed name/role/state in DevTools.
- Run automated name/reference checks.
- Keyboard to each control.
- Screen reader announce check on those controls.
- Exercise expanded, selected, error, and loading states.
- Compare names with visible text and task language.
- File impact based defects with AT details.
- Retest after fix with the same AT pair.
- Add regression cases for custom widgets.
Practice
Accessible naming is a craft. After you inspect a few pages, practice describing expected names and failure impact in QABattle battles. To build a consistent accessibility practice path, sign up and keep a personal library of good vs bad naming examples from systems you test.
Final Checklist for ARIA Labels Testing
- Every interactive control has a meaningful accessible name.
- Names match visible intent closely.
aria-labelledbyreferences resolve.- Native labels preferred over unnecessary ARIA.
- Roles match behavior.
- States update and are conveyed.
- Descriptions link hints and errors when needed.
- Screen reader output confirmed on critical journeys.
- Dynamic lists include context in names.
- i18n and state changes considered.
ARIA labels testing is not an exercise in collecting attributes. It is a product quality check that people who rely on assistive technologies get the same clarity others get from icons, layout, and visual hierarchy. When names, roles, and states are right, custom UI becomes usable. When they are wrong, polished interfaces turn into guesswork.
If you remember one rule, remember this: inspect the computed accessible name, confirm it with a screen reader, and treat wrong or missing names as functional defects.
Accessible Name Computation Surprises Testers Should Know
When you practice how to test ARIA labels, expect edge cases that pure HTML reading misses.
Hidden content still contributing to names
Nodes with display:none or hidden are often excluded from names, but aria-labelledby can still reference elements that are visually hidden on purpose, such as .sr-only text. That is valid when intentional. It is a bug when a draft or obsolete string remains in a hidden node and becomes the spoken name.
Multiple sources competing
If a button has inner text "Save" and also aria-label="Continue", the aria-label typically wins. Sighted users and AT users now have different names. Flag it unless there is a carefully justified exception.
Images inside controls
An image with empty alt inside a button may contribute nothing, leaving the button unnamed unless other naming exists. An image with alt "x" may produce a poor name. Prefer explicit button text or aria-label and mark decorative SVGs as hidden from the tree when appropriate.
Whitespace and punctuation
Concatenated aria-labelledby fragments can produce awkward names like "Invite teammateSubmit" without spacing. Listen with a screen reader; do not assume ID order alone is enough if empty separators are missing.
Live regions are not labels
aria-live announcements communicate changes. They do not replace a control's accessible name. A toast that says "Saved" does not name the save button.
Testing ARIA in Design Systems and Component Libraries
Most product bugs are multiplied design system bugs.
QA partnership ideas:
- Build a gallery page of every icon button variant and run name checks.
- Include modal, drawer, tabs, toast, and menu compositions in Storybook test hooks.
- Add automated axe checks on component stories for missing names.
- Still run SR samples on composed product pages where labels include business context.
Component tests catch "unnamed close icon." Product tests catch "Delete" without invoice number context in a dense table. You need both layers.
Voice Control and Name Consistency
Accessible names also affect voice control software. If visible text says "Continue" but the accessible name is "Next step in onboarding wizard 2," voice users saying "Click Continue" may fail. This reinforces the rule that visible label text and accessible name should align closely.
When filing bugs, mention voice control impact for high traffic controls even if you primarily reproduced with a screen reader. It widens the user impact story.
Internationalization Checklist for Labels
| Check | Why it matters |
|---|---|
| aria-label strings are in translation pipelines | Hard coded English breaks locales |
| Name length still makes sense in German/Finnish | Layout and verbosity differ |
| aria-labelledby references translated visible nodes | Keeps one source of truth |
| Locale switched retest on critical forms | Runtime language changes can leave stale labels |
| Mixed LTR/RTL icon buttons remain named | Icon meaning may change with direction |
If your product ships multiple languages, ARIA labels testing is incomplete in English only.
Anti-Patterns Cheatsheet
| Anti-pattern | Better approach |
|---|---|
<div onclick> with aria-label only | Native <button> with name and keyboard support |
| aria-label on every element "just in case" | Name only what needs it; prefer visible text |
| Labeling a whole page region "content" | Meaningful landmark labels only when needed |
| Using role=button without Enter/Space | Implement full keyboard behavior or use native |
| aria-labelledby=" " empty | Remove or fix references |
| Identical "More" actions in long lists | Include row context in the name |
Print this for code review days. Many ARIA defects are pattern repeats.
Mini Regression Pack You Can Automate Plus Manually Spot Check
Automate:
- All buttons and links have accessible names (axe)
- No invalid aria-labelledby references (axe)
- Dialog nodes expose names (axe + unit tests)
Manually spot check each release:
- One icon only control in the changed area with SR
- One form error association with SR
- One expandable widget state flip with SR
- One list/table row action context check
Automation reduces drift. Manual spot checks protect meaning.
FAQ
Questions testers ask
What is an ARIA label?
An ARIA label is an accessible name provided through ARIA attributes such as aria-label or aria-labelledby. It helps assistive technologies announce what a control is when visible text is missing, incomplete, or not programmatically associated. Good labels describe the purpose of the control in user language.
How do you test ARIA labels?
Inspect the accessible name in browser DevTools Accessibility panels, confirm the name matches visible intent, verify the control role and state, then validate with a screen reader while completing real tasks. Check both idle and dynamic states, including errors, expanded menus, and icon only buttons.
What is the difference between aria-label and aria-labelledby?
aria-label sets the accessible name with a string on the element. aria-labelledby points to one or more element IDs whose text content form the name. Prefer visible text and aria-labelledby when the name is already on screen. Use aria-label for icon only or otherwise unnamed controls when needed.
Do I need ARIA on every element?
No. The first rule of ARIA is not to use it when native HTML already provides the right semantics. A native button with text, a label linked to an input, and a semantic heading often need no ARIA. Incorrect ARIA is often worse than no ARIA.
Can automated tools fully validate ARIA labels?
No. Tools can flag missing names, invalid references, and some conflicting ARIA. They cannot fully judge whether a name is meaningful, duplicated in a confusing way, or wrong for the business task. Pair scanners with manual and screen reader checks.
What are common ARIA labeling bugs?
Common bugs include icon buttons with no name, aria-labelledby pointing to missing IDs, names that do not match visible text, overuse of aria-label that overrides useful visible names, wrong roles with correct labels, and stale labels after UI state changes.
RELATED GUIDES
Continue the route
Screen Reader Testing: NVDA, VoiceOver, JAWS
Learn screen reader testing with NVDA, VoiceOver, and JAWS: practical checklists, ARIA announcements, live regions, and QA workflows that catch real barriers.
Accessibility Testing Checklist (WCAG 2.2)
Use this WCAG accessibility testing checklist for WCAG 2.2 AA: audit process, A vs AA vs AAA, functional test cases, and a practical QA starting path.
Automated Accessibility Testing with axe-core
Learn automated accessibility testing with axe-core: CI integration, Playwright scans, what automation catches, and limits you still must test by hand.
Keyboard Navigation Testing
Learn keyboard navigation testing for web apps: tab order, focus indicators, skip links, modal focus traps, and practical QA test cases you can run today.