Axe Accessibility Testing with Playwright + HTML Reports: The Complete Guide
Playwright is a powerful automation tool that can be used for testing web applications, including accessibility testing. Accessibility testing ensures that web content and applications are usable by people with disabilities. This article discusses integrating the Axe Accessibility Testing Engine into your Playwright tests (NodeJs version).
Can we really automate accessibility testing?
Automating accessibility testing is possible to a certain extent, but it cannot replace manual testing entirely. Automated accessibility testing tools can identify and detect some common accessibility issues with websites or applications, such as missing alt text for images, incorrect use of semantic elements, or improper colour contrast. These tools can help developers find and fix problems more efficiently and can be especially useful for maintaining accessibility standards during development.
Step breakdown:
- STEP 01: Initiate Playwright project
- STEP 02: Install axe-playwright
- STEP 03: Import required packages to test file
- STEP 04: Complete the script
- STEP 05: Scanning for WCAG violations
- STEP 06: Excluding specific components from the scan
- STEP 07: Disable specific scan rules
- STEP 08: Generate HTML reports
STEP 01: Initiate Playwright project
To run accessibility testing, you need to initiate a Playwright project. Similar to regular Playwright tests, accessibility tests can be executed in two ways.
- Create independent test cases specifically for accessibility testing
- Incorporate accessibility scans and verifications into your current test cases.
I have already written an article about setting up a Playwright project and you can refer to that article.
Setting up a local environment for the Playwright Framework
STEP 02: Install axe-playwright
Run the following command in the terminal to install the required libraries. Visit the NpmJs for more information.
npm install @axe-core/playwright
STEP 03: Import required packages to test file
In order to execute your test, the following packages will be required.
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
STEP 04: Complete the script
Testers can define whether they need to scan a full page or a component of the page. Here are the two scripts for them.
1: Scan full page
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test.describe('Playwright Homepage', () => {
test('Verify there is no accessibility issues', async ({ page }) => {
await page.goto('https://playwright.dev');
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
});
2: Scan a specific component
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test.describe('Playwright Homepage', () => {
test('Verify there is no accessibility issues', async ({ page }) => {
await page.goto('https://playwright.dev');
await page.locator('#id').waitFor();
const accessibilityScanResults = await new AxeBuilder({ page })
.include('#id')
.analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
});
The results of the accessibility scan are stored in the JSON constant ‘accessibilityScanResults’. If this array is empty, it indicates that there are no accessibility issues on the page or component, and the test will pass. Conversely, if there is at least one accessibility issue, the array will not be empty, and the test will fail.
STEP 05: Scanning for WCAG violations
WCAG is a well-known recommendation set for web accessibility. The good thing is Playwright is able to configure WCAG Tags by passing them to the above script itself without worrying about it too much.
The Tags are : wcag2a, wcag2aa, wcag21a, wcag21aa
Based on the requirement your team can decide what should be passed into the script. Also note that as I mentioned earlier, automated testing cannot detect all types of WCAG violations. There should be a manual verification as well.
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test.describe('Playwright Homepage', () => {
test('Verify there is no accessibility issues', async ({ page }) => {
await page.goto('https://playwright.dev');
const accessibilityScanResults = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
.analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
});
STEP 06: Excluding specific components from the scan
By specifying which components to be scanned in STEP 04, we have the ability to exclude certain components from accessibility testing if they are known issues or deemed unnecessary to test.
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test.describe('Playwright Homepage', () => {
test('Verify there is no accessibility issues', async ({ page }) => {
await page.goto('https://playwright.dev');
await page.locator('#id').waitFor();
const accessibilityScanResults = await new AxeBuilder({ page })
.exclude('#id')
.analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
});
STEP 07: Disable specific scan rules
If some scan rules are not required, we can disable those rules via the script. The Axe has already defined those rules so you can easily find them out by clicking here.
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test.describe('Playwright Homepage', () => {
test('Verify there is no accessibility issues', async ({ page }) => {
await page.goto('https://playwright.dev');
const accessibilityScanResults = await new AxeBuilder({ page })
.disableRules(['duplicate-id'])
.analyze();
expect(accessibilityScanResults.violations).toEqual([]);
});
});
STEP 08: Generate HTML reports
To generate an HTML report using the above test results, you need to use another library called axe-html-reporter.
Install axe-html-reporter using the following command.
npm install axe-html-reporter
Then modify the script to generate the HTML report.
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
import { createHtmlReport } from 'axe-html-reporter';
const fs = require('fs');
import { test, expect } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';
test.describe('Playwright Homepage', () => {
test('Verify there is no accessibility issues', async ({ page }) => {
await page.goto('https://playwright.dev');
const accessibilityScanResults = await new AxeBuilder({ page }).analyze();
const reportHTML = createHtmlReport({
results: accessibilityScanResults,
options: {
projectKey: "PlaywrightHomepage"
},
});
if (!fs.existsSync("build/reports/accessibility-report.html")) {
fs.mkdirSync("build/reports", {
recursive: true,
});
}
fs.writeFileSync("build/reports/accessibility-report.html", reportHTML);
expect(accessibilityScanResults.violations).toEqual([]);
});
});
It uses the accessibilityScanResults json to generate the HTML report.
Conclusion
In conclusion, this guide provides a comprehensive approach to integrating Axe Accessibility Testing with Playwright for automating accessibility tests and generating HTML reports. While automated accessibility testing can efficiently identify common accessibility issues, it is crucial to remember that it cannot replace manual testing entirely. By following the outlined steps, you can initiate a Playwright project, install necessary libraries, import required packages, scan full pages or specific components, exclude components, disable specific scan rules, and generate HTML reports for accessibility testing. Incorporating these techniques into your development process will help maintain accessibility standards and ensure a more inclusive experience for users with disabilities.
If you require additional information and configuration options for various languages, you can find them in the official Playwright documentation.