Skip to content

Accessibility Interop Project Overview and Contribution Guidelines

Rahim Abdi edited this page Sep 20, 2024 · 35 revisions

Accessibility Interop Overview and Contribution Guidelines

Web Platform Tests (WPT) Overview

The Web Platform Tests (WPT) project is a “cross-browser test suite for the Web-platform stack”. Its main goals are described on the Web Platform Tests website:

“Writing tests in a way that allows them to be run in all browsers gives browser projects confidence that they are shipping software which is compatible with other implementations, and that later implementations will be compatible with their implementations. This in turn gives Web authors/developers confidence that they can actually rely on the Web platform to deliver on the promise of working across browsers and devices without needing extra layers of abstraction to paper over the gaps left by specification editors and implementers.”

Additional resources to learn more about WPT:

Accessibility Interop Group

The Interop Project is an integral component of WPT:

“The goal of the Interop Project is to improve the web by making it easier to make websites and web apps that work in every browser or browser engine at the same time.”

The Interop Project investigates specific focus areas (2024 Interop focus areas dashboard) and specifically, the Accessibility Interop group focuses on web platform accessibility testing.

From the accessibility-interop GitHub repo README:

“Contributors from Apple, Mozilla, Igalia, Bocoup, Adobe, Hilton, Microsoft, Google, and many more individual web developers collaborated to kickstart a continuous integration, interoperable, accessibility testing project in all major browsers. To date, this is the only known project that stands to improve the state of accessibility across the entire Web, regardless of which platform, browser, or assistive technology you may be using or testing.”

The group usually meets on the first Tuesday of the month to discuss current accessibility investigation and focus area topics, accessibility tests, yearly investigation progress and open issues.

To participate in the monthly Zoom meetings, please reach out to Simon Pieters (@zcorpan).

Related group: Accessible Rich Internet Applications (ARIA) Working Group.

Accessibility Testing Overview

Why Are We Doing This?

Prior to WPT, browser vendors primarily wrote engine-specific, internal tests to check accessibility. This sometimes resulted in inconsistent behavior between browsers, whether due to testing of different edge cases or differing interpretations of the specifications. In addition, for web developers that may be frustrated by code that should “just work”, writing engine-specific tests is an opaque, non-trivial task. For example, if an ARIA attribute is supported in all but one browser, what can a developer do to get this fixed at the browser level?

Using the WPT framework, the Interop Accessibility project enables developers to write a single automated test that runs in all major browser engines; once submitted to WPT, browser bugs can then be raised, systematically tracked and ultimately resolved in a transparent manner.

By empowering web developers to make the web more interoperable, we achieve numerous accessibility benefits:

  • Helping to build a web that accessible by default
  • Surfacing browser implementation gaps and unexpected accessibility behaviors per specifications
  • Preventing regression of accessibility bugs
  • Freeing up time spent on debugging/addressing accessibility during development

To learn more, see WebKit blog: Improving Web Accessibility with Web Platform Tests.

Web Automation Stack

At a high level, platform accessibility APIs expose browser-generated accessibility information about user interfaces (UI). This metadata (e.g., role, name, state) is then relayed to users of assistive technologies to understand the purpose and structure of UI:

web automation stack Source: https://github.com/w3c/aria/blob/main/documentation/tests.md

Browser engines have internal, engine-specific tests however, WPT facilitates cross-browser testing via WebDriver.

WebDriver & Accessibility Introspection

We’re able to write JavaScript-based tests to test accessibility-focused web platform features using the WPT infrastructure which includes:

At present, WebDriver supports the following accessors for querying accessibility object properties:

Note: See also web-platform-tests.org for additional function documentation on get_computed_label() and get_computed_role().

As part of the 2024 accessibility interop investigation, additional accessibility accessors are being explored to query more than label/role for an accessible node.

WPT Accessibility Directories

WPT contains tests for many web features/technologies and there is no single “accessibility” directory. Below are common locations for accessibility-focused tests:

WPT directory (/wpt) Tested Specifications
/accessibility Primarily accessibility crash tests (and not for testing accessibility specs)
/accname Accessible Name and Description Computation
/core-aam Core Accessibility API Mappings
/css For accessibility testing of CSS browser behavior. Currently, we only have CSS tests in wpt/css/css-display/accessibility.
/dpub-aam Digital Publishing Accessibility API Mappings
/html-aam HTML Accessibility API Mappings
/svg-aam SVG Accessibility API Mappings
/wai-aria ARIA, includes ARIA roles/states/properties. Here, you’ll also find useful ARIA utilities when writing tests (see wpt/wai-aria/scripts).

Writing WPT Accessibility Tests

Getting Started

See machine setup steps for Running WPT Tests for ARIA and Related Specs.

Example Test File Structure

Accessibility tests are simply HTML files with some data attributes that provide hooks for WPT test execution and reporting.

As an example, here’s an excerpt from the button roles test (wpt/wai-aria/role/button-role.html):

<!doctype html>
<html>
<head>
  <title>Button-related Role Verification Tests</title>
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
  <script src="/resources/testdriver.js"></script>
  <script src="/resources/testdriver-vendor.js"></script>
  <script src="/resources/testdriver-actions.js"></script>
  <script src="/wai-aria/scripts/aria-utils.js"></script>
</head>
<body>

<p>Tests <a href="https://w3c.github.io/aria/#button">button</a> and related roles.</p>

<div role="button" aria-haspopup="false" data-testname="button aria-haspopup false" data-expectedrole="button" class="ex"></div><script>
AriaUtils.verifyRolesBySelector(".ex");
</script>

</body>
</html>

Notable callouts:

  • The <title> tag serves as the page title. Usually, this is the name of the test, e.g., “Button-related Role Verification Tests”.
  • The <script> tags in the import external WPT scripts required for test execution.
  • The actual test declaration, e.g., in the example above, we have a <div role=”button”> that we’re asserting has a “button” role. Specifically, note the data-expectedrole attribute used to assert what we’re looking for, and the data-testname attribute that serves as a test descriptor.
  • The <script> block at the bottom of the <body> tag references a helpful function. Here, we’re using the ARIA utility verifyRolesBySelector() function on all elements matching the .ex selector to verify their role.

Promise Tests, Assertions & Accessibility WPT Utilities

Returning to our button example above, let’s look at this test:

<div role="button" aria-haspopup="false" data-testname="button aria-haspopup false" data-expectedrole="button" class="ex"></div>

It would be cumbersome to write WebDriver accessibility accessor functions for every HTML test file. To simplify testing efforts, what we want to do is write HTML markup, provide a test name (via data-testname) and assert some accessibility information about the DOM element (e.g., WebDriver get_computed_role() returns "button" for this example test).

Fortunately, we have ARIA helper functions available in wpt/wai-aria/scripts/aria-utils.js. Our button test uses verifyRolesBySelector() from aria-utils.js:

 /*
  Tests computed ROLE of all elements matching selector
  against the string value of their data-expectedrole attribute.
 */

  verifyRolesBySelector: function(selector, roleTestNamePrefix) {
    const els = document.querySelectorAll(selector);
    if (!els.length) {
      throw `Selector passed in verifyRolesBySelector("${selector}") should match at least one element.`;
    }
    for (const el of els) {
      let role = el.getAttribute("data-expectedrole");
      let testName = el.getAttribute("data-testname") || role; // data-testname optional if role is unique per test file
      if (typeof roleTestNamePrefix !== "undefined") {
        testName = roleTestNamePrefix + testName;
      }
      promise_test(async t => {
        const expectedRole = el.getAttribute("data-expectedrole");
        const computedRole = await test_driver.get_computed_role(el);
        assert_equals(computedRole, expectedRole, el.outerHTML);
      }, `${testName}`);
    }
  }

Notable callouts:

  • We don’t need to call the WebDriver accessibility accessors (i.e., get_computed_role(), get_computed_label()) in this test because it happens within verifyRolesBySelector() here:
const computedRole = await test_driver.get_computed_role(el);
  • For each of our tests, the ARIA utility functions use a Promise test which is a method of reliably executing code in an asynchronous manner. The important thing to note here is the assertion:
assert_equals(computedRole, expectedRole, el.outerHTML);

Note: This section is mostly informative. Besides including aria-utils.js in your test file’s <script> block, you won’t be interacting much with aria-utils.js unless new global functionality is needed to support test authoring.

Test Authoring & Best Practices

After machine setup (see “Getting Started” above), the general process for writing accessibility tests:

  • Create a new Interop Accessibility issue, or assign yourself an existing issue (e.g., from ARIA, Accessibility Interop repos). For existing issues, we suggest starting with issues tagged “good first issue”
  • Determine where the accessibility test file should reside (see “WPT Accessibility Directories” section)
  • After writing the test, submit a pull request (PR)
  • Address feedback from others and iterate on the test
  • Once approved, merge PR

Below is example HTML scaffolding that can be used as a template for new test files:

<!doctype html>
<html>
<head>
  <title>MY TEST NAME</title>
  <script src="/resources/testharness.js"></script>
  <script src="/resources/testharnessreport.js"></script>
  <script src="/resources/testdriver.js"></script>
  <script src="/resources/testdriver-vendor.js"></script>
  <script src="/resources/testdriver-actions.js"></script>
  <script src="/wai-aria/scripts/aria-utils.js"></script>
</head>
<body>
  <h1>MY TEST NAME</h1>
  <p>Tests <a href="W3C-Spec-Link">W3C SPEC HERE</a> AND SOME ADDITIONAL CONTEXT HERE.</p>

  <!-- 
     YOUR TESTS GO HERE 
  -->
  <script>
    /* 
    ARIA Utils you may need which is usually one or more of the following:

     AriaUtils.verifyLabelsBySelector(".ex-label");
     AriaUtils.verifyRolesBySelector(".ex-role");
     AriaUtils.verifyGenericRolesBySelector(".ex-generic"); 
     */
  </script>
</body>
</html>

Some helpful tips to streamline test authoring and ensure test consistency across accessibility interoperability work:

  • Validate HTML such as with the W3C’s Markup Validation Service
  • Always run tests locally (see “Test Execution” section)
  • Provide links to relevant parts of a specification or standard being tested
  • Provide comments for related/open issues as needed, e.g.,
<!-- Embedded controls tested in ./comp_embedded_control.html -->
  • Name your HTML file descriptively, e.g., aria-hidden-tested-via-label.html
  • Alphabetize tests where possible, and/or provide structure via heading tags (e.g., <h2>) to better organize tests
  • Ensure that test names supplied via data-testname are globally unique within the WPT Project. Generally, more descriptive (and verbose) test names are preferred
  • Ensure ids when referencing elements are unique (e.g., <span id=”s7”>)
  • Links without a destination can use an href value of “#”, e.g., <a href=”#”>
  • Images without a URL source can use a src value of src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==
  • For PRs
    • PRs should use descriptive names, e.g., “display: contents accessibility tests”
    • Ensure all PR checks have passed which includes a lint check, e.g.,: All pull request checks have passed

It’s strongly encouraged to take a look at past accessibility tests (see “WPT Accessibility Directories” section) to familiarize yourself with existing tests, testing approaches, test file structure and general inspiration!

Test Execution & Viewing Results

WPT supports a robust continuous integration (CI) environment maintained by W3 members. This means that tests pushed to the WPT repo are automatically run and published to the live WPT dashboard so results can be seen in real-time across the latest, publicly released browser engines.

Please see below for a high-level overview of WPT and how tests interact with the WPT infrastructure: WPT infrastructure overview

Tests are executed in two ways:

  1. Running WPT tests locally - Tests are executed in your terminal using the following wpt command:
./wpt run --log-mach-level debug --log-mach - --webdriver-arg="--diagnose" <BROWSER> <FILE PATH>

For example, the following browser-specific commands run the existing name calculation test (https://github.com/web-platform-tests/wpt/blob/master/accname/name/comp_label.html); note the parameters at the end of the command specifying the browser engine to use for execution and test file path:

Safari:

./wpt run --log-mach-level debug --log-mach - --webdriver-arg="--diagnose" safari /Desktop/wpt/accname/name/comp_label.html

Chrome:

./wpt run --log-mach-level debug --log-mach - --webdriver-arg="--diagnose" chrome /Desktop/wpt/accname/name/comp_label.html

Firefox:

./wpt run --log-mach-level debug --log-mach - --webdriver-arg="--diagnose" firefox /Desktop/wpt/accname/name/comp_label.html

Note: As part of executing WPT tests locally, depending on the browser, you may be prompted within the CLI to download the associated webdriver.

  1. Pushing commits to the WPT remote repository - Push a commit to your test branch and view the test results using the PR checks (such as the pull request’s “Checks” tab under “wpt.fyi” checks). For example: WPT test PR check page

Troubleshooting

The following are common error messages when running tests locally:

  • Duplicate test names” - Ensure every data-testname attribute has a globally unique description of the test.

  • Selector passed in verify…() should match at least one element” - This error will occur if you use an invalid or non-existent class name in your test. Verify that the spelling of the class in your test matches the spelling of the selector in your JavaScript.

  • Action get_computed_label/get_computed_role failed” - This is usually a result of malformed HTML. Ensure that the HTML markup is valid, well-formed, elements are nested appropriately and start/end tags are used (where required). Performing HTML validation is strongly recommended.

  • Expected (object) null but got…” - This error can occur if the test contains malformed data attributes. Ensure that all aria-utils.js data-* attributes are expected values and spelled correctly, namely: data-testname, data-expectedlabel, data-expectedrole.

FAQs

Q: How can I contribute? Where can I find open tests or the current test backlog?

A: Accessibility interop work relies on contributions from individuals and browser vendors. Your support is needed and welcome!

From the Accessibility Interop repo:

If you're interested in contributing or learning more, start by reviewing the open issues list, or reviewing an open pull request.

Q: What aspects of accessibility interoperability are currently testable with WPT?

A: WPT uses WebDriver for querying accessibility information about DOM elements. At present, this is limited to an element’s label or role (see “WebDriver & Accessibility Introspection” section).

Q: Besides role and label, when will other WebDriver accessibility accessors be available?

A: This is being explored as a priority for 2024 accessibility interop work. Discussion on this can be found in AOM #203.

Q: I’m writing a test for which there are no existing related tests. Where do I put it?

A: Please check with Accessibility Interop members (mainly James Craig (@cookiecrook) to ensure it’s appropriately located.

Q: Do I need to run tests locally since tests pushed to the WPT repo are executed automatically and results subsequently published to the WPT reporting dashboard (wpt.fyi)?

A: Yes, always run tests locally for several reasons:

  • it reduces CI resource usage
  • allows you to see diffs between local and CI execution results
  • allows instant test execution without pushing commits

Q: I’m writing a test and getting a CLI error. How can I troubleshoot it?

A: See “Writing WPT Accessibility Tests - Troubleshooting” section.

Q: I need to test something that isn’t available via aria-utils.js. What should I do?

A: There may be instances where a test requires additional test-specific logic unavailable in aria-utils.js (e.g., a function that walks a DOM tree and verifies a property for an element’s ancestors). As done across other WPT work, this extra functionality can be added directly in the file’s <script>. If you think the functionality should be made available as a global utility, please raise an issue or reach out to an Accessibility Interop member.

Q: Accessibility interop work seems to focus on assistive technology accessibility. What about testing other aspects of web accessibility, e.g., the visual or keyboard experience?

A: The group is currently investigating keyboard accessibility testing as part of interop-accessibility #101. If you have additional ideas to expand testing coverage, please let us know!

Q: Besides assert_true() and assert_false(), what other assert functions does WPT provide?

A: See web-platform-test.org’s testharness.js page on “Assert” functions.

Clone this wiki locally