Tackle web accessibility issues with automated testing

Henk-Jan van Voorthuijsen
Henk-Jan van Voorthuijsen

10 oktober 2019

Spiffy animations and visuals are the norm now when creating a website. A lot of websites are responsive so everybody can checkout the website on every device. Sounds good right? A website that is available for everybody… or at least as long as you can see.

When you’re visually impaired the story is different. All those websites with their spiffy animations aren’t that great to navigate on with a screen reader. But I hear you think: Making a website accessible is HARD! And yes, I agree, making EVERYTHING on your website accessible for the visually impaired as well for people with normal sight is actually quite a challenge, but that doesn’t mean we shouldn’t do our best to make almost everything on our website accessible!

Rules

There are a lot of small things you can do to make your website more accessible, for example:

  • Using alt-tags for images (visually impaired people rely on those to know what’s going on)
  • Creating a proper heading structure
  • Use enough contrast
  • Use proper roles for the elements on your website

I just listed four things, but there is a lot more that you can do to make your website better accessible. 

Remembering all those ‘rules’ is quite difficult. Even when you are fully focussed on accessibility it is quite easy to make mistakes and forget stuff. And some things are quite hard to keep an eye on when you are working on a single component (for example the heading structure).

Automated testing

Wouldn’t it be great to have something in your development process that tests for accessibility issues automatically so you can fix issues before they even become part of your website?

Actually that something is already available. The company deque created a (free) tool called axe that can test your website for you. You can use it as a browser extension (but that still feels manual right?) or you can use axe-core with Javascript. They even created a lot of integrations so every ingredient is there to start testing.

When the idea grew to test for accessibility automatically (in the pipeline) I had three wishes:

  1. Easy setup: if you want developers to use it it the setup has to be easy;
  2. Testing the rendered page: accessibility of your website heavily relies on the context, so you need the full page with all styling applied;
  3. Works for SPA’s.

The second and third points are quite easy to tackle since there are axe plugins for Puppeteer / Selenium / PhantomJS. With either of those we could render a page, click around and test the resulting webpage.

The first point is harder. Let’s look at an example:

(using Puppeteer since I have the most experience with that)

 

This is what I want to test

Imagine we are on the homepage
When I click on the next button in a stepper component and wait for the second step to load
Then I want that second step to be checked for accessibility issues.

This is the code needed for that

const { AxePuppeteer } = require('axe-puppeteer');
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.goto('https://localhost/');
  await Promise.all([
    page.waitForSelector('#step-two'),
    page.click('button.next')
  ]);

  const results = await new AxePuppeteer(page).analyze();
  console.log(results.violations);

  await page.close();
  await browser.close();
})()

Auch.. That is some hefty code for just one step in a stepper component.

Solution

I like the test, but not the code that is needed for it. So with the (financial) help of SIDN (Dutch fund for improving the internet) I’ve created something that lets you write your test this way:

Feature: Stepper

Scenario: Test the second step of the stepper
    Given I open the url "http://localhost/"
    When I click the button "button.next" and wait for the element "#step-two"
    Then the section "#step-two" should be accessible

Nice, right? 

But I can hear you think: “Looks great, but probably a hell to implement…”

It really isn’t that hard:

  1. Put the test in a file “features/stepper.feature”
  2. Run:
docker run -v `pwd`/features:/home/node/app/features --rm -it --network=host 
enrise/puppeteer-cucumber:2.2

DONE

For this example you need Docker, but I’ve created an example setup that shows you how to run this with or without Docker.

The accessibility issues that are found are outputted directly in the command line; perfect for in a pipeline of some sorts!

Links