Testing forms for accessibility using React Testing Library

Katie Radford
Beam Benefits
Published in
4 min readMay 23, 2022

Accessibility is starting to receive the recognition it deserves in the tech space. Citing Robles v. Domino’s Pizza, accessibility is not only an ethical issue but also a potential legal issue. Unfortunately, websites are still falling behind standards with 54.4% of homepages missing form input labels in 2021!

How can we ensure that our forms are up to standards from the start?

Photo by Tamas Pap on Unsplash

As engineers, we carry a large portion of the responsibility for building and maintaining accessible applications. With so many guidelines, articles, and resources, one can certainly feel overwhelmed when approaching this challenge. This is especially true concerning forms, which even for a seasoned engineer, may require a few searches of MDN’s web docs.

An effective way to confirm that your form is meeting guidelines is to implement test-driven development (TDD). To summarize TDD, the test is written first and then the code is written to fulfill those requirements. Using TDD takes us out of the “Let’s make a form!” mentality and into a “How should the form function? 🤔” mentality. It’s like thinking before you speak, but with code.

We’ll be using Jest as our testing framework and React Testing Library (RTL) for our helpers. RTL simulates how a user would interact with the page. For example, a person would search for a Submit button on a page and then click it (or press Enter on the keyboard) to use it. RTL can accomplish this task with userEvent.

Testing examples

In our examples, we will be referencing a pizza-building form that would send pizza details to a local pizzeria, which would then cook and deliver the perfect pizza!

Our tests will be based on Web Content Accessibility Guidelines (WCAG) 2 which are accessibility guidelines provided by the Accessibility Guidelines Working Group. These are generally accepted as the standard to uphold in the web accessibility space.

UI Controls

The most common theme in WCAG for forms is proper labeling. Both visual and non-visual users identify fields by their labels, so when targeting fields for input, use getByLabelText. This is the preferred method for form elements. By using this method to target a field, we are confirming the field has a label and the label states what we expect.

The getByLabelText query will be able to find <label>, aria-labelled-by, and aria-label. Take note, however, that the aria-label will not be visually on the page, so the purpose of this type of input should be visually obvious (perhaps through context or an icon).

Custom inputs, such as a button styled to appear as a checkbox, can still be tested using RTL. However, these creative solutions often result in less accessible elements. In some cases, the element loses its native keyboard accessibility and gains odd default styling.

When our user starts building their pizza, they are asked to choose the pizza size, which is a great candidate for a radio group. Using getByRole and the name of the radio group (determined by a legend), we can confirm that a fieldset is present. We are also indirectly asserting that the radio buttons’ labels are present and meaningful using getByLabelText.

Required messaging

To communicate that a field is required, plain language (e.g. “Required”) is best. Alternatively, we can display an asterisk for visual users and provide an aria-label of “required field”. Both of these routes will pass our test below; though, in practice, we would pick just one route to test.

Testing for “required” in the label
This form element uses plain language to communicate that the field is required.
This form element uses an asterisk to communicate to visual users and a label for users with a screen reader.

Validation and errors

Testing for validation and errors is a strong suit of RTL. Let’s say we want to ensure delivery instructions are present. After a user clicks on the Submit button, we expect validation to run and applicable errors to display. If a user didn’t fill in a required Delivery instructions field, we expect the error text, “Please enter delivery instructions for this order,” to display in the document.

Keyboard & mobile navigation

Navigating the form entirely from the keyboard or device is another important element of accessibility.

Some keyboard interaction can be accomplished with userEvent, which comes in handy for checking that a user can access a form field and change the value by keyboard alone. You can see some examples of this here.

Furthermore, other device accessibility (e.g. a touchscreen phone) is mentioned in WCAG 2.5, which can be covered by RTL’s pointer.

Pro Tip: If you are testing an existing application, testing-playground.com is an excellent tool for finding queries. There’s even a browser extension!

Because these examples are not exhaustive, I recommend the resources below for further testing (both automated and manual).

Disclosure: For informational purposes only and not intended to be relied on as complete information and does represent the opinion or position of Beam Insurance Services LLC.

Additional Resources

--

--

Katie Radford
Beam Benefits

Software engineer and leisurely fashion historian