Automate Accessibility Audits with GitHub Actions

Erin Doyle
InstructorErin Doyle

Share this video with your friends

Send Tweet
Published 3 months ago
Updated 2 weeks ago

We can leverage GitHub Actions to automate the running of all of our accessibility auditing tools as part of a Continuous Integration (CI) workflow.

Auditing tools will only catch a percentage of potential accessibility issues, it is no replacement for manual testing. But being able to automate the auditing will add efficiencies to our testing and provide an early warning system that can be run much more frequently than it’s practical to perform manual testing. Additionally, we can use our CI suite as a safety net to prevent code changes that break accessibility from being able to be merged.

Resources

  • https://app.egghead.io/lessons/react-set-up-eslint-to-audit-accessibility-issues-in-react
  • https://docs.cypress.io/guides/continuous-integration/github-actions#Basic-Setup
  • https://github.com/cypress-io/github-action

Instructor: [0:00] To leverage GitHub Actions to automate the running of all of our accessibility auditing tools, we'll need to set up a continuous integration workflow. If this is your first GitHub Actions workflow, then you'll need to create a .github directory at the root of your project and, within that, a Workflows directory.

[0:19] Then you'll need to create a YAML file in this new Workflows directory. Since this is our continuous integration Workflow. I'm going to name it ci.yaml. We'll start this Workflow with its name, and we'll specify that it should run on all pushes and PRs submitted to the main branch.

[0:43] The first thing we want to add to the workflow is a job for running ESLint, which, if we've got the JSX accessibility plugin installed, we'll automate checking our static code for potential accessibility issues. We'll specify that this job runs on the latest version of Ubuntu, and we'll give our job a name. Now, we specify the steps that the job needs to take.

[1:04] The first step will be to check out the branch. Then we'll need to install Node on the machine running our job, and we're going to specify that it should install Node version 14. Now, we need to install our npm dependencies. Finally, we can go ahead and run the Lint script, which, as specified in our package.json file, is going to run ESLint.

[1:27] Now, we'll add a job for running the unit tests that we've written using Jest aXe to check our components for accessibility issues. Similar to before, I'm going to specify the machine to run the job on, give the job a name. We'll repeat the same steps of checking out the repo, setting up Node and installing our dependencies. Then, finally, we'll run our test script.

[1:48] Finally, we'll need to add one more job for running our end-to-end tests. The first parts are the same as before. We'll specify the machine. We'll give it a name. We'll check out the repo. Here, we'll specify that we're going to be using the Cypress GitHub Action.

[2:04] We tell it that we want to use Chrome as the browser to test in. We give it the script that we want to use in order to start our application. We'll specify the URL for our local server so the job knows to wait until the server is ready before the tests start running.

[2:19] One thing to note is how each of these is organized into their own jobs. I could have created one big job that ran all of these scripts, but I deliberately wanted to keep them separate. This is so that I can see failures for each separately.

[2:31] If these tasks were run linearly, then if one failed, the whole job would exit before executing the following task. I want to know if I have failures in any of these jobs, rather than having to fix any failures for one, push the changes and run again before I can learn if I have any failures in the other jobs.

[2:50] Now, let's see what this looks like in GitHub when I push a PR. You can see all three of the jobs defined in our workflow have started running automatically when I created this PR, and it's running all three of them in parallel as we defined.

[3:06] Now that all three of the jobs have completed, we can see that the ESLint job was successful, but the unit test job and the end-to-end test job both failed. Again, this is why we want to see them running separately so we can see the failure separately. If we want to look at the details of any of these, we can get to them here. Let's see what failed in our unit test job.

[3:28] This brings us to the log for each of the jobs. We can see that our unit tests failed because there were accessibility findings, which is what we expected. Now, let's look at our end-to-end test job. Here, we have the summary from our end-to-end tests. We can see that each of these tests failed.

[3:58] Now, if we go back to the PR, we can see that, even though some of my checks have failed, I'm still able to merge if I want to. We can add a branch protection rule that will prevent merging a pull request if any of the checks have failed.

[4:14] We can do that by going to the Settings for the repository, going to Branches, and under Branch protection rules, click the button to Add a rule. I'm going to be setting this up on my main branch. You'll want to check the box next to Require status checks to pass before merging. We'll need to search for each of the jobs in order to add them to the list of status checks that are required.

[4:43] Now that we've added all of these to the list, they should be required to pass before merging will be allowed. Now, if I go back to my PR, you'll see that now there's this message about "Required statuses must pass before merging." If I weren't an administrator, I would not be allowed to merge this pull request.