Skip to content

Instantly share code, notes, and snippets.

@WestonThayer
Created July 11, 2025 21:36
Show Gist options
  • Select an option

  • Save WestonThayer/a23b88107bb6acc9113e860b7fcd23f8 to your computer and use it in GitHub Desktop.

Select an option

Save WestonThayer/a23b88107bb6acc9113e860b7fcd23f8 to your computer and use it in GitHub Desktop.
Guidepup example with Playwright - download as zip

Follow along at https://assistivlabs.com/articles/automating-screen-readers-for-accessibility-testing

Requirements

  • A Windows PC (or virtual machine)
  • Node.js

Instructions

  1. Download this Gist as a zip on Windows
  2. From a Node.js command prompt in the unzipped folder...
    1. npm install
    2. npx playwright install chromium
    3. npx @guidepup/setup (this will install a special copy of NVDA along with some registry changes)
    4. npx playwright test

Note that NVDA is not configured to vocalize, you may hear some beeps during the test only.

// @ts-check
import { nvdaTest as test } from "@guidepup/playwright";
import { WindowsKeyCodes, WindowsModifiers } from "@guidepup/guidepup";
import { expect } from "@playwright/test";
import delay from "delay";
test("I can navigate the Guidepup Github page", async ({ page, nvda }) => {
// 1. Loads https://www.guidepup.dev
await page.goto("https://www.guidepup.dev");
// this means delay until the h1 is visible
await page.locator("h1").waitFor();
await delay(500);
// Tell NVDA to focus on the browser (instead of elsewhere in the OS)
// Make sure NVDA is not in focus mode.
await nvda.perform(nvda.keyboardCommands.exitFocusMode);
// Ensure application is brought to front and focused.
await nvda.perform(nvda.keyboardCommands.reportTitle);
let windowTitle = await nvda.lastSpokenPhrase();
let applicationSwitchRetryCount = 0;
while (!windowTitle.includes("Chromium") && applicationSwitchRetryCount < 10) {
applicationSwitchRetryCount++;
await nvda.perform({
keyCode: [WindowsKeyCodes.Escape],
modifiers: [WindowsModifiers.Alt],
});
await nvda.perform(nvda.keyboardCommands.reportTitle);
windowTitle = await nvda.lastSpokenPhrase();
}
// Clear out logs.
await nvda.clearItemTextLog();
await nvda.clearSpokenPhraseLog();
// 2. Read the page's 4 headings
let headingCount = 0;
const expectedHeadings = [ // NVDA announcements
"main landmark, Guidepup, heading, level 1",
"Reliable Automation For Your Screen Reader A 11y Workflows Through Java Script, heading, level 2",
"Full Control, heading, level 3",
"Mirrors Real User Experience, heading, level 3",
"Framework Agnostic, heading, level 3",
];
while (
!(await nvda.lastSpokenPhrase()).includes("Framework Agnostic") &&
headingCount <= 10
) {
await nvda.perform(nvda.keyboardCommands.moveToNextHeading);
expect(await nvda.lastSpokenPhrase()).toBe(expectedHeadings[headingCount]);
headingCount++;
}
// 3. Reads the "Get Started and GitHub" links (above the footer)
let nextCount = 0;
const expectedContent = [
"Run with Jest, with Playwright, as an independent script, no vendor lock in.",
"link, Get Started",
"link, Git Hub",
];
while (
!(await nvda.lastSpokenPhrase()).includes("Git Hub") &&
nextCount <= 10
) {
await nvda.next();
expect(await nvda.lastSpokenPhrase()).toBe(expectedContent[nextCount]);
nextCount++;
}
// 4. Invokes the "Get Started" link
await nvda.previous();
await nvda.act();
});
{
"name": "demo",
"private": true,
"dependencies": {
"@guidepup/playwright": "^0.14.2",
"@playwright/test": "^1.54.1",
"delay": "^6.0.0"
}
}
// @ts-check
import { devices, defineConfig } from "@playwright/test";
export default defineConfig({
testDir: ".",
/**
* We can only run a single instance of Screen Readers, so we must run a
* single test at a time.
*/
workers: 1,
/**
* We can't parallelize Screen Reader tests as they are singletons, you can't
* start multiple instances at once.
*/
fullyParallel: false,
reportSlowTests: null,
timeout: 5 * 60 * 1000,
projects: [
{
name: "chromium",
use: {
...devices["Desktop Chrome"],
// Screen Readers don't work against headless browsers.
headless: false
},
},
],
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment