🚅 Building a Cypress Accessibility Pipeline with Next.js and Axe
Tags: a11y, webdev, nextjs, cypress
Published: 2023-12-18 15:42:03

<Intro>

In the web development world, there's a LOT of things we should remember. We should remember to build applications that are accessible, responsive, scalable, maintainable, cost-effective, secure, and the list goes on.

But that first item, accessibility, gets overlooked way too often. Unfortunately, it's normal to see accessibility as an afterthought in a web application, much like those who need websites to be accessible. People are people and they have every right to use your website (assuming its public) as anyone else. 

If a user wants to consume your content, why shouldn't they be able to? 

If someone is taking time out of their day to use your product, why shouldn't they have the best experience possible?

These are the questions we should be asking ourselves as we construct things that we care about. But as the developer, that's another thing you need to be mindful of. 

Is my application accessible? Am I meeting the needs of my users, ADA, and WCAG? Is my company or client at risk of being sued for not being above a certain accessibility score? 

It's hard to keep up with all of these things, but hopefully this tool will make it easier on you.

Let's talk about Cypress and Axe.

---

## What's Cypress? 🌲

Cypress is a common name for some conifers in the Cupressaceae family (okay, I'm joking 😉, wrong cypress).

Cypress is (primarily) an E2E testing framework.

You can document user journeys, record where errors occur in your application, test components, and test E2E tests.

Cypress has tons of support and is available in any project that can install NPM dependencies. 

## What's Axe? 🪓

Axe is an accessibility testing framework that enables you to test your website against the standards of WCAG, A11y, ADA, and the like. 

You can use Axe as a browser extension, GitHub CI/CD, and so much more. We're gonna use it in an automated CI/CD pipeline.

## Building the Pipeline 🏗️

Okay cool, we know what the tools are so let's clone [the repo](https://github.com/lundjrl/nextjs-accessibility-ci) and play around.

To start off, we'll install our dependencies with [bun install](https://bun.sh/docs/cli/install) or if you want, `yarn install` is supported too.

Next, let's spin up the site with `bun run dev` or `yarn dev`. If you see the site at `localhost:3000` then we're good to go. But before we get ahead of ourselves, let's look at the folders inside the project.

The main takeaways here are the `app`, `.github`, and `cypress` directories.

If you're new to Next.js or Next.js 13, the `app` directory is a new way to implement SSR (server-side rendering) in your web application. Each folder is a route and will render content on the page as long as there is a `page.tsx` file inside of it. 

To those of you who haven't worked with GitHub Actions, if you have a `.github/workflows` folder in your project (and your repo is hosted on GitHub), upon pushing your code, GitHub will look in this folder for YAML files to run as CI/CD. 

This is a super easy way to implement CI/CD pipelines in your projects. The two files already in this repo are for e2e testing on push and verifying our Next.js site will build.

And as you may have guessed, the `cypress` directory will contain our tests and some configuration for Cypress. Let's take a peak at the resources there.

<Looking at the Cypress directory>

If you look in the `cypress/support/e2e.ts` file, you'll see that we're importing custom commands (if we had any) and the cypress-axe package. 

![If I had any custom cypress commands meme](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/96dyd6wdxw9qo5853gh4.jpg)

That cypress-axe package import is crucial to using the functions that allow us to test our website against accessibility violations. 

The `cypress/e2e` directory itself contains all of our tests for the UI of the application. The `cypress/e2e/log-to-terminal.cy.ts` file is mainly here to provide cleaner logs to us for debugging accessibility issues. The main tests exist in the sibling file `check-accessibility.cy.ts`.

### What are we testing?

Each test should be self-describing. Some will target color accessibility for folks with color blindness, some will check for accessible HTML, and some others do custom things.

These "custom things" can be anything between excluding HTML elements, targeting specific ones, specifying custom rules, and only failing a test if serious or critical accessibility issues are found. 

Here are some examples:

#### Checking All Potential Issues

![Checking potential issues](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6hjnr074zhcu2u8jb25w.png)

#### Critical Issues Only

![Critical issues only](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfoa6ieweph7g7d7ijei.png)

#### Custom Rules

![Using custom rules](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/34v6emh0howvrm7u3wgs.png)

#### Ignoring Specific Elements

![Ignoring specific elements](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uxdn0ft1uvar2usvd5ad.png)

#### Targeting Specific Elements

![Targeting specific elements](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e5uxarrb24zwhh7h1odc.png)

As you can see, there's not a lot of code that goes into these tests which is ideal if we're double-checking for any violation we might have missed. 

Now, let's run these tests via `bun run cypress:open` or `yarn cypress:open` respectively.

If all is well, you should see this:

![Cypress opening window](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yfjdbe96refy4v7mce9y.png)

You can choose whichever browser suits your preference.
Next, click the `E2E` testing type:

![Cypress E2E testing type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5tx7ud2b2ao7nebdi6nr.png)

After that, you should see a list of our spec files. `check-accessibility.cy.ts` is the only one we care about for the purpose of this tutorial. Click the spec and watch our tests run!

![Cypress spec dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i8m4h8m0ct1dxk7uux3p.png)

## Reviewing the pipeline steps

Awesome, so we can spin up the Next.js project and run our E2E tests locally. What about the YAML file for the pipeline?

It's pretty simple but let's review the steps inside `.github/workflows/e2e.yaml`.

At the top of the file, the `on` statement specifies on push or pull request to the main branch. This filters the action to only run under those conditions:
1. On push to the `main` branch.
2. On a pull request to the `main` branch.

After that, we specify our job and the container it runs in (ubuntu-22.04).

Then as you can see, there's 6 steps the pipeline executes:

1. Checkout our repo.

2. Install Node (Bun isn't supported yet).

3. Restore the Next.js cache for faster build times.

4. Install dependencies

5. Build the Next.js site

6. Run Cypress


### Conclusion
That's it! After we push to our main branch or make a PR, Cypress scanned each page we defined and let us know where we should fix our code to comply with accessibility standards.

Now could you imagine reading up all the WCAG and A11y rules yourself? Using a tool like this will save your team time, cost, and possibly a lawsuit.

I hope you enjoyed this article and learned something! Got a hot tip for implementing accessibility? Something cool about the tools discussed that I didn't mention? Let me know in the comments below!

### Resources
[Is your site accessible enough?](https://www.accessibilitychecker.org/)

[Demo Repository](https://github.com/lundjrl/spark-accessibility-ci)

[Cypress Docs](https://docs.cypress.io/guides/overview/why-cypress)

[Axe Docs](https://github.com/dequelabs/axe-core/blob/develop/doc/developer-guide.md)

[Meme creation tool](https://imgflip.com/memegenerator)

Cover Image created by [Tomáš Hirsch](https://unsplash.com/photos/a-dirt-road-surrounded-by-trees-and-bushes-3VXDX6-cRPA)