Write Hamcrest Tests

Link to Write Hamcrest Tests copied to clipboard

Using Hamcrest Matchers with axe DevTools

Prerequisites

In order to write accessibility tests and produce results, you must have already created a test file with axe DevTools and your choice of Selenium WebDriver pre-imported & pre-initialized. If you haven't done this yet, read this guide on how to do so.

A set of matchers have been provided for accessibility testing through hamcrest using Selenium WebDriver. These matchers can be used in a unit testing framework, or in custom cucumber steps.

Choosing a scanning method

As seen in the import statements, there are two accessibility scanning methods. The first, isAxeClean, will throw an exception and stop the tests if any violations are found. The second, isAuditedForAccessibility, won't stop the tests or throw an exception regardless of the accessibility level of the scanned page.

Writing Tests

For the remaining examples, the isAxeClean method is shown for brevity, but both methods work interchangeably. With your WebDriver and AxeDriver objects instantiated and initialized creating a scan is as simple as adding these two lines of code to a test method. Replace $URL with the desired URL of the page you wish to scan.

webDriver.get("$URL");
assertThat(axedriver, isAxeClean());

When testing multiple pages, you can repeat the get, scan process without having to create new instances of the drivers. In order to scan different states of a page, you can manipulate the page using the webdriver API and then run a new scan.

Additional Reference

Several chaining methods are available to modify the way the page is scanned. These methods include exclusion/inclusion clauses or scoping and modifications of accessibility standards, accessibility rules, and accessibility rulesets. For brevity, all chain methods are coupled with isAxeClean(), but they are interchangeable with isAuditedForAccessibility().

Accessibility Standards

Deque offers a chain method, according to, which can directly specify what accessibility testing standards are used by a scan.

Tag Name Accessibility Standard
wcag2a WCAG 2.0 Level A
wcag2aa WCAG 2.0 Level AA
wcag2aaa WCAG 2.0 Level AAA
wcag21a WCAG 2.1 Level A
wcag21aa WCAG 2.1 Level AA
wcag21aaa WCAG 2.0 Level AAA
wcag22a WCAG 2.2 Level A
wcag22aa WCAG 2.2 Level AA
wcag22aaa WCAG 2.2 Level AAA
section508 Section 508
EN-301-549 EN 301 549
TTv5 Trusted Tester v5
best-practice Best practices endorsed by Deque

If you aren't sure which standard is for you, read the axe-core documentation on which rules are associated with which standard, or contact us through your Deque representative or our help desk. For a full list of which rules apply to each standard, view this page on Rule Descriptions

To use a single standard, simply add the according to chain method and pass in your desired standard

assertThat(axedriver, isAxeClean().accordingTo("wcag2a"));

In addition to using one testing standard, there are two ways to scan against two or more testing standards. Both work identically.

assertThat(axedriver, isAxeClean().accordingTo("wcag2a", "section508"));
assertThat(axedriver, isAxeClean().accordingTo("wcag2a").accordingTo("section508"));

Scoping

Deque offers two chained methods to assist in scoping scans. The within() method alters the scan to only scan the page within the bounds of the selector passed to it. The excluding() method works the opposite way. It alters the scan to ignore content within the selector passed into it. The below examples all show the within() method, but the excluding() method works identically.

Most simply, the assertion is modified with one selector

assertThat(axedriver, isAxeClean().within("#selector1")); 

Compound selectors are also possible. In the below example, only elements with selector 2 within selector 1 are scanned

assertThat(axedriver, isAxeClean().within("#selector1 .selector2"));

There are three ways to accomplish multiple selection, or selecting multiple scopes to test within. In all of these examples, elements within selector 1 and selector 2.

assertThat(axedriver, isAxeClean().within("#selector1, .selector2"));
assertThat(axedriver, isAxeClean().within("#selector1", ".selector2"));
assertThat(axedriver, isAxeClean().within("#selector1").within(".selector2"));

In order to scope within an IFrame, an IFrame selector must be declared. The scope to be scanned within the IFrame is passed in as an additional parameter.

assertThat(axedriver, isAxeClean().within(new IFrameSelector("#frame1", "#selector1")));

Scoping within multiple IFrames works the same way as standard multiple selection. Simply create two or more IFrame selectors separated by commas.

assertThat(axedriver, isAxeClean().within(new IFrameSelector("#frame1", "selector1"), 
        new IFrameSelector("#frame2", "#selector2")));

It is also possible to scope within nested IFrames. This example shows scoping a scan within selector 1 of an IFrame which is inside a second IFrame.

assertThat(axedriver, isAxeClean().within(
    new IFrameSelector("#frame1",
    new IFrameSelector("#frame2", "#selector1"))));

Finally, it is possible to set multiple scopes within a page as well as within an IFame. For this to work, an element selector object is required.

assertThat(axedriver, isAxeClean().within(
    new ElementSelector("#selector1"),
    new ElementSelector("#selector2"),
    new IFrameSelector("#frame", "selector3")));

Rule Selection

The API also offers the ability to modify which rules are used in a scan. There are three ways to modify which rules are used. These are checking additional rules outside of the standard ruleset for the scan, not checking rules within the standard ruleset for the scan, and checking only those rules explicitly specified.

For a complete list of the valid rule tags you can use with these methods and what they test for, read the documentation on rules

In order to check additional rules, use the checking method. To test a single additional rule, just pass the rule label into the checking method

assertThat(axedriver, isAxeClean().checking("label"));

Similar to the other chain methods, multiple additional rules can be checked with the checking method two ways:

assertThat(axedriver, isAxeClean().checking("label", "tabindex"));
assertThat(axedriver, isAxeClean().checking("label").checking("tabindex"));

The checking method can be chained with a rule selection method as well.

assertThat(axedriver, isAxeClean().accordingTo("wcag2a").checking("tabindex"));

The option also exists to omit rules from a scan. This is possible through the skipping method. It works identically to the checking method except that it leaves rules out instead of adding them.

assertThat(axedriver, isAxeClean().skipping("label"));

It can also be used to omit multiple rules.

assertThat(axedriver, isAxeClean().skipping("label", "tabindex"));
assertThat(axedriver, isAxeClean().skipping("label").skipping("tabindex));

Finally, it can be used with a rule selection method as well.

assertThat(axedriver, isAxeClean().accordingTo("wcag2a").skipping("#label"));

The last method is used when only specific rules are wanted. The checking only method modifies the scan to check only those rules explicitly passed into it. Additionally, this method will not chain with the accessibility standards selection method. To check only a single rule:

assertThat(axedriver, isAxeClean().checkingOnly("label"));

This method can also be used to check multiple rules in two ways.

assertThat(axedriver, isAxeClean().checkingOnly("label", "tabindex"));
assertThat(axedriver, isAxeClean().checkingOnly("label").checkingOnly("tabindex"));

For a complete list of the valid rule tags you can use with this methods and what they test for, read the documentation on rules.

Ignoring Violations

It is possible to configure the scan to ignore specific instances of violations. In order to do this, the ignoring method is used. It works by passing the selector(s) of the element(s) you want to ignore as an array, coupled with the rule they violate.

assertThat(axedriver, isAxeClean().ignoring("[\".sidebar\", \"#branded-content\"]", "color-contrast"));

Usage Service

Gain insight into axe DevTools usage trends within your organization

By default the usage-service is disabled and the default url is https://usage.deque.com.

Environment variables

This method allows users to change specific values of the usage service via environment variables

Environment Variable Type Description
AXE_IS_LOGGED_IN Boolean Whether the user is logged in to the app under test
AXE_KEYCLOAK_ID String The keycloak id of the logged in user
AXE_USER_ID String The name of the user running the test
AXE_SESSION_ID String Description of the test session
AXE_USER_STATUS String The status of the user
AXE_USER_JOB_ROLE String The title/role of the individual performing the test
AXE_DISTINCT_ID String An individual user's distinct ID
AXE_IS_DEV_INSTANCE Boolean Whether the app under test is in a dev instance
AXE_ORGANIZATION String The user's organization - organizing data on a company wide scale
AXE_APPLICATION String The name of the application under test
AXE_METRICS_URL String The URL to which usage data is sent
AXE_TRACK_USAGE Boolean Whether or not usage data is being captured

Next Steps

For further use of your axe DevTools scan results, like reporting, see the axe DevTools Java Selenium package documentation

Troubleshooting

If you experience issues setting up your accessibility testing, contact your Deque representative directly, reach us via our support desk, or send us an email. We're happy to help get your accessibility testing efforts off the ground.