Write Selenium Tests

Link to Write Selenium Tests copied to clipboard

Use axe DevTools Java Selenium

This axe DevTools configuration does not inherently bind to any assertion library. This allows for simple accessibility testing as well as full test customization and use with custom assertions.

Prerequisites

In order to use axe DevTools Java Selenium and produce results with it, you must have already created a test file with axe DevTools and have your choice of Selenium WebDriver imported & initialized. If you haven't completed this step, first read this guide on how to do so.

Run a Scan

With this configuration, running a basic accessibility scan requires only three lines of code. In your test file, replace <URL> with the desired web address of the page you want to test. The scan results are saved in the results variable

webdriver.get("<URL>");
Results results = axeSelenium.run(axedriver);
webdriver.quit();

Using the Scan Results

Once you've run the scan, you may want to do something with the results. The simplest option is to print the results to the console.

System.out.print(results);

You can also use the results to check for accessibility violations. The simplest way to do this is with a statement like this:

if (!results.violationFree()) { 
    //do something, like throw an exception
}

For more information on how to utilize the results object to write custom tests, see the page on using the results.

Sample Test File

This test file works with the same building blocks covered in import and initialize as well as the writing tests guide on this page.

import com.deque.html.axedevtools.selenium.*;
import com.deque.html.axedevtools.selenium.results.*;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class Example {
    public static void main(final String[] args) {
        AxeSelenium axeselenium = new AxeSelenium();
        WebDriver webdriver = new ChromeDriver();
        AxeDriver axedriver = new AxeDriver(wd);

        webdriver.get("<URL>");

        Results results = axeselenium.run(axedriver);

        webdriver.quit();

        if (!results.violationFree()) {
            int violationCount = results.getViolations().size();
            System.out.printf("Found %d violations!\n", violationCount);
            System.exit(1);
        }

        System.out.println("No violations found!");
    }
}

In this example, Chrome and ChromeDriver are used. This can be substituted to any other selenium browser driver and browser. If this test file finds any accessibility issues, it prints out the number of found violations and exits with status code 1 (error). To use this test file in your own environment, you will have to add a URL to the line

webdriver.get("<URL>");

Additional Reference

In addition to the basic usage outlined above, axe DevTools Java Selenium provides several chaining methods to modify the way the scan is run. These methods can modify the scan's scope and ruleset to any desired configuration. By default, the entire page is scanned and checked for accessibility violations according to WCAG 2.0 level AA guidelines. An important note is that subsequent calls to the run method will overwrite any of the chain methods' preferences below. Changes made to scope or rules do not persist to multiple scans using these chan methods.

Scoping

By default, the entire page is scanned. However, axe DevTools supports the ability to scan specific portions of a page with its scoping chain methods. These scoping methods effectively change the "surface area" of the page to be scanned to the desired target area(s). Additionally, an ignore violations method is available. "Scoping" the page with this method doesn't reduce the area of the scan, but it will ignore violations of a specified type within the specified area and still scan the area for other potential violations. All of these methods work based on CSS selector areas. The area of each CSS selector on a given page can be determined by using the "inspect element" widget of your browser's developer tools.

Scoping Methods

As explained above, these methods effectively change the surface area of the page to be scanned. There are two methods in this category, an "inclusive" method and an "exclusive" method. They can be mutually chained with each other to create multiple enclaves and exclaves of scanning surface area.

Scoping - Including

The including scoping chain method alters the scan to only run within the page area specified by the CSS selector(s) passed to it. There are several ways to use the including method: single scope, multiple scope, compound scope, and IFrame scoping.

This method can be used with a single selector as follows:

axeselenium.including("#selector1").run(axedriver);

This scan will only run within the scope of selector 1

You can set up a scan with multiple scopes:

axeselenium.including("#selector1").including("#selector2").run(axedriver);

This call will scan within the scope of selector 1 and selector 2. They can either be comma separated or declared in a separate including clause.

Compound scoping can be accomplished with the following syntax:

axeselenium.including("#selector1 .selector2").run(axedriver);

This compound scoping results in only elements with selector 2 within selector 1 being scanned. This is set up by not comma separating the selectors.

In order to scope within an IFrame, a List<String> can be passed. The scope to be scanned within the IFrame is passed in as an additional parameter.

axeselenium.including(Arrays.asList(new String[] {"#frame1", "#selector1"})).run(axedriver);

This scan runs on elements within selector 1, which is inside of frame 1.

Scoping within multiple IFrames works the same way as standard multiple selection. Simply call including again.

axeselenium.including(Arrays.asList(new String[] {"#frame1", "#selector1"}))
    .including(Arrays.asList(new String[] {"#frame2", "#selector2"})).run(axedriver);

This scan runs only inside of selector 1 within frame 1, and selector 2 inside frame 2.

It is also possible to scope within nested IFrames:

axeselenium.including(Arrays.asList(new String[] {"#frame1", "#frame2", "#selector1"})).run(axedriver);

This scan runs within the scope of selector 1 inside of frame 2, which is itself inside frame 1

Scoping - Excluding

In addition to the including chain method, this API has an excluding method. This method alters the scan so that only elements outside of the specified scope will be scanned. Its setup and usage is identical to the including method, so refer to the above section for more details and examples of how it can be used. One important detail to remember is that the including and excluding methods can be chained with each other to create complex scopes much more simply than by only using include or exclude.

This example shows one such way to pair the within and excluding methods:

axeselenium.including("#selector1").excluding("#selector2").run(axedriver);

This scan runs only on the part of the page that is within selector 1 that is not also within selector 2.

Scoping - Ignoring Violations

The final scoping related chain method is the ignoring results method. This method doesn't alter the overall scope of the scan, but will ignore violations of a specified type within a specified scope. It works by passing the selector(s) of the element(s) you want to ignore as an array, coupled with the rule they violate.

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

This scan will ignore color contrast violations within the sidebar section and the branded-content section.

Rules

There are three ways to modify your rule configuration for each scan. These different methods allow for different granularity when selecting a rules to test against. The least granular ruleset method selects a ruleset, or larger group of rules based on the common accessibility standards. The slightly more granular ruleset standards method, also known as tags, selects rules based on which areas of a larger accessibility standard they fall within. Finally, there are three options for configuration with one rule at a time. All together, these chain methods allow you to tune your scan to run precisely the rules you want.

For information on axe-core rules, visit the ruleset overview page.

Ruleset Selection

This method selects rules by their most aggregated association - a ruleset. A ruleset is a collection of all the rules which pertain to an industry wide accessibility standard. Rulesets for WCAG 2.0, 2.1, and 2.2; ADA Section 508; Trusted Tester v5; and EN 301 549. Additionally, best practice rules can be enabled with a boolean flag.

Rulesets are often comprised of multiple tags, which are rules grouped by more specific distinctions. For example, the wcag2 ruleset contains all rules tagged wcag2a WCAG 2.0 level A rules, wcag2aa for WCAG 2.0 level AA rules, and wcag2aaa for WCAG 2.0 level AAA rules.

Use this option when you want to select a ruleset unmodified.

axeselenium.forRuleset("wcag2.1").run(axedriver);

This scan will be run with only WCAG 2.1 rules.

To enable best practice rules, use the second form of forRuleset.

axeselenium.forRuleset("wcag2.1", true).run(axedriver);

Standard Selection

The accessibility standard, or tag, chain method allows slightly more granularity within axe-core's rulesets. For WCAG based rules, this method allows you to select only rules tagged single-A or double-A. This list breaks down the available tag names and their corresponding standards.

This option is particularly useful when only testing a specific portion a ruleset, for example, only the single A rules under WCAG 2.0.

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

While not defined explicitly as a part of any accessibility standard, we offer a number of rules we call "best practices." While not strictly necessary, testing with these rules will help your website be as equitable in use as possible.

A single standard can be selected as follows:

axeselenium.accordingTo("wcag2a").run(axedriver);

This scan will run with only rules tagged under WCAG 2.0 level A

Additionally, multiple tags can be specified to select multiple accessibility standards:

axeselenium.accordingTo("wcag2a", "section508").run(axedriver);

These scans will run both the rules tagged under WCAG 2.0 level A and ADA Section 508.

Rule Selection

Finally, you can alter your ruleset by a single rule. For information on the names of all of axe-core's rules and what each rule tests for, see the axe-core rule descriptions documentation.

These methods work well when your desired final group of rules is only differnet from an existing ruleset or standard/tag by a few individual rules. To build a completly customized ruleset, check out our custom rule options.

Checking Additional Rules

The checking chain method allows you to add additional rules to test with in addition to your standard ruleset.

This method can be used to check a single additional rule:

axeselenium.checking("label").run(axedriver);

where the scan is run with the default ruleset in addition to the "label" rule.

It can also be used to check multiple additional rules in two different ways:

axeselenium.checking("label", "tabindex").run(axedriver);
axeselenium.checking("label").checking("tabindex").run(axedriver);

where the scan is run with the default ruleset in addition to the "label" and "tabindex" rules.

It can also be used to add a single, or multiple, rules to a specified tag:

axeselenium.accordingTo("wcag2a").checking("tabindex").run(axedriver);

where the scan is run testing against WCAG 2.0 level A rules, with the addition of the "tabindex" rule.

Skipping Rules

Similar to the checking method, the skipping method changes the default rules to be used by the rule(s) specified. However, instead of adding it to the ruleset, the skipping method removes the specified rule(s) from those used to test the page. Its setup and usage is identical to the checking method, so refer to the above section for more details and examples on how to use it. One important detail to remember is that the checking and skipping methods can be chained with each other to create customized rulesets much more simply than by using only the ignoring or checking methods alone.

axeselenium.accordingTo("wcag2a").checking("tabindex").skipping("label").run(axedriver);

This example shows a scan testing against WCAG 2.0 level A rules, with the addition of the "tabindex" rule and the removal of the "label" rule.

Checking Only

The checking only method checks only the rule(s) specified. Any rule not explicitly specified will not be included in the scan.

This chain method can be used to specify a single rule:

axeselenium.checkingOnly("tabindex").run(axedriver);

where the scan is run with only the "tabindex" rule.

It can also be used to specify more than one rule in these two ways:

axeselenium.checkingOnly("label", "tabindex").run(axedriver);
axeselenium.checkingOnly("label").checkingOnly("tabindex").run(axedriver);

where the scan is run with only the "label" and "tabindex" rules.

Disabling iframe Testing

On volatile pages, iframes can cause issues. Axe needs to be injected into every frame and configured the same way in each frame. If iframes are added or removed while AxeSelenium::run is testing your page, it is possible for exceptions to be thrown or unexpected behavior to occur. As a failsafe, AxeSelenium exposes a method to disable all iframe interaction, AxeSelenium::disableIframeTesting. When enabled, axe-core will not be injected into iframes in the page, nor will it be run in said iframes. Only the top-level page will be checked.

It can be used like so:

axeselenium.disableIframeTesting().run(axedriver);
note

The use of this method is not recommended. It is always better to wait for your page to become stable before passing it to AxeSelenium::run.

Usage Service

Gain insight into axe DevTools usage trends within your organization

The usage service can be configured through enviornment variables, or methods at runtime. When both are used, the values in the methods are used. Note: not all usage service data fields can be set through methods.

By default the usage-service is disabled and the default url results are sent to 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

Enable Tracking

This method allows users to opt in or out of sending data to the usage service

.enableTracking(boolean state)

Set Tracking Url

This method allows users to change where the usage metrics data are being sent to. Defaults to https://usage.deque.com

.setTrackingUrl(String url)

Set Distinct ID

This method allows users to change the distinct id being stored/used

.setDistinctId(String distinctId)

Next Steps

Once you are writing tests with axe DevTools, read more about using results to write more detailed custom tests, or read about using the reporter to generate reports of the accessibility scans.

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.