Created
October 13, 2020 20:30
-
-
Save WestonThayer/f08d9c1162e4a1a68e1cfe8f24ff9837 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// All tests visiting a page with this HTML: | |
// | |
// <p>content before</p> | |
// | |
// <ol id="target"> | |
// <li> | |
// Cats | |
// <ol> | |
// <li>Big cat</li> | |
// <li>Small cat</li> | |
// </ol> | |
// </li> | |
// <li> | |
// Dogs | |
// </li> | |
// <li> | |
// Birds | |
// </li> | |
// </ol> | |
// <p>content after</p> | |
// Approach 1 - play 100% the end user | |
// | |
// Pros - very straightforward | |
// Cons - brittle, will break on simple speech output changes. Each AT would | |
// need its own test script. Focus on speech output excludes braille. | |
const nvda = startNvda(); | |
// Start Firefox — this could easily be a utility call, just playing around here | |
keyboard.keys.Win.hit(); | |
nvda.speech.waitForOutput("Windows search"); | |
keyboard.type("firefox"); | |
nvda.speech.waitForOutput("Firefox"); | |
keyboard.keys.Enter.hit(); | |
nvda.speech.waitForOutput("Focus on address bar, autocomplete"); | |
keyboard.type("https://mytestsite.com"); | |
keyboard.keys.Enter.hit(); | |
nvda.speech.waitForOutput("Document loaded"); | |
keyboard.keys.ArrowDown.hit(); | |
nvda.speech.waitForOutput("content before"); | |
keyboard.keys.ArrowDown.hit(); | |
nvda.speech.waitForOutput("list, 3 items, 1. Cats"); | |
// etc, keep arrowing down | |
nvda.speech.waitForOutput("out of list"); | |
// Approach 2 - play the end user, but deal in OS accessibility tree nodes | |
// | |
// Pros - abstracts enough to easily sub in different ATs without changing code | |
// Cons - harder to understand, mental model needs to include understanding of | |
// OS a11y tree, really tough questions around AT "meta output", like | |
// when the AT is announcing the boundaries of an a11y tree node, instead | |
// of just describing the node itself | |
const sr = startScreenReader("nvda"); | |
const tree = getOsA11yTree(); | |
const browser = startApp("C:\\Program Files\\Firefox\\firefox.exe"); | |
const browserNode = tree.findNode((node) => { | |
if (node.role === Roles.Window && node.name.contains("Firefox")) { | |
return true; | |
} | |
return false; | |
}); | |
// Focus address bar | |
sr.focus( | |
browserNode.findNode( | |
(node) => | |
node.role === Roles.EditText && node.name.contains("enter address") | |
) | |
); | |
keyboard.type("http://mytestsite.com"); | |
keyboard.keys.Enter.hit(); | |
const documentNode = browserNode.findNode( | |
(node) => node.role === Roles.Document && node.name === "My Test Page" | |
); | |
const startNode = documentNode.findNode( | |
(node) => node.role === Roles.Text && node.name === "content before" | |
); | |
sr.focus(startNode); | |
expect(sr.describeFocusedNode().name).toBe("content before"); | |
// Navigate through the list | |
sr.navigateUntil( | |
documentNode.findNode((node) => node.name === "content after") | |
); | |
const output = sr.getOutputCollection(); | |
// This is where it gets really tricky — to have the same lines of code work for | |
// NVDA, JAWS, VoiceOver, etc, we need some sort of abstraction for speech | |
// output that categorizes it. In this case, BOUNDARY_EXIT is a type of output. | |
// Other types could include NODE_DESC for announcing a node's role, name, and | |
// possible value. | |
// | |
// But it'll be a lot of work to wrangle all the ATs like this. I don't know how | |
// they tag output under the hood | |
expect(output[output.length - 1]).toBe({ | |
type: "BOUNDARY_EXIT", | |
boundaryNodeRole: "list", | |
}); | |
// Alternatively, could just hardcode expected output from every AT | |
expect(output[output.length - 1]).toBeIn([ | |
"out of list", | |
"exiting list", | |
"end of list", | |
]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment