Test helpers for specifying accessibility of pages during web development.

Usage no npm install needed!

<script type="module">
  import continua11yAcceptance from '';



Build Status Test Coverage Code Climate

Accessibility is important. Mobile first development is also important. This is an acceptance test framework designed to make it easy to test accessibility as part of your build process. It also makes it easy to test in a variety of sizes.

Under the covers, this package is using the great pa11y library. Configuration from this framework is passed down to pa11y.


This tool is meant to be used programmatically and has assertions via assert built in. These are acceptance and not unit tests, and the tests run against a node http server.

With express the server is returned from the call to listen:

let server = app.listen(3344, () => { /* a great place for test setup!*/ });

This is just a vanilla server generated by node's http module with the function createServer.

Using it with the continua11y-acceptance module aims to be as easy as possible.

Here is an example that uses the mocha framework to take advantage of before and after blocks:

let accessibilityTest;
let config = { /* */ }

before((done) => {
  server = app.listen(3344, () => {
    accessibilityTest = contintua11yAcceptance(config).test(server);

it('should have no accessibility errors', (done) => {'/my-great-path', (err, results) {
    if (err) { return done(err); }

    results.assertNoErrors(); // raises an assertion error, like assert

Test callbacks have the arguments:

*err: any error that happened during the page examination process. *results: a Result object with both data and built in assertions.


All the configuration options available in pa11y are passed down. In addition, there are easy size configurations for testing accessibility in mobile, tablet, desktop or other custom viewports:

let accessibility = contintua11yAcceptance({
  sizes: {
    mobile: {width: 320, height: 480},
    mobileLandscape: {width: 480, height: 320}

let test = accessibility.test(server, 'mobileLandscape');'/my-great-page', (err, results) => {
  // assertions


The results object passed into an accessibility test comes with assertions, built in. Under the cover these use the assert module to raise an assertion error.

  • assertNoErrors: raises an assert.AssertionError if the number of errors is not zero.
  • assertErrorsLessThan: raises an assert.AssertionError if the number of errors is greater than, or equal to the number passed in as an argument.
  • assertWarningsLessThan: raises an assert.AssertionError if the number of warnings is greater than, or equal to the number passed in as an argument.
  • assertNoticesLessThan: raises an assert.AssertionError if the number of notices is greater than, or equal to the number passed in as an argument.

Need more flexibility with assertions?

The results object passed into the test callback comes with the underlying data, available as a series of methods.

  • errors
  • warnings
  • notices

Each packs a data format that comes from pa11y's json format and has the keys:

  • code: the identifier for the underlying accessibility issue
  • context: a snippet of html code where the issue occured
  • message: a description of the accessibility issues
  • selector: a CSS selector for the element causing problems
  • type: either 'error', 'notice', or 'warning'
  • typeCode: ??, if you know, please make a pull request!

Here is an example data for a missing/empty title tag.

  code: 'WCAG2AA.Principle2.Guideline2_4.2_4_2.H25.1.NoTitleEl',
  context: '<head>\n    <meta charset="utf-8">\n\n  ...</head>',
  message: 'A title should be provided for the document, using a non-empty title element in the head section.',
  selector: 'html > head',
  type: 'error',
  typeCode: 1


The library by default writes reports about each url in each size that it runs to /accessibility. Reporting can be turned off in configration.

You will likely want to update your .gitignore to ignore accessibility reports. These are effemeral artifacts that should not be part of the repository.

You can turn off configuration via options that include this: { report: false }

To send the report to an alternate directory use this configuration:

  report: '/my-special/directory'

Environmental valiables can be used to override whether reporting happens:

# or

The main purpose of this flag is to reduce test time in local development environments. Therefore, directory specifications are only available via json configuration.

It makes sense to clear the report directory before generating new reports via acceptance tests. The object returned from configuring the library has a method clearReport, that will destroy the report directory. You will want to hook this into the beginning of your test run in some way:

let accessibilityAcceptance = require('continua11y-acceptance')(config);
accessibilityAcceptance.clearReport((err) => {
  if (err) { throw err; }
  // do something now that test setup is finished

Currently reporting is only available as json, one file per path and size. The goal of reporting is to allow CI processes to aggregate this data and send it to a reporting dashboard.


See CONTRIBUTING for additional information.

Public domain

This project is in the worldwide public domain. As stated in CONTRIBUTING:

This project is in the public domain within the United States, and copyright and related rights in the work worldwide are waived through the CC0 1.0 Universal public domain dedication.

All contributions to this project will be released under the CC0 dedication. By submitting a pull request, you are agreeing to comply with this waiver of copyright interest.