Accessibility testing using the axe-core library
A guide to running accessibility tests in BrowserStack Automate using the axe-core open source library
This document provides you with the step-by-step process to verify if your website follows the WCAG and other guidelines (as supported by axe-core library), ensuring your website is accessible to all types of users on the Internet. Axe is a fast and lightweight accessibility testing tool that checks the entire document against the rules and generates a report with all violations, passes, etc.
In this guide, you will learn:
Pre-requisites
Before you can integrate your tests with BrowserStack and generate reports using the axe-core library, ensure that the following pre-requisites are complete:
Run your first accessibility test
The following sample script opens the file you downloaded in the pre-requisite step and injects the axe.min.js
script in the DOM of the website under test. After that, using a Javascript Executor, the accessibility checks are invoked using the axe-core library. The generated report is saved in a JSON file as per the path provided in the script.
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.MutableCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
public class test{
public static final String AUTOMATE_USERNAME = "YOUR_USERNAME";
public static final String AUTOMATE_ACCESS_KEY = "YOUR_ACCESS_KEY";
public static final String URL = "https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub";
public static void main(String[] args) throws Exception {
MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserName", "Chrome");
capabilities.setCapability("browserVersion", "103.0");
HashMap<String, Object> browserstackOptions = new HashMap<String, Object>();
browserstackOptions.put("os", "Windows");
browserstackOptions.put("osVersion", "10");
browserstackOptions.put("projectName", "BStack Accessibility Test");
browserstackOptions.put("buildName", "BStack Accessibility Sample Build");
capabilities.setCapability("bstack:options", browserstackOptions);
WebDriver driver = new RemoteWebDriver(new URL(URL), caps);
driver.get("https://www.google.com");
JavascriptExecutor jse = (JavascriptExecutor)driver;
Path path = Paths.get("path/to/axe.min.js");
String content = new String(Files.readAllBytes(path));
jse.executeScript(content);
File output = new File("path/to/report.json");
FileWriter writer = new FileWriter(output);
String result = String.valueOf(jse.executeAsyncScript("var callback = arguments[arguments.length - 1]; axe.run().then(results => callback(results));"));
Gson g = new Gson();
String p = g.toJson(result);
writer.write(p);
writer.flush();
writer.close();
driver.quit();
}
}
Copy icon
Copy
const webdriver = require('selenium-webdriver');
const fs = require('fs')
// Input capabilities
var capabilities = {
'bstack:options' : {
"os" : "Windows",
"osVersion" : "10",
"projectName" : "BStack Accessibility Test",
"buildName" : "BStack Accessibility Sample Build",
"userName" : "YOUR_USERNAME",
"accessKey" : "YOUR_ACCESS_KEY",
},
"browserName" : "Chrome",
"browserVersion" : "103.0",
}
async function runAccessibilityTest () {
let driver = new webdriver.Builder()
.usingServer('https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub')
.withCapabilities(capabilities)
.build();
await driver.get("https://www.google.com");
const data = await fs.readFileSync('path/to/axe.min.js', 'utf8')
await driver.executeScript(data.toString());
let result = await driver.executeAsyncScript('var callback = arguments[arguments.length - 1];axe.run().then(results => callback(results))');
await fs.writeFileSync('path/to/report.json', JSON.stringify(result));
await driver.quit();
}
runAccessibilityTest();
Copy icon
Copy
using System;
using System.IO;
using Newtonsoft.Json;
using OpenQA.Selenium.Remote;
namespace SeleniumTest
{
class Program
{
static readonly string axe = @"/path/to/axe.min.js";
static readonly string report = @"/path/where/you/want/to/save/report.json";
static void Main(string[] args)
{
RemoteWebDriver driver;
ChromeOptions capabilities = new ChromeOptions();
capabilities.BrowserVersion = "103.0";
Dictionary<string, object> browserstackOptions = new Dictionary<string, object>();
browserstackOptions.Add("os", "Windows");
browserstackOptions.Add("osVersion", "10");
browserstackOptions.Add("projectName", "BStack Accessibility Test");
browserstackOptions.Add("buildName", "BStack Accessibility Sample Build");
browserstackOptions.Add("userName", "YOUR_USERNAME");
browserstackOptions.Add("accessKey", "YOUR_ACCESS_KEY");
browserstackOptions.Add("browserName", "Chrome");
capabilities.AddAdditionalOption("bstack:options", browserstackOptions);
driver = new RemoteWebDriver(
new Uri("https://hub-cloud.browserstack.com/wd/hub/"), capability
);
driver.Navigate().GoToUrl("https://www.google.com/");
if (File.Exists(axe))
{
string axeCode = File.ReadAllText(axe);
driver.ExecuteScript(axeCode);
IJavaScriptExecutor javascriptExecutor = (IJavaScriptExecutor) driver;
string result = JsonConvert.SerializeObject(javascriptExecutor.ExecuteAsyncScript("var callback = arguments[arguments.length - 1]; axe.run().then(results => callback(results))"), Formatting.Indented);
File.WriteAllText(report, result);
}
driver.Quit();
}
}
}
Copy icon
Copy
<?php
require_once('vendor/autoload.php');
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
$caps = array(
'bstack:options' => array(
"os" => "Windows",
"osVersion" => "10",
"projectName" => "BStack Accessibility Test",
"buildName" => "BStack Accessibility Sample Build",
),
"browserName" => "Chrome",
"browserVersion" => "103.0",
)
$web_driver = RemoteWebDriver::create(
"https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub",
$caps
);
$web_driver->get("https://www.google.com");
$axe_script = fopen("path/to/axe.min.js", "r");
$web_driver->executeScript(fread($axe_script,filesize("path/to/axe.min.js")));
fclose($axe_script);
$result = $web_driver->executeAsyncScript('var callback = arguments[arguments.length - 1];axe.run().then(results => callback(results))');
$file = fopen("path/to/report.json", "w");
// $reportJSON = json_encode($result);
fwrite($file,json_encode($result, JSON_PRETTY_PRINT));
fclose($file);
$web_driver->quit();
?>
Copy icon
Copy
from selenium import webdriver
import json
desired_cap = {
'bstack:options' : {
"os" : "Windows" ,
"osVersion" : "10" ,
"projectName" : "BStack Accessibility Test" ,
"buildName" : "BStack Accessibility Sample Build" ,
} ,
"browserName" : "Chrome" ,
"browserVersion" : "103.0" ,
}
driver = webdriver. Remote(
desired_capabilities= desired_cap,
command_executor= 'https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub'
)
driver. get( "https://www.microsoft.com" )
axe_script = open ( './axe.min.js' , 'r' )
driver. execute_script( axe_script. read( ) )
axe_script. close( )
result = driver. execute_async_script( 'var callback = arguments[arguments.length - 1];axe.run().then(results => callback(results))' )
file = open ( "./report.json" , "w" )
file . write( json. dumps( eval ( str ( result) ) ) )
file . close( )
driver. quit( )
Copy icon
Copy
require 'rubygems'
require 'selenium-webdriver'
require 'json'
#Input Capabilities
capabilities = {
'bstack:options' => {
"os" => "Windows",
"osVersion" => "10",
"projectName" => "BStack Accessibility Test",
"buildName" => "BStack Accessibility Sample Build",
},
"browserName" => "Chrome",
"browserVersion" => "103.0",
}
driver = Selenium::WebDriver.for(:remote,
:url => "https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub",
:desired_capabilities => caps)
# Searching for 'BrowserStack' on google.com
driver.navigate.to "https://www.google.com"
axe_script = open('path/to/axe.min.js', 'r')
driver.execute_script(axe_script.read())
axe_script.close()
result = driver.execute_async_script('var callback = arguments[arguments.length - 1];axe.run().then(results => callback(results))')
file = open("path/to/report.json", "w")
file.write(result.to_json)
file.close()
driver.quit
Copy icon
Copy
You can also conduct Accessibility testing of your websites on browsers where High Contrast Mode is enabled by setting BrowserStack’s custom capability high_contrast
to true
. Check out high contrast mode to learn more.
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.io.File;
import java.io.FileWriter;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
public class test{
public static final String AUTOMATE_USERNAME = "YOUR_USERNAME";
public static final String AUTOMATE_ACCESS_KEY = "YOUR_ACCESS_KEY";
public static final String URL = "https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub";
public static void main(String[] args) throws Exception {
DesiredCapabilities caps = new DesiredCapabilities();
caps.setCapability("os_version", "10");
caps.setCapability("browser", "chrome");
caps.setCapability("browser_version", "latest");
caps.setCapability("os", "Windows");
caps.setCapability("name", "Accessibility Test - Google"); // test name
caps.setCapability("build", "Java Accessibility Test Sample Build"); // CI/CD job or build name
WebDriver driver = new RemoteWebDriver(new URL(URL), caps);
driver.get("https://www.google.com");
JavascriptExecutor jse = (JavascriptExecutor)driver;
Path path = Paths.get("path/to/axe.min.js");
String content = new String(Files.readAllBytes(path));
jse.executeScript(content);
File output = new File("path/to/report.json");
FileWriter writer = new FileWriter(output);
String result = String.valueOf(jse.executeAsyncScript("var callback = arguments[arguments.length - 1]; axe.run().then(results => callback(results));"));
Gson g = new Gson();
String p = g.toJson(result);
writer.write(p);
writer.flush();
writer.close();
driver.quit();
}
}
Copy icon
Copy
const webdriver = require('selenium-webdriver');
const fs = require('fs')
// Input capabilities
const capabilities = {
'browserName': 'chrome',
'browserVersion': 'latest',
'os': 'windows',
'os_version': '10',
'build': 'Accessibility Test Sample Build',
'name': 'Accessibility test - Google'
}
async function runAccessibilityTest () {
let driver = new webdriver.Builder()
.usingServer('https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub')
.withCapabilities(capabilities)
.build();
await driver.get("http://www.google.com");
const data = await fs.readFileSync('path/to/axe.min.js', 'utf8')
await driver.executeScript(data.toString());
let result = await driver.executeAsyncScript('var callback = arguments[arguments.length - 1];axe.run().then(results => callback(results))');
await fs.writeFileSync('path/to/report.json', JSON.stringify(result));
await driver.quit();
}
runAccessibilityTest();
Copy icon
Copy
using System;
using System.IO;
using Newtonsoft.Json;
using OpenQA.Selenium.Remote;
namespace SeleniumTest
{
class Program
{
static readonly string axe = @"/path/to/axe.min.js";
static readonly string report = @"/path/where/you/want/to/save/report.json";
static void Main(string[] args)
{
RemoteWebDriver driver;
OpenQA.Selenium.Chrome.ChromeOptions capability = new OpenQA.Selenium.Chrome.ChromeOptions();
capability.AddAdditionalCapability("os_version", "10", true);
capability.AddAdditionalCapability("browser", "Chrome", true);
capability.AddAdditionalCapability("browser_version", "latest", true);
capability.AddAdditionalCapability("os", "Windows", true);
capability.AddAdditionalCapability("name", "Accessibility Test - Google", true); // test name
capability.AddAdditionalCapability("build", "C-sharp Accessibility Test Sample Build", true); // CI/CD job or build name
capability.AddAdditionalCapability("browserstack.user", "YOUR_USERNAME", true);
capability.AddAdditionalCapability("browserstack.key", "YOUR_ACCESS_KEY", true);
driver = new RemoteWebDriver(
new Uri("https://hub-cloud.browserstack.com/wd/hub/"), capability
);
driver.Navigate().GoToUrl("https://www.google.com/");
if (File.Exists(axe))
{
string axeCode = File.ReadAllText(axe);
driver.ExecuteScript(axeCode);
IJavaScriptExecutor javascriptExecutor = (IJavaScriptExecutor) driver;
string result = JsonConvert.SerializeObject(javascriptExecutor.ExecuteAsyncScript("var callback = arguments[arguments.length - 1]; axe.run().then(results => callback(results))"), Formatting.Indented);
File.WriteAllText(report, result);
}
driver.Quit();
}
}
}
Copy icon
Copy
<?php
require_once('vendor/autoload.php');
use Facebook\WebDriver\Remote\RemoteWebDriver;
use Facebook\WebDriver\WebDriverBy;
$caps = array(
"os_version" => "10",
"browser" => "Chrome",
"browser_version" => "latest",
"os" => "Windows",
"name" => "Accessibility testing", // test name
"build" => "Accessibility Testing Sample Build" // CI/CD job or build name
);
$web_driver = RemoteWebDriver::create(
"https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub",
$caps
);
$web_driver->get("https://www.google.com");
$axe_script = fopen("path/to/axe.min.js", "r");
$web_driver->executeScript(fread($axe_script,filesize("path/to/axe.min.js")));
fclose($axe_script);
$result = $web_driver->executeAsyncScript('var callback = arguments[arguments.length - 1];axe.run().then(results => callback(results))');
$file = fopen("path/to/report.json", "w");
// $reportJSON = json_encode($result);
fwrite($file,json_encode($result, JSON_PRETTY_PRINT));
fclose($file);
$web_driver->quit();
?>
Copy icon
Copy
from selenium import webdriver
import json
desired_cap = {
"browser" : "chrome" ,
"browser_version" : "latest" ,
"os" : "windows" ,
"os_version" : "10" ,
'build' : 'Python Accessibility Test Build' ,
'name' : 'Axe-core testing microsoft'
}
driver = webdriver. Remote(
desired_capabilities= desired_cap,
command_executor= 'https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub'
)
driver. get( "https://www.microsoft.com" )
axe_script = open ( './axe.min.js' , 'r' )
driver. execute_script( axe_script. read( ) )
axe_script. close( )
result = driver. execute_async_script( 'var callback = arguments[arguments.length - 1];axe.run().then(results => callback(results))' )
file = open ( "./report.json" , "w" )
file . write( json. dumps( eval ( str ( result) ) ) )
file . close( )
driver. quit( )
Copy icon
Copy
require 'rubygems'
require 'selenium-webdriver'
require 'json'
#Input Capabilities
caps = Selenium::WebDriver::Remote::Capabilities.new
caps["os"] = "Windows"
caps["os_version"] = "10"
caps["browser"] = "chrome"
caps["browser_version"] = "latest"
caps["build"] = "Sample Accessibility Test Build"
caps["name"] = "Accessibility test - Google"
caps["javascriptEnabled"] = "true"
driver = Selenium::WebDriver.for(:remote,
:url => "https://YOUR_USERNAME:YOUR_ACCESS_KEY@hub-cloud.browserstack.com/wd/hub",
:desired_capabilities => caps)
# Searching for 'BrowserStack' on google.com
driver.navigate.to "http://www.google.com"
axe_script = open('path/to/axe.min.js', 'r')
driver.execute_script(axe_script.read())
axe_script.close()
result = driver.execute_async_script('var callback = arguments[arguments.length - 1];axe.run().then(results => callback(results))')
file = open("path/to/report.json", "w")
file.write(result.to_json)
file.close()
driver.quit
Copy icon
Copy
You can also conduct Accessibility testing of your websites on browsers where High Contrast Mode is enabled by setting BrowserStack’s custom capability browserstack.high_contrast
to true
. Check out high contrast mode to learn more.
Understand components of the JSON report
After you successfully run test script, a report.json
file is generated as per the path set in the script. The report.json
JSON file contains the following accessibility test information:
{
testEngine: { …}
passes: [ …]
inapplicable: [ ]
url: “<URL of the website under test>”
timestamp: “time when the json result is generated”
testRunner: { …}
toolOptions: { …}
testEnvironment: { …}
violations: { …}
incomplete: { …}
}
Copy icon
Copy
Some of the information components available in the generated JSON report are:
violations (json
): These results indicate what elements failed in the rules.
passes (array
): These results indicate what elements passed in the rules.
incomplete (json
): It contains results that were aborted and require further testing. This can happen either because of technical restrictions to what the rule can test or because a javascript error that occurred.
inapplicable (array
): These results indicate rules that did not run because no matching content was found on the page. For example, if no video exists, those rules won’t run.
Each object returned in these arrays has some properties that can be found in the axe-core API documentation
Is this page helping you?
Thank you for your valuable feedback!