How to fix Unable to query by role "button" - no matching elements in React
This error occurs when React Testing Library cannot find an element with the specified ARIA role during testing. It often happens when elements are not properly accessible, have incorrect roles, or are rendered asynchronously.
Quick fix
Fixes Unable to query by role "button" - no matching elements
// Good: button element has implicit role
<button>Click me</button>
// Good: div with explicit role
<div role="button">Click me</div>
// Problematic: div without role
<div onClick={handleClick}>Click me</div> // No role- Verify the element has the correct role
- Check for accessibility tree exclusions
- Handle asynchronous rendering
- Check for role changes between versions
// Good: button element has implicit role<button>Click me</button>// Good: div with explicit role<div role="button">Click me</div>// Problematic: div without role<div onClick={handleClick}>Click me</div> // No roleUnable to query by role "button" - no matching elements
What this error means
The "Unable to query by role" error indicates that React Testing Library's query methods (getByRole, findByRole, etc.) cannot locate an element with the specified role in the rendered DOM. This can happen due to several reasons including incorrect role assignment, elements not being accessible, asynchronous rendering not being handled properly, or the element being hidden from the accessibility tree.
Typical symptoms
- Tests fail with "Unable to find role=\"button\" - no matching elements"
- getByRole or findByRole queries return TestingLibraryElementError
- The element appears visually in the rendered output but is not found by role queries
- Other queries like getByText or getByTestId work but getByRole does not
- The error occurs after upgrading React Testing Library versions
Common causes
- The element does not have the expected implicit or explicit role attribute
- The element is hidden from the accessibility tree (aria-hidden, display: none, visibility: hidden)
- The element is rendered asynchronously and the test does not wait for it to appear
- The role has changed between Testing Library versions (e.g., button to combobox for certain components)
- The element is inside a container with aria-hidden="true"
- The element has role="presentation" or role="none" which removes it from the accessibility tree
- The query uses incorrect options (e.g., missing name when required)
How to fix "Unable to query by role "button" - no matching elements"
Inspect the rendered DOM to ensure the element has the expected role. For example, a <button> element has an implicit role of "button". If using a custom element, you may need to add role="button" explicitly.
// Good: button element has implicit role
<button>Click me</button>
// Good: div with explicit role
<div role="button">Click me</div>
// Problematic: div without role
<div onClick={handleClick}>Click me</div> // No roleEnsure the element is not hidden from the accessibility tree. Elements with aria-hidden="true", display: none, or visibility: hidden are excluded by default. Also check if parent elements have aria-hidden="true".
// Problematic: hidden from accessibility
<div aria-hidden="true">
<button>This button won't be found</button>
</div>
// Solution: remove aria-hidden or use { hidden: true } option
const button = screen.getByRole('button', { hidden: true });If the element renders asynchronously, use findByRole instead of getByRole. findByRole returns a Promise and waits for the element to appear (default timeout is 1000ms).
// Using getByRole (fails if element not immediately present)
// const button = screen.getByRole('button');
// Using findByRole (waits for element)
const button = await screen.findByRole('button');
// You can also increase timeout if needed
const button = await screen.findByRole('button', {}, { timeout: 5000 });Some elements may have different implicit roles in newer versions of Testing Library. For example, certain Material-UI components changed from role="button" to role="combobox". Check the Testing Library documentation and your component library's release notes.
// Old query (may fail after upgrade)
screen.getByRole('button', { name: /Ernie Variable 1/i });
// New query for combobox
screen.getByRole('combobox', { name: /Ernie Variable 1/i });Some roles require additional options like name for elements with accessible names. Check that you're providing the correct options for your query.
// Button with accessible name via aria-label
<button aria-label="Submit form">Submit</button>
// Query with name option
const button = screen.getByRole('button', { name: /submit form/i });
// Button with text content (implicit name)
<button>Save changes</button>
// Query with name from text content
const saveButton = screen.getByRole('button', { name: /save changes/i });Use screen.debug() to see the entire rendered DOM and verify what roles are available. This can help identify if the element has the expected role or if there are other issues.
import { screen } from '@testing-library/react';
// Render your component
render(<MyComponent />);
// Print the DOM to console
screen.debug();
// Print only accessible elements
screen.logTestingPlaygroundURL();
// Check available roles
console.log(screen.getAllByRole('button'));Advanced notes
React Testing Library uses the Accessibility Tree (computed by the browser) rather than just the DOM structure. This means elements must be accessible to be found by role queries. The hidden option can be used to include elements that are normally excluded from the accessibility tree. Also note that role="presentation" and role="none" completely remove elements from the accessibility tree, which differs from aria-hidden="true". When testing complex components like Material-UI or Chakra UI, check their documentation for correct role usage as these libraries may use non-standard ARIA patterns.
Frequently asked questions
- What does "Unable to query by role "button" - no matching elements" mean?
- ) cannot locate an element with the specified role in the rendered DOM. This can happen due to several reasons including incorrect role assignment, elements not being accessible, asynchronous rendering not being handled properly, or the element being hidden from the accessibility tree.
- How do I fix "Unable to query by role "button" - no matching elements"?
- This error occurs when React Testing Library cannot find an element with the specified ARIA role during testing. It often happens when elements are not properly accessible, have incorrect roles, or are rendered asynchronously.
- What causes "Unable to query by role "button" - no matching elements"?
- The element does not have the expected implicit or explicit role attribute The element is hidden from the accessibility tree (aria-hidden, display: none, visibility: hidden) The element is rendered asynchronously and the test does not wait for it to appear
- Is the "Unable to query by role "button" - no matching elements" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.