Using Roles in React Testing Library

June 26, 2024

Many different HTML elements, such as tables and buttons and text inputs, have what is referred to as an implicit role.

Why Use Roles?

React Testing Library encourages the use of roles to find elements in your tests. This approach not only makes your tests more accessible but also ensures that they closely mirror how users interact with your application.

Common Default Roles

Here is a short list of default roles you might use in your tests:

  1. button - For clickable buttons.
  2. checkbox - For checkboxes.
  3. textbox - For input fields that accept text.
  4. link - For anchor elements that link to other locations.
  5. radio - For radio buttons.
  6. combobox - For combo boxes (drop-downs).
  7. list - For lists, such as <ul> or <ol>.
  8. listitem - For items within a list.
  9. heading - For headings, such as <h1>, <h2>, etc.
  10. dialog - For dialog windows.

Example: Using Roles in Tests

Let's walk through an example to demonstrate how to use these roles in your tests.

Component: ExampleComponent.jsx

First, we'll create a simple React component that includes various elements:

import React from 'react';

function ExampleComponent() {
  return (
    <div>
      <h1>Title</h1>
      <button>Click me</button>
      <input type="text" placeholder="Enter text" />
      <a href="/about">About</a>
    </div>
  );
}

export default ExampleComponent;

Test: ExampleComponent.test.jsx

Next, we'll write a test that uses roles to find these elements:

import React from 'react';
import { render, screen } from '@testing-library/react';
import ExampleComponent from './ExampleComponent';

test('renders elements with correct roles', () => {
  render(<ExampleComponent />);

  // Find elements by their roles
  const heading = screen.getByRole('heading', { level: 1 });
  const button = screen.getByRole('button');
  const textbox = screen.getByRole('textbox');
  const link = screen.getByRole('link');

  // Assert that elements are in the document
  expect(heading).toBeInTheDocument();
  expect(button).toBeInTheDocument();
  expect(textbox).toBeInTheDocument();
  expect(link).toBeInTheDocument();
});

Explanation

By using getByRole, we ensure that our tests are closely aligned with how users interact with the UI, improving both accessibility and reliability.

Conclusion

Using roles in React Testing Library is a powerful way to write accessible and maintainable tests. By leveraging roles, you can create tests that are more intuitive and robust, ultimately leading to a better user experience. So, next time you write a test, remember to consider using roles to find elements and ensure your application is accessible to all users.