Automated UI accessibility testing with Cypress

Make sure your UI projects follow accessibility standards before deploying to production

Photo by Philipp Deus on Unsplash

A more accessible, readable, mobile-friendly and up to date version of this story is available on my personal blog!

While writing tests (unit, integration or end to end) is core to my day to day workflow before pushing anything to production, I’ve often forgotten to bring my focus to whether or not what I was building was accessible to everyone. Accessibility or a11y (accessibility has 11 letters between the first and last letter) is nonetheless an essential part of every product development and should get as much if not even more attention than testing.

Skipping this was a mistake on my end, so I started looking to see if there were any ways I could integrate accessibility tests into my testing pipeline. The aim was similar to writing tests, although here there would be an additional acceptance item, which would be that a given feature or view would have to be compliant with a set of rules. That’s how I discovered cypress-axe, which integrated perfectly with cypress, the end to end testing framework I’m currently using.

In this short post, we’ll see how to setup cypress and cypress-axe and write tests that will make sure your frontend projects follow proper accessibility rules.

Note: The repository containing the code snippets featured in this article is available here.

Setup

For the purpose of this post, we’ll consider a very simple React app to provide a frontend to run tests against. If you have any apps based on any other favorite framework or library that you wish to use while following this tutorial, you can use them; everything should work the same.

First, we’ll have to install a few dev dependencies:

Cypress, the testing framework, if you’re not already using it

axe-core , the accessibility engine for automated Web UI testing

, the accessibility engine for automated Web UI testing cypress-axe , the package which will let us use axe-core capabilities within cypress.

, the package which will let us use capabilities within cypress. start-server-and-test , a little helper that we’ll run to start our app, wait for it to be ready, then start cypress to run the test suits.

To get these you can run the following command at the root of your UI project:

yarn add -D cypress cypress-axe axe-core start-server-and-test

Now that we have all the tools installed in our project, we’ll have to write some scripts in our package.json to help us run the tests:

package.json excerpt with our test script

The code snippet above contains the scripts required to run the tests. We need a start script that can start our app; in my case, it’s react-scripts start since I’ve based this demo on a create-react-app. If you already have a start command no need to change it.

The test script runs start-server-and-test which runs a series of steps. First, it will run the start script, then wait for the http://localhost:3000 to be available, and finally, once the app is fully started it will run the cy:open which will start the cypress UI and let us run tests.

Writing an accessibility test

Now that cypress and cypress-axe are setup, it’s time to write our first test. First, in cypress/support/index.js , let’s add the following code snippet:

cypress/support/index.js excerpt with cypress-axe

Then, let’s head to the cypress/integration folder and create a accessibility.spec.js . This file will contain the following accessibility test:

Our first accessibility test using cypress-axe

The test is contained within the it statement above, and as we can see it contains a few lines which execute the following steps:

we visit our app on whatever URL it is running, in the case of the sample React app: http://localhost:3000 we run injectAxe which injects the axe-core runtime into the page we’re testing. we run checkA11y with some options which will return any potential accessibility issues on the current page.

Concerning the options passed in the last function, we can see that we’re passing an object with a key runOnly . This object has two fields, type set to tag , and value set to ["section508"] . With these options, we’re telling axe-core to test our page by only running the rules under the section508 accessibility standard which is one of the many accessibility standards for web UIs.

If we choose to call checkA11y without any options, we would run the accessibility tests with all the accessibility rules available.

Now that we’re done writing our first test, it’s time to give it a try!

First accessibility test run