DEV Community

Cover image for A11y Unlocked: Screen Reader Automation Tests
Craig Morten
Craig Morten

Posted on • Edited on

A11y Unlocked: Screen Reader Automation Tests

In the past year since my last post A11y Testing: Automating ScreenReaders on the topic of automating screen readers, we're now in a better place with progress made in standards and tooling.

It is exciting to see the W3C ARIA-AT Community Group formed with a mission to improve screen reader interoperability by building out a suite of specifications, test standards, and test automation to mature the screen reader ecosystem towards first-class tooling.

"Enabling AT interoperability is a large, ongoing endeavor that requires industry-wide collaboration and support. The W3C ARIA-AT Community Group is focusing on a stable and mature test suite for five screen readers by the end of 2023. In the future, we plan to test additional screen readers and other kinds of assistive technologies with a broader set of web design patterns and test material."

Source: https://aria-at.w3.org/

While the standards community slowly work towards their long term goal, I am pleased to share some screen reader automation tooling which you can use today! 🚀

Guidepup for playwright

In this tutorial we're going to make use of the package @guidepup/playwright to write e2e tests for testing the accessibility of pages for people who use the VoiceOver screen reader for MacOS.

GitHub logo guidepup / guidepup-playwright

Screen reader driver for Playwright tests.

Guidepup Playwright

@guidepup/playwright available on NPM @guidepup/playwright test workflows @guidepup/playwright uses the MIT license

MacOS Monetary Support MacOS Ventura Support MacOS Sonoma Support Windows 10 Support Windows Server 2019 Support Windows Server 2022 Support

This package provides Guidepup integration with Playwright for writing screen reader tests that automate VoiceOver on MacOS and NVDA on Windows.

Capabilities

  • Full Control - If a screen reader has a keyboard command, then Guidepup supports it.
  • Mirrors Real User Experience - Assert on what users really do and hear when using screen readers.

Getting Started

Set up your environment for screen reader automation with @guidepup/setup:

npx @guidepup/setup
Enter fullscreen mode Exit fullscreen mode

If you are using GitHub Actions, check out the dedicated guidepup/setup-action:

- name: Setup Environment
  uses: guidepup/setup-action
Enter fullscreen mode Exit fullscreen mode

Install @guidepup/playwright to your project:

npm install --save-dev @guidepup/playwright @guidepup/guidepup @playwright/test
Enter fullscreen mode Exit fullscreen mode

Note: you require @guidepup/guidepup and @playwright/test as they are peer dependencies to this project.

And get cracking with your first screen reader tests in Playwright!

Examples

Head over to the Guidepup Website for guides, real world examples, environment setup, and complete API documentation…

The package provides a reliable set of APIs to automate your screen reader a11y workflows when using Playwright. It does this by providing both Playwright configuration as well as a custom Playwright test instance that exposes a voiceOver object for controlling VoiceOver with.

Getting setup

Let's create a new project:

npm init
Enter fullscreen mode Exit fullscreen mode

Install the @guidepup/playwright package as a dependency:

npm install @guidepup/playwright
Enter fullscreen mode Exit fullscreen mode

We'll also need Playwright as the test runner for our browser:

npm install @playwright/test
Enter fullscreen mode Exit fullscreen mode

Last but not least we'll want to test against Safari using Playwright, so let's use their tool get grab the browser:

npx playwright install webkit
Enter fullscreen mode Exit fullscreen mode

We now have all the dependencies we need! 🚀

A touch of config

Create a new playwright.config.js file:

import { voConfig } from "@guidepup/playwright";

const config: PlaywrightTestConfig = {
  ...voConfig,

  // Your custom config ...
};

export default config;
Enter fullscreen mode Exit fullscreen mode

Here we're pulling in the minimum recommended Playwright config for using Guidepup - you can check it out in the source code. This sets the number of workers to 1 and sets Playwright to use "headed" mode because when we're using VoiceOver we can only control one browser at a time (and ideally it's visible!).

We should now be completely set to get going with our first test! 🎉

Writing your first screen-reader test

Create a new file voiceover.spec.js and copy in the following contents:

// We use a special test instance from the Guidepup package
// that gives us access to VoiceOver!
import { voTest as test } from "@guidepup/playwright";
import { expect } from "@playwright/test";

// The test setup is exactly the same as normal for
// Playwright, expect we now get a `voiceOver` object as well
// as the `page` object!
test.describe("Playwright VoiceOver", () => {
  test("I can navigate the Guidepup Github page", async ({
    page,
    voiceOver,
  }) => {
    // Let's navigate to Guidepup GitHub page and wait for
    // page to be ready, nothing special here!
    await page.goto("https://github.com/guidepup/guidepup", {
      waitUntil: "domcontentloaded",
    });
    await expect(
      page.locator('header[role="banner"]')
    ).toBeVisible();

    // This is where things start to get awesome! Let's tell
    // VoiceOver to interact with the main page content, just 
    // the same as you would when use VoiceOver normally.
    await voiceOver.interact();

    // Let's do something a lil more exciting - move across
    // the page's headings until we reach the main Guidepup
    // repo title in the README using VoiceOver!
    while ((await voiceOver.itemText()) !== "Guidepup heading level 1") {
      await voiceOver.perform(
        voiceOver.keyboard.commands.findNextHeading
      );
    }
});
Enter fullscreen mode Exit fullscreen mode

Check out the comments in the code for what will happen in each part - pretty awesome huh? 🙌

Last checks before we launch

In order to automate screen-readers a few OS level settings need to be sorted first!

You can head over to the Guidepup environment setup docs for more details, but I recommend trying out the @guidepup/setup package which is designed to get you setup no faff!

npx @guidepup/setup
Enter fullscreen mode Exit fullscreen mode

You're now ready to rock! 🤘

Running your first screen-reader test

No special commands needed here, just the same as with any other Playwright test! Fire off the command then hold tight - we don't want to interact with the machine while the test is running as it might move VoiceOver's focus!

npx playwright test
Enter fullscreen mode Exit fullscreen mode

Gif over Playwright controlled Safari browser being driven with VoiceOver. Announcements read:

What's next?

To find out more there's a whole load of reading, modules, and docs - check some of these out:


Time to try out some e2e screen-reader tests?

Let me know your thoughts, questions, and opinions in the comments below!

Till next time folks 👋

Top comments (1)

Collapse
 
scottnath profile image
Scott Nath

@craigmorten FYI, I did a copypasta of the code above and discovered that voConfig is no longer the exported method from guidepup and the url (github.com/guidepup/guidepup-playw...) gives a 404 on GitHub.
Just an FYI that this article needs updating to use voiceOverTest.

Cheers and thanks for a great set of libraries!