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 and play around.
To start off, we'll install our dependencies with bun 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.
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.
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
Critical Issues Only
Custom Rules
Ignoring Specific Elements
Targeting Specific Elements
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:
You can choose whichever browser suits your preference.
Next, click the E2E
testing type:
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!
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:
- On push to the
main
branch. - 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:
Checkout our repo.
Install Node (Bun isn't supported yet).
Restore the Next.js cache for faster build times.
Install dependencies
Build the Next.js site
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?
Cover Image created by Tomรกลก Hirsch