What is @axe-core/playwright?
@axe-core/playwright is an accessibility testing library that integrates with Playwright to automate accessibility checks. It leverages the axe-core engine to analyze web pages and identify accessibility issues, making it easier for developers to ensure their applications are accessible to all users.
What are @axe-core/playwright's main functionalities?
Basic Accessibility Scan
This feature allows you to perform a basic accessibility scan on a web page. The code sample demonstrates how to launch a browser, navigate to a page, inject the axe-core script, and run an accessibility check.
const { chromium } = require('playwright');
const { injectAxe, checkA11y } = require('@axe-core/playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await injectAxe(page);
const results = await checkA11y(page);
console.log(results);
await browser.close();
})();
Customizing Axe-core Options
This feature allows you to customize the axe-core options for the accessibility scan. The code sample shows how to specify which WCAG levels to check for during the scan.
const { chromium } = require('playwright');
const { injectAxe, checkA11y } = require('@axe-core/playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await injectAxe(page);
const options = { runOnly: { type: 'tag', values: ['wcag2a', 'wcag2aa'] } };
const results = await checkA11y(page, null, options);
console.log(results);
await browser.close();
})();
Excluding Elements from Scan
This feature allows you to exclude specific elements from the accessibility scan. The code sample demonstrates how to exclude elements with a specific class from being checked.
const { chromium } = require('playwright');
const { injectAxe, checkA11y } = require('@axe-core/playwright');
(async () => {
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await injectAxe(page);
const exclude = ['.ignore-this-element'];
const results = await checkA11y(page, null, null, exclude);
console.log(results);
await browser.close();
})();
Other packages similar to @axe-core/playwright
pa11y
Pa11y is an automated accessibility testing tool that runs accessibility tests on web pages and reports issues. It is similar to @axe-core/playwright in that it helps identify accessibility issues, but it does not integrate directly with Playwright. Instead, it can be used as a standalone CLI tool or integrated into other testing frameworks.
cypress-axe
Cypress-axe is a plugin for Cypress that allows you to run axe-core accessibility checks within your Cypress tests. It is similar to @axe-core/playwright in that it uses the axe-core engine for accessibility testing, but it is designed to work with the Cypress testing framework instead of Playwright.
axe-webdriverjs
Axe-webdriverjs is a library that integrates axe-core with Selenium WebDriver for automated accessibility testing. It is similar to @axe-core/playwright in that it uses the axe-core engine, but it is designed to work with Selenium WebDriver instead of Playwright.
@axe-core/playwright
Provides a chainable axe API for playwright and automatically injects into all frames
Getting Started
Install Node.js if you haven't already.
Install Playwright: npm install playwright
Install @axe-core/playwright: npm install @axe-core/playwright
Usage
This module uses a chainable API to assist in injecting, configuring, and analyzing axe with Playwright. As such, it is required to pass an instance of Playwright.
Here is an example of a script that will drive Playwright to a page, perform an analysis, and then log results to the console.
const { AxeBuilder } = require('@axe-core/playwright');
const playwright = require('playwright');
(async () => {
const browser = await playwright.chromium.launch({ headless: true });
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://dequeuniversity.com/demo/mars/');
try {
const results = await new AxeBuilder({ page }).analyze();
console.log(results);
} catch (e) {
}
await browser.close();
})();
AxeBuilder({ page: Playwright.Page })
Constructor for the AxeBuilder helper. You must pass an instance of Playwright as the first argument.
const builder = new AxeBuilder({ page });
AxeBuilder#analyze(): Promise<axe.Results | Error>
Performs analysis and passes any encountered error and/or the result object.
new AxeBuilder({ page })
.analyze()
.then(results => {
console.log(results);
})
.catch(e => {
});
AxeBuilder#include(selector: String | String[])
Adds a CSS selector to the list of elements to include in analysis
new AxeBuilder({ page }).include('.results-panel');
Method chaining is also available, add multiple CSS selectors to the list of elements to include in analysis
new AxeBuilder({ page })
.include('.selector-one')
.include('.selector-two')
.include('.selector-three');
Note: arrays with more than one index when passing multiple CSS selectors are not currently supported example: .include(['#foo', '#bar', '#baz'])
AxeBuilder#exclude(selector: String | String[])
Add a CSS selector to the list of elements to exclude from analysis
new AxeBuilder({ page }).exclude('.another-element');
Method chaining is also available, add multiple CSS selectors to the list of elements to exclude from analysis
new AxeBuilder({ page })
.exclude('.selector-one')
.exclude('.selector-two')
.exclude('.selector-three');
Note: arrays with more than one index when passing multiple CSS selectors are not currently supported example: .exclude(['#foo', '#bar', '#baz'])
AxeBuilder#options(options: axe.RunOptions)
Specifies options to be used by axe.run
. Will override any other configured options. including calls to AxeBuilder#withRules()
and AxeBuilder#withTags()
. See axe-core API documentation for information on its structure.
new AxeBuilder({ page }).options({ checks: { 'valid-lang': ['orcish'] } });
AxeBuilder#withRules(rules: String|Array)
Limits analysis to only those with the specified rule IDs. Accepts a String of a single rule ID or an Array of multiple rule IDs. Subsequent calls to AxeBuilder#options
, AxeBuilder#withRules
or AxeBuilder#withRules
will override specified options.
new AxeBuilder({ page }).withRules('html-lang');
new AxeBuilder({ page }).withRules(['html-lang', 'image-alt']);
AxeBuilder#withTags(tags: String|Array)
Limits analysis to only those with the specified rule IDs. Accepts a String of a single tag or an Array of multiple tags. Subsequent calls to AxeBuilder#options
, AxeBuilder#withRules
or AxeBuilder#withRules
will override specified options.
new AxeBuilder({ page }).withTags('wcag2a');
new AxeBuilder({ page }).withTags(['wcag2a', 'wcag2aa']);
AxeBuilder#disableRules(rules: String|Array)
Skips verification of the rules provided. Accepts a String of a single rule ID or an Array of multiple rule IDs. Subsequent calls to AxeBuilder#options
, AxeBuilder#disableRules
will override specified options.
new AxeBuilder({ page }).disableRules('color-contrast');
AxeBuilder#setLegacyMode(legacyMode: boolean = true)
Set the frame testing method to "legacy mode". In this mode, axe will not open a blank page in which to aggregate its results. This can be used in an environment where opening a blank page is causes issues.
With legacy mode turned on, axe will fall back to its test solution prior to the 4.3 release, but with cross-origin frame testing disabled. The frame-tested
rule will report which frames were untested.
Important Use of .setLegacyMode()
is a last resort. If you find there is no other solution, please report this as an issue.
const axe = new AxeBuilder({ page }).setLegacyMode();
const result = await axe.analyze();
axe.setLegacyMode(false);