Carl Rippon

Building SPAs

Carl Rippon
BlogBooks / CoursesAbout
This site uses cookies. Click here to find out more

Automated React Accessibility Checks

April 06, 2022
reacttests

Testing apps on accessibility is something that is often forgotten. This post covers a couple of tools that provide automated accessibility checks for React apps.

Automated React Accessibility Checks

eslint-plugin-jsx-a11y

The first tool is an ESLint plugin called eslint-plugin-jsx-a11y.

To install the accessibility plugin, run the following command in a terminal:

npm install eslint-plugin-jsx-a11y --save-dev

We tell ESLint to use the accessibility plugin with its recommended rules in the ESLint configuration file as follows:

{
  ...,
  "plugins": [..., "jsx-a11y"],
  "extends": [..., "plugin:jsx-a11y/recommended"],
  ...
}

If you use Visual Studio Code and the ESLint extension, accessibility issues will be highlighted as shown in the screen shot below:

ESLint error

In the example above, eslint-plugin-jsx-a11y has picked up that a form field’s label and input elements aren’t associated. This means that a screen reader won’t read out the label when the input gains focus.

The great thing about this ESLint plugin is that it catches accessibility issues as you write code. This means that it is cheap to resolve the detected accessibility issues. 😊

jest-axe

The second tool we will look at is a Jest plugin called jest-axe. To install this with its TypeScript types, run the following command in a terminal:

npm install --save-dev jest-axe @types/jest-axe

We can use jest-axe to implement a component test that checks accessibility.

In the test file, we start by importing the following from jest-axe:

import { axe, toHaveNoViolations } from 'jest-axe';

axe will inspect the component’s DOM structure, and toHaveNoViolations is a Jest matcher which fails the test if axe finds accessibility problems.

After the import, we also have to make Jest aware of the toHaveNoViolations matcher:

expect.extend(toHaveNoViolations);

We can then write a component test with React Testing Library as follows:

test('Should not violate accessibility rules', async () => {
  const { container } = render(<Form1 />);
  expect(await axe(container)).toHaveNoViolations();});

Running the test catches the same accessibility issue as the ESLint plugin caught:

Jest error

The nice thing about doing accessibility checks in a component test is that you can interact with the component to get it in a particular state before doing the checks. So, for example, accessibility can be checked after the form has been submitted:

test('Should not violate accessibility rules when invalid form submitted', async () => {
  const { container } = render(<Form2 />);
  userEvent.click(screen.getByText('Submit'));
  await screen.findByText('You must enter your name');
  expect(await axe(container)).toHaveNoViolations();
});

Nice. 😊

These won’t guarantee your app is fully accessible

Consider the following form:

export function Form2() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<FormData>();
  const onSubmit = (data: FormData) => console.log(data);
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <label htmlFor="name">Name</label>
      <input id="name" type="text" {...register('name', { required: true })} />
      {errors.name && <div>You must enter your name</div>}
      <button type="submit">Submit</button>
    </form>
  );
}

The field label and input elements are associated and the ESLint and Jest plugins don’t report any accessibility issues.

The accessibility of this form can be improved though. For example, a screen reader won’t let the user know whether the field is invalid or not and will not read out the validation error message. 😞

These tools are worth it though, and it does catch some issues. Also, it costs very little time to set both these tools up and use them.

Check out the next post to learn how to make the above form more accessible.

This example project is on my GitHub

Did you find this post useful?

Let me know by sharing it on Twitter.
Click here to share this post on Twitter

If you to learn more about testing React apps, you may find my course useful:

Testing React Apps with Jest and React Testing Library

Testing React Apps with Jest and React Testing Library
Find out more