Custom Jest matcher for aXe for testing accessibility
The GDS Accessibility team found that only ~30% of issues are found by automated testing.
Tools like aXe are similar to code linters such as eslint or sass-lint: they can find common issues but cannot guarantee what you build works for users.
You'll also need to:
- test your interface with the assistive technologies that real users use (see also WebAIM's survey results).
- include people with disabilities in user research.
npm install --save-dev jest-axe
const { axe, toHaveNoViolations } = require('jest-axe')
expect.extend(toHaveNoViolations)
it('should demonstrate this matcher`s usage', async () => {
const render = () => '<img src="#"/>'
// pass anything that outputs html to axe
const html = render()
expect(await axe(html)).toHaveNoViolations()
})
Note, you can also require
'jest-axe/extend-expect'
which will callexpect.extend
for you. This is especially helpful when using the jestsetupTestFrameworkScriptFile
configuration.
const { axe, toHaveNoViolations } = require('jest-axe')
expect.extend(toHaveNoViolations)
const React = require('react')
const ReactDOMServer = require('react-dom/server')
it('should demonstrate this matcher`s usage with react', async () => {
const html = ReactDOMServer.renderToString(
<img src='#' />
)
const results = await axe(html)
expect(results).toHaveNoViolations()
})
The axe
function allows options to be set with the same options as documented in axe-core:
const { axe, toHaveNoViolations } = require('jest-axe')
expect.extend(toHaveNoViolations)
it('should demonstrate this matcher`s usage with a custom config', async () => {
const render = () => `
<div>
<img src="#"/>
</div>
`
// pass anything that outputs html to axe
const html = render()
const results = await axe(html, {
rules: {
// for demonstration only, don't disable rules that need fixing.
'image-alt': { enabled: false }
}
})
expect(results).toHaveNoViolations()
})
If you find yourself repeating the same options multiple times, you can export a version of the axe
function with defaults set.
Note: You can still pass additional options to this new instance; they will be merged with the defaults.
This could be done in Jest's setup step
// Global helper file (axe-helper.js)
const { configureAxe } = require('jest-axe')
const axe = configureAxe({
rules: {
// for demonstration only, don't disable rules that need fixing.
'image-alt': { enabled: false }
}
})
module.exports = axe
// Individual test file (test.js)
const { toHaveNoViolations } = require('jest-axe')
const axe = require('./axe-helper.js')
expect.extend(toHaveNoViolations)
it('should demonstrate this matcher`s usage with a default config', async () => {
const render = () => `
<div>
<img src="#"/>
</div>
`
// pass anything that outputs html to axe
const html = render()
expect(await axe(html)).toHaveNoViolations()
})
- Jest for the great test runner that allows extending matchers.
- aXe for the wonderful axe-core that makes it so easy to do this.
- Government Digital Service for making coding in the open the default.
- GOV.UK Publishing Frontend team who published the basis of the aXe reporter
- jest-image-snapshot for inspiration on README and repo setup