Giter Club home page Giter Club logo

pa11y's Introduction

Pa11y

Pa11y is your automated accessibility testing pal. It runs accessibility tests on your pages via the command line or Node.js, so you can automate your testing process.

NPM version Node.js version support Build status LGPL-3.0-only licensed

On the command line:

pa11y https://example.com

In JavaScript:

const pa11y = require('pa11y');

pa11y('https://example.com').then((results) => {
    // Use the results
});

Requirements

Pa11y 8 requires Node.js 18 or 20. An older version of Node.js can be used with Pa11y 6 or below.

Linux and macOS

To install Node.js you can use nvm. For example, to install with nvm with Homebrew, and then install the latest version of Node:

brew install nvm
nvm install node
nvm install-latest-npm

Alternatively, download a pre-built package from the Node.js website for your operating system.

Windows

On Windows 10, download a pre-built package from the Node.js website. Pa11y will be usable via the bundled Node.js application as well as the Windows command prompt.

Command-line interface

Install Pa11y globally with npm:

npm install -g pa11y
$ pa11y --help

Usage: pa11y [options] <url>

  Options:

    -V, --version                  output the version number
    -n, --environment              output details about the environment Pa11y will run in
    -s, --standard <name>          the accessibility standard to use: WCAG2A, WCAG2AA (default), WCAG2AAA – only used by htmlcs runner
    -r, --reporter <reporter>      the reporter to use: cli (default), csv, json
    -e, --runner <runner>          the test runners to use: htmlcs (default), axe
    -l, --level <level>            the level of issue to fail on (exit with code 2): error, warning, notice
    -T, --threshold <number>       permit this number of errors, warnings, or notices, otherwise fail with exit code 2
    -i, --ignore <ignore>          types and codes of issues to ignore, a repeatable value or separated by semi-colons
    --include-notices              Include notices in the report
    --include-warnings             Include warnings in the report
    -R, --root-element <selector>  a CSS selector used to limit which part of a page is tested
    -E, --hide-elements <hide>     a CSS selector to hide elements from testing, selectors can be comma separated
    -c, --config <path>            a JSON or JavaScript config file
    -t, --timeout <ms>             the timeout in milliseconds
    -w, --wait <ms>                the time to wait before running tests in milliseconds
    -d, --debug                    output debug messages
    -S, --screen-capture <path>    a path to save a screen capture of the page to
    -A, --add-rule <rule>          WCAG 2.1 rules to include, a repeatable value or separated by semi-colons – only used by htmlcs runner
    -h, --help                     output usage information

Testing with pa11y

Find accessibility issues at a URL:

pa11y https://example.com

The default test runner is HTML_CodeSniffer, but axe is also supported. To use axe:

pa11y https://example.com --runner axe

Use both axe and HTML_CodeSniffer in the same run:

pa11y https://example.com --runner axe --runner htmlcs

Generate results in CSV format, and output to a file, report.csv:

pa11y https://example.com > report.csv --reporter csv 

Find accessibility issues in a local HTML file (absolute paths only, not relative):

pa11y ./path/to/your/file.html

Exit codes

The command-line tool uses the following exit codes:

  • 0: Pa11y ran successfully, and there are no errors
  • 1: Pa11y failed run due to a technical fault
  • 2: Pa11y ran successfully but there are errors in the page

By default, only accessibility issues with a type of error will exit with a code of 2. This is configurable with the --level flag which can be set to one of the following:

  • error: exit with a code of 2 on errors only, exit with a code of 0 on warnings and notices
  • warning: exit with a code of 2 on errors and warnings, exit with a code of 0 on notices
  • notice: exit with a code of 2 on errors, warnings, and notices
  • none: always exit with a code of 0

Command-line configuration

The command-line tool can be configured with a JSON file as well as arguments. By default it will look for a pa11y.json file in the current directory, but you can change this with the --config flag:

pa11y https://example.com --config ./path/to/config.json 

If any configuration is set both in a configuration file and also as a command-line option, the value set in the latter will take priority.

For more information on configuring Pa11y, see the configuration documentation.

Ignoring

The ignore flag can be used in several different ways. Separated by semi-colons:

pa11y https://example.com --ignore "issue-code-1;issue-code-2" 

or by using the flag multiple times:

pa11y https://example.com --ignore issue-code-1 --ignore issue-code-2 

Pa11y can also ignore notices, warnings, and errors up to a threshold number. This might be useful if you're using CI and don't want to break your build. The following example will return exit code 0 on a page with 9 errors, and return exit code 2 on a page with 10 or more errors.

pa11y https://example.com --threshold 10 

Reporters

The command-line tool can provide test results in a few different ways using the --reporter flag. The built-in reporters are:

  • cli: output test results in a human-readable format
  • csv: output test results as comma-separated values
  • html: output test results as an HTML page
  • json: output test results as a JSON array
  • tsv: output test results as tab-separated values

You can also write and publish your own reporters. Pa11y looks for reporters in your node_modules folder (with a naming pattern), and the current working directory. The first reporter found will be loaded. So with this command:

pa11y https://example.com --reporter rainbows 

The following locations will be checked:

<cwd>/node_modules/pa11y-reporter-rainbows
<cwd>/rainbows

A Pa11y reporter must export a string property named supports. This is a semver range which indicates which versions of Pa11y the reporter supports:

exports.supports = '^8.0.0';

A reporter should export the following methods, each returning one string. If your reporter needs to perform asynchronous operations, then it may return a promise which resolves to a string:

begin(); // Called when pa11y starts
error(message); // Called when a technical error is reported
debug(message); // Called when a debug message is reported
info(message); // Called when an information message is reported
results(results); // Called with a test run's results

JavaScript interface

Add Pa11y to your project with npm, most commonly as a development dependency:

npm install pa11y --save-dev

Require Pa11y:

const pa11y = require('pa11y');

Run Pa11y against a URL, the pa11y function returns a Promise:

pa11y(url).then((results) => {
    // Use the results
});

Pa11y can also be run with options:

const options = { /* ... */ };
pa11y(url, options)).then((results) => {
    // Use the results
});

Pa11y resolves with a results object, containing details about the page, and an array of accessibility issues found by the test runner:

{
    pageUrl: 'The tested URL',
    documentTitle: 'Title of the page under test',
    issues: [
        {
            code: 'WCAG2AA.Principle1.Guideline1_1.1_1_1.H30.2',
            context: '<a href="https://example.com/"><img src="example.jpg" alt=""/></a>',
            message: 'Img element is the only content of the link, but is missing alt text. The alt text should describe the purpose of the link.',
            selector: 'html > body > p:nth-child(1) > a',
            type: 'error',
            typeCode: 1
        }
    ]
}

Transforming the results

If you wish to transform these results with a command-line reporter, require it into your code. The csv, tsv, html, json, and markdown reporters each expose a method process:

// Assuming you've already run tests, and the results
// are available in a `results` variable:
const htmlReporter = require('pa11y/lib/reporters/html');
const html = await htmlReporter.results(results);

async/await

Pa11y uses promises, so you can use async functions and the await keyword:

async function runPa11y() {
    try {
        const results = await pa11y(url);
        // Use the results
    }
    catch (error) {
        // Handle error
    }
}

runPa11y();

Callback interface

For those who prefer callbacks to promises:

pa11y(url, (error, results) => {
    // Use results, handle error
});

Validating actions

Pa11y's isValidAction function can be used to validate an action string ahead of its use:

pa11y.isValidAction('click element #submit');  // true
pa11y.isValidAction('open the pod bay doors'); // false

Configuration

Pa11y has lots of options you can use to change the way Headless Chrome runs, or the way your page is loaded. Options can be set either as a parameter on the pa11y function or in a JSON configuration file. Some are also available directly as command-line options.

Below is a reference of all the options that are available:

actions (array)

Actions to be run before Pa11y tests the page. There are quite a few different actions available in Pa11y, the Actions documentation outlines each of them.

pa11y(url, {
    actions: [
        'set field #username to exampleUser',
        'set field #password to password1234',
        'click element #submit',
        'wait for path to be /myaccount'
    ]
});

Defaults to an empty array.

browser (Browser) and page (Page)

A Puppeteer Browser instance which will be used in the test run. Optionally you may also supply a Puppeteer Page instance, but this cannot be used between test runs as event listeners would be bound multiple times.

If either of these options are provided then there are several things you need to consider:

  1. Pa11y's chromeLaunchConfig option will be ignored, you'll need to pass this configuration in when you create your Browser instance
  2. Pa11y will not automatically close the Browser when the tests have finished running, you will need to do this yourself if you need the Node.js process to exit
  3. It's important that you use a version of Puppeteer that meets the range specified in Pa11y's package.json
  4. You cannot reuse page instances between multiple test runs, doing so will result in an error. The page option allows you to do things like take screen-shots on a Pa11y failure or execute your own JavaScript before Pa11y

Note: This is an advanced option. If you're using this, please mention in any issues you open on Pa11y and double-check that the Puppeteer version you're using matches Pa11y's.

const browser = await puppeteer.launch({
    ignoreHTTPSErrors: true
});

pa11y(url, {
    browser: browser
});

browser.close();

A more complete example can be found in the puppeteer examples.

Defaults to null.

chromeLaunchConfig (object)

Launch options for the Headless Chrome instance. See the Puppeteer documentation for more information.

pa11y(url, {
    chromeLaunchConfig: {
        executablePath: '/path/to/Chrome',
        ignoreHTTPSErrors: false
    }
});

Defaults to:

{
    ignoreHTTPSErrors: true
}

headers (object)

A key-value map of request headers to send when testing a web page.

pa11y(url, {
    headers: {
        Cookie: 'foo=bar'
    }
});

Defaults to an empty object.

hideElements (string)

A CSS selector to hide elements from testing, selectors can be comma separated. Elements matching this selector will be hidden from testing by styling them with visibility: hidden.

pa11y(url, {
    hideElements: '.advert, #modal, div[aria-role=presentation]'
});

ignore (array)

An array of result codes and types that you'd like to ignore. You can find the codes for each rule in the console output and the types are error, warning, and notice. Note: warning and notice messages are ignored by default.

pa11y(url, {
    ignore: [
        'WCAG2AA.Principle3.Guideline3_1.3_1_1.H57.2'
    ]
});

Defaults to an empty array.

ignoreUrl (boolean)

Whether to use the provided Puppeteer Page instance as is or use the provided url. Both the Puppeteer Page instance and the Puppeteer Browser instance are required alongside ignoreUrl.

const browser = await puppeteer.launch();
const page = await browser.newPage();

pa11y(url, {
    ignoreUrl: true,
    page: page,
    browser: browser
});

Defaults to false.

includeNotices (boolean)

Whether to include results with a type of notice in the Pa11y report. Issues with a type of notice are not directly actionable and so they are excluded by default. You can include them by using this option:

pa11y(url, {
    includeNotices: true
});

Defaults to false.

includeWarnings (boolean)

Whether to include results with a type of warning in the Pa11y report. Issues with a type of warning are not directly actionable and so they are excluded by default. You can include them by using this option:

pa11y(url, {
    includeWarnings: true
});

Defaults to false.

level (string)

The level of issue which can fail the test (and cause it to exit with code 2) when running via the CLI. This should be one of error (the default), warning, or notice.

{
    "level": "warning"
}

Defaults to error. Note this configuration is only available when using Pa11y on the command line, not via the JavaScript Interface.

log (object)

An object which implements the methods debug, error, and info which will be used to report errors and test information.

pa11y(url, {
    log: {
        debug: console.log,
        error: console.error,
        info: console.info
    }
});

Each of these defaults to an empty function.

method (string)

The HTTP method to use when running Pa11y.

pa11y(url, {
    method: 'POST'
});

Defaults to GET.

postData (string)

The HTTP POST data to send when running Pa11y. This should be combined with a Content-Type header. E.g to send form data:

pa11y(url, {
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    method: 'POST',
    postData: 'foo=bar&bar=baz'
});

Or to send JSON data:

pa11y(url, {
    headers: {
        'Content-Type': 'application/json'
    },
    method: 'POST',
    postData: '{"foo": "bar", "bar": "baz"}'
});

Defaults to null.

reporter (string)

The reporter to use while running the test via the CLI. More about reporters.

{
    "reporter": "json"
}

Defaults to cli. Note this configuration is only available when using Pa11y on the command line, not via the JavaScript Interface.

rootElement (element)

The root element for testing a subset of the page opposed to the full document.

pa11y(url, {
    rootElement: '#main'
});

Defaults to null, meaning the full document will be tested. If the specified root element isn't found, the full document will be tested.

runners (array)

An array of runner names which correspond to existing and installed Pa11y runners. If a runner is not found then Pa11y will error.

pa11y(url, {
    runners: [
        'axe',
        'htmlcs'
    ]
});

Defaults to:

[
    'htmlcs'
]

rules (array)

An array of WCAG 2.1 guidelines that you'd like to include to the current standard. You can find the codes for each guideline in the HTML Code Sniffer WCAG2AAA ruleset. Note: only used by htmlcs runner.

pa11y(url, {
    rules: [
        'Principle1.Guideline1_3.1_3_1_AAA'
    ]
});

screenCapture (string)

A file path to save a screen capture of the tested page to. The screen will be captured immediately after the Pa11y tests have run so that you can verify that the expected page was tested.

pa11y(url, {
    screenCapture: `${__dirname}/my-screen-capture.png`
});

Defaults to null, meaning the screen will not be captured. Note the directory part of this path must be an existing directory in the file system – Pa11y will not create this for you.

standard (string)

The accessibility standard to use when testing pages. This should be one of WCAG2A, WCAG2AA, or WCAG2AAA. Note: only used by htmlcs runner.

pa11y(url, {
    standard: 'WCAG2A'
});

Defaults to WCAG2AA.

threshold (number)

The number of errors, warnings, or notices to permit before the test is considered to have failed (with exit code 2) when running via the CLI.

{
    "threshold": 9
}

Defaults to 0. Note this configuration is only available when using Pa11y on the command line, not via the JavaScript Interface.

timeout (number)

The time in milliseconds that a test should be allowed to run before calling back with a timeout error.

Please note that this is the timeout for the entire test run (including time to initialise Chrome, load the page, and run the tests).

pa11y(url, {
    timeout: 500
});

Defaults to 30000.

userAgent (string)

The User-Agent header to send with Pa11y requests. This is helpful to identify Pa11y in your logs.

pa11y(url, {
    userAgent: 'A11Y TESTS'
});

Defaults to pa11y/<version>.

viewport (object)

The viewport configuration. This can have any of the properties supported by the puppeteer setViewport method.

pa11y(url, {
    viewport: {
        width: 320,
        height: 480,
        deviceScaleFactor: 2,
        isMobile: true
    }
});

Defaults to:

{
    width: 1280,
    height: 1024
}

wait (number)

The time in milliseconds to wait before running HTML_CodeSniffer on the page.

pa11y(url, {
    wait: 500
});

Defaults to 0.

Actions

Actions are additional interactions that you can make Pa11y perform before the tests are run. They allow you to do things like click on a button, enter a value in a form, wait for a redirect, or wait for the URL fragment to change:

pa11y(url, {
    actions: [
        'click element #tab-1',
        'wait for element #tab-1-content to be visible',
        'set field #fullname to John Doe',
        'clear field #middlename',
        'check field #terms-and-conditions',
        'uncheck field #subscribe-to-marketing',
        'screen capture example.png',
        'wait for fragment to be #page-2',
        'wait for path to not be /login',
        'wait for url to be https://example.com/',
        'wait for #my-image to emit load',
        'navigate to https://another-example.com/'
    ]
});

Below is a reference of all the available actions and what they do on the page. Some of these take time to complete so you may need to increase the timeout option if you have a large set of actions.

click element <selector>

Clicks an element:

pa11y(url, {
    actions: [
        'click element #tab-1'
    ]
});

You can use any valid query selector, including classes and types.

set field <selector> to <value>

Sets the value of a text-based input or select:

pa11y(url, {
    actions: [
        'set field #fullname to John Doe'
    ]
});

clear field <selector>

Clears the value of a text-based input or select:

pa11y(url, {
    actions: [
        'clear field #middlename'
    ]
});

check field <selector>, uncheck field <selector>

Checks/unchecks an input of type radio or checkbox:

pa11y(url, {
    actions: [
        'check field #terms-and-conditions',
        'uncheck field #subscribe-to-marketing'
    ]
});

screen capture <to-file-path.png>

Captures the screen, saving the image to a file, which can be useful between actions for debugging, or just for visual reassurance:

pa11y(url, {
    actions: [
        'screen capture example.png'
    ]
});

wait for

wait for <fragment|path|url>

This allows you to pause the test until a condition is met, and the page has either a given fragment, path, or URL. This will wait until Pa11y times out so it should be used after another action that would trigger the change in state. You can also wait until the page does not have a given fragment, path, or URL using the to not be syntax. This action takes one of the forms:

  • wait for fragment to be <fragment> (including the preceding #)
  • wait for fragment to not be <fragment> (including the preceding #)
  • wait for path to be <path> (including the preceding /)
  • wait for path to not be <path> (including the preceding /)
  • wait for url to be <url>
  • wait for url to not be <url>

E.g.

pa11y(url, {
    actions: [
        'click element #login-link',
        'wait for path to be /login'
    ]
});

wait for element's state

This allows you to pause the test until an element on the page (matching a CSS selector) is either added, removed, visible, or hidden. This will wait until Pa11y times out so it should be used after another action that would trigger the change in state. This action takes one of the forms:

  • wait for element <selector> to be added
  • wait for element <selector> to be removed
  • wait for element <selector> to be visible
  • wait for element <selector> to be hidden

E.g.

pa11y(url, {
    actions: [
        'click element #tab-2',
        'wait for element #tab-1 to be hidden'
    ]
});

wait for element's event

This allows you to pause the test until an element on the page (matching a CSS selector) emits an event. This will wait until Pa11y times out so it should be used after another action that would trigger the event. This action takes the form wait for element <selector> to emit <event-type>. E.g.

pa11y(url, {
    actions: [
        'click element #tab-2',
        'wait for element #tab-panel-to to emit content-loaded'
    ]
});

navigate to <url>

This action allows you to navigate to a new URL if, for example, the URL is inaccessible using other methods. This action takes the form navigate to <url>. E.g.

pa11y(url, {
    actions: [
        'navigate to https://another-example.com'
    ]
});

Runners

Pa11y supports multiple test runners which return different results. The built-in options are:

You can also write and publish your own runners. Pa11y looks for runners in your node_modules folder (with a naming pattern), and the current working directory. The first runner found will be loaded. So with this command:

pa11y https://example.com --runner custom-tool

The following locations will be checked:

<cwd>/node_modules/pa11y-runner-custom-tool
<cwd>/node_modules/custom-tool
<cwd>/custom-tool

A Pa11y runner must export a string property named supports. This is a semver range which indicates which versions of Pa11y the runner supports:

exports.supports = '^8.0.0';

A Pa11y runner must export a property named scripts. This is an array of strings which are paths to scripts which need to load before the tests can be run. This may be empty:

exports.scripts = [
    `${__dirname}/vendor/example.js`
];

A runner must export a run method, which returns a promise that resolves with test results (it's advisable to use an async function). The run method is evaluated in a browser context and so has access to a global window object.

The run method must not use anything that's been imported using require, as it's run in a browser context. Doing so will error.

The run method is called with two arguments:

  • options: Options specified in the test runner
  • pa11y: The Pa11y test runner, which includes some helper methods:
    • pa11y.getElementContext(element): Get a short HTML context snippet for an element
    • pa11y.getElementSelector(element): Get a unique selector with which you can select this element in a page

The run method must resolve with an array of Pa11y issues. These follow the format:

{
    code: '123', // An identifier for this error
    element: {}, // The HTML element this issue relates to; `null` if no element is involved
    message: 'example', // A description of the issue
    type: 'error', // 'error', 'warning', or 'notice'
    runnerExtras: {} // Additional data a runner is free to provide; unused by Pa11y itself
}

Examples

Basic example

Run Pa11y on a URL and output the results. See the example.

Multiple URLs example

Run Pa11y on multiple URLs at once and output the results. See the example.

Actions example

Step through some actions before Pa11y runs. This example logs into a fictional site then waits until the account page has loaded before running Pa11y. See the example.

Puppeteer example

Pass in pre-created Puppeteer browser and page instances so that you can reuse them between tests. See the example.

Common questions and troubleshooting

See our Troubleshooting guide to get the answers to common questions about Pa11y, along with some ideas to help you troubleshoot any problems.

Tutorials and articles

You can find some useful tutorials and articles in the Tutorials section of pa11y.org.

Contributing

There are many ways to contribute to Pa11y, some of which we describe in the contributing guide for this repo.

If you're ready to contribute some code, clone this repo, commit your code to a new branch, then create a pull request to bring your changes into main. If you're an external contributor, fork this repo first, then follow the same process.

Please write unit tests for your code, and check that everything works by running the following before opening a pull request:

npm run lint                # Lint the code
npm test                    # Run every test, reporting coverage

You can also run test suites individually:

npm run test-unit           # Run the unit tests alone
npm run test-integration    # Run the integration tests alone
npm run test-coverage       # Run the unit tests alone, reporting coverage

Support and migration

Tip

We maintain a migration guide to help you migrate between major versions.

When we release a new major version we will continue to support the previous major version for 6 months. This support will be limited to fixes for critical bugs and security issues. If you're opening an issue related to this project, please mention the specific version that the issue affects.

The following table lists the major versions available and, for each previous major version, its end-of-support date, and its final minor version released.

Major version Final minor version Node.js support Puppeteer version Support end date
8 18, 20 ^22 ✅ Current major version
7 7.0 18, 20 ^20 October 2024
6 6.2 12, 14, 16 ~9.1 July 2024
5 5.3 8, 10, 12 ^1 2021-11-25
4 4.13 4, 6, 8 2018-08-15
3 3.8 0.12, 4 2016-12-05
2 2.4 0.10, 0.12 2016-10-16
1 1.7 0.10 2016-06-08

License

Pa11y is licensed under the Lesser General Public License (LGPL-3.0-only).
Copyright © 2013-2024, Team Pa11y and contributors

pa11y's People

Contributors

aarongoldenthal avatar andrewmee avatar andygout avatar carbonrobot avatar colinrotherham avatar danyalaytekin avatar glynnphillips avatar hollsk avatar joeyciechanowicz avatar josebolos avatar jsa34 avatar kkoskelin avatar lily2point0 avatar lorenzoancora avatar m1rp avatar manuelmeister avatar mariabg avatar mfairchild365 avatar nickcall avatar ondras avatar paazmaya avatar pamo avatar petetnt avatar redgardner avatar robloach avatar rowanmanning avatar rrmoelker avatar ryhinchey avatar sangitamane avatar tavvy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pa11y's Issues

Allow sending options to pa11y

I've been seeing errors where pa11y fails to open URLs due to failed ssl handshakes. The solution is to change the ssl protocol that phantomjs uses via this command line option:

--ssl-protocol=any

I'm sure other issues could crop up where passing user defined configuration to phantomjs would be helpful, so maybe it would be better to implement phantomjs's --config option:

--config=/path/to/config.json

Sources:

  1. http://stackoverflow.com/questions/12021578/phantomjs-failing-to-open-https-site#answer-17101575
  2. https://github.com/ariya/phantomjs/wiki/API-Reference

Allow for reporting levels to be set: error, warning, notice

Great tool, very good implementation of HTML Code Sniffer!

For CI integration, it would be very useful to be able to specify the reporting level, eg.

0 - error & warning & notice
1 - error & warning
2 - error

With 0 being the default.

In our case, this would allow CI testing to halt a build if an error is found in the WCAG standard but allow the build to continue if only warnings and notices are present.

Finalise and document the JavaScript API

Make a JavaScript API for pa11y which is consistent, stable and documented. This will allow for tools to be built on top of pa11y's core (e.g. #16), as well as enable pa11y to be easily integrated into other tools such as Grunt.

This may mean moving some of the more command-line-specific stuff out of lib/pa11y. Off the top of my head, we'd need to reconsider:

  • Use of process.cwd in path resolution (for config files)
  • Use of console.log/console.error in reporters. Either that, or reporters should be exclusive to the command-line tool and pa11y should just deal in JavaScript objects

Source code and screenshot backup

Hello,
For some website, the page tested by pa11y is not the same as the one displayed in a browser (maybe cause of the user-agent ...). It would be nice to have an option to get a backup of the source page code and a screenshot (phantomjs) of the page tested by pa11y to be sure this is the good one.

Investigate passing data to PhantomJS

The way we pass data to PhantomJS at the moment is awful. We're passing the 'standard' to use through the querystring.

There's almost definitely a nicer way.

I couldn't work out how to pass data into PhantomJS any other way using our chosen Node library. I may just be being blind.

Allow customizing the viewport width

It looks like pa11y currently renders and checks pages at a mobile width. This is useful, and goes with a mobile first attitude, however it ignore other potential breakpoints.

Especially when considering responsive design, the layout, colors, content, etc can change at different breakpoints, which can affect accessibility.

So, it would be nice if there was a command line option to configure the viewport size. Ideally, you could add several breakpoints and pa11y would run the test suite against each breakpoint, and then return the breakpoints for each error that was found.

Implement error/warning rules that HTML CodeSniffer implements

The following list is taken roughly from HTML CodeSniffer's implemented rules. We should aim to implement tests for all of these in pa11y 2.0 as a baseline.

I've excluded notices for now to focus on actionable items.

  • 1.1.1 Non-text content
    • missing alt attribute on img (error)
    • empty alt attribute on img inside an a with no other content (error)
    • empty alt attribute on img but title attribute is set (error)
    • missing alt attribute on input type="image" (error)
    • missing alt attribute on area (error)

todo: continue adding these, also get unique codes for each

Tests fail on first run

The first time you run grunt from within pa11y, you get this:

$ grunt

…

Running "mochaTest:functional" (mochaTest) task


  pa11y --help
    ✓ should be successful
    ✓ should output usage information

  pa11y --version
    ✓ should be successful
    ✓ should output the current version


  pa11y --config ./config.json http://localhost:4117/normal
    1) "before all" hook

  4 passing (2s)
  1 failing

  1) pa11y --config ./config.json http://localhost:4117/normal "before
all" hook:
     Error: timeout of 2000ms exceeded
      at null.<anonymous>
(/Users/jrobinson/repositories/git/pa11y/node_modules/grunt-mocha-test/node
_modules/mocha/lib/runnable.js:165:14)
      at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)



Warning: Task "mochaTest:functional" failed. Use --force to continue.

Aborted due to warnings.

Tests pass if run again.

Unhandled error event

sieben@sieben-lincs:~|⇒ pa11y nature.com

Welcome to Pa11y
We'll sniff your page for you now.

Loading page...

events.js:72
throw er; // Unhandled 'error' event
^
Error: spawn ENOENT
at errnoException (child_process.js:980:11)
at Process.ChildProcess._handle.onexit (child_process.js:771:34)

Break up and unit test `lib/pa11y.js`

This is the last un-(unit)tested part of the code base – mainly because it's quite large and difficult to test in its current state. Look at breaking this apart and making more testable.

Not able to get detailed accessibility report

I am using pa11y for accessibility audit on my web application and it generate a report which shows following details -

  • code : WCAG2AA.Principle2.Guideline2_4.2_4_2.H25.2
  • message : Check that the title element describes the document.
  • type : notice

But i am not able to get details like where any particular accessibility error/warning exists in my html.
May be i am not able to understand.
so, please help me on this or let me know if there is any option to customize reports to get complete details to resolve issues in html.

Confirming usage under the GPL

Greetings team pa11y! @adelevie introduce me to the awesomeness that is pa11y last week, and since then, we've set out to make an automated 508 testing tool for Jekyll and other static sites. We've lovingly called the Ruby gem Ra11y.

Before we go too far down the 🐰 hole, we wanted to check in with you and make sure that we were honoring both the project's vision and the spirit of the GPL.

Pa11y is not distributed with Ra11y, instead, the Readme instructs users on how to install Pa11y via NPM. Ra11y shells out to pa11y with default arguments, and then parses the JSON returned via stdout. The executable is even configurable if the user would like to use a different command-line testing tool.

From The GPL FAQ:

By contrast, pipes, sockets and command-line arguments are communication mechanisms normally used between two separate programs. So when they are used for communication, the modules normally are separate programs.

To me, it sounds like the letter of the law is clear, but because we'll likely want to contribute improvements upstream, wanted to check in with the project maintainers personally before we were too far along.

Edit: To answer the most obvious question ("why not just use pa11y?"), Ra11y serves as an test abstraction, allowing you run to run accessibility tests against an entire directory of static files locally, aggregating the results.

Don't use return codes to indicate lint error count

I feel a bit guilty about this one, since I introduced it in #25 and #32.

I still think the process should exit with an error to indicate that there were errors (as per #14), but using the actual count as the code will break if there are too many errors (more than 255). Also, using -1 wraps around, and while it is still possible to get it back, the process is a hassle (not to mention that if there are exactly 255 errors, the results count will be indistinguishable from a pa11y internal error).

Thoughts on this?

Sync JSON config file with command line options

Idea: adding the ability to configure all the same options in the JSON config (.pa11yrc) that are available as command line flags.

I'm not 100% sure where I would draw the line on this as not all of the command line flags are worthy (e.g. help and version), but I think the others might be useful.

Thoughts? With ideas like #50/#51 and #53, maybe the JSON config is underutilised.

Revisit (and refactor) feature tests

These were thrown together as a basic safety net before we had a decent test suite. There's now a lot of repetition and most of the JS code in test/feature is a mess.

running pa11y from the command line throws an error

phantom stderr: 2013-12-18 17:01:57.429 phantomjs[8694:507] *** WARNING: Method userSpaceScaleFactor in class NSView is deprecated on 10.7 and later. It should not be used in new applications. Use convertRectToBacking: instead.

Review Truffler

Hey @whymarrh, I've been working on splitting out the PhantomJS part of pa11y into a separate library, which is now open-sourced at https://github.com/nature/truffler. Before I start using this, can you envisage any issues? Is there anything I've missed?

There's no rush on this, but it'd be excellent if you could cast your eyes over it at some point.

Code Sniffer Error

Hello!
I got a generic "Code Sniffer Error" when I launch the following command:
pa11y scuolafalconeborsellino.it

Also when use the flag -d, I can't understand what went wrong:

Welcome to Pa11y
We'll sniff your page for you now.

Debug: Starting timeout timer (30000ms)
Loading page...
Running HTML CodeSniffer...
Error: HTML CodeSniffer error

What to do to better understand the problem? I suppose this is caused by the frame included in the webpage...

Thank you very much!

Ignore SSL errors by default

For 2.0, it'd perhaps be good to ignore SSL errors by default. See #64. This should be much easier to do in the newer code-base.

Conform to GPL usage guidelines

Just noticed that pa11y doesn't follow the GPL guidelines for using the license.

Quoting from http://www.gnu.org/licenses/gpl-howto.html (emphasis is mine)...

"...the process involves adding two elements to each source file of your program: a copyright notice... and a statement of copying permission, saying that the program is distributed under the terms of the GNU General Public License..."

"The copying permission statement should come right after the copyright notices.
...
For programs that are more than one file, it is better to replace “this program” with the name of the program, and begin the statement with a line saying “This file is part of NAME”. For instance,

This file is part of Foobar.

Foobar is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Foobar is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Foobar.  If not, see <http://www.gnu.org/licenses/>.

This statement should go near the beginning of every source file, close to the copyright notices."

"For interactive programs, it is usually a good idea to make the program print out a brief notice about copyright and copying permission when it starts up."

"You should also include a copy of the license itself somewhere in the distribution of your program. All programs, whether they are released under the GPL or LGPL, should include the text version of the GPL. In GNU programs the license is usually in a file called COPYING."

Zombies!

First of all, thank you for such a wonderful project. We have been using it quite extensively and have thus found some problems with it. The most problematic of which is that it spawns zombie processes that consume memory and cpu and eventually crash the server.

Some details:
If you run pa11y on a page that generates an error, p11y eventually reaches its timeout but at least two processes live on (node and phantomjs).

To reproduce the error I have been able to do the following:

  1. run pa11y -r json http://prairieschooner.unl.edu/?q=fusion%2Fwork%2Fbus-driver and wait for it to error
  2. run ps x -o "%p %r %y %x %c " or look at the output of ps x and you should see two zombies processes (one for node and one for phantomjs). Sometimes you will see one or the other.

We are using SiteMaster to scan our sites with several metrics, including accessibility via pa11y. In order to get around this problem, I implemented our own custom timeout for the pa11y process, which recursively kills child processes. See: UNLSiteMaster/metric_pa11y@d478bc8

I'm not sure where exactly this problem lives. It might actually be a bug in phantomjs. I just thought I'd give you a heads up.

Review Pa11y 2.0 API

A first pass of pa11y 2.0 has been built, and is viewable on the 2.x branch for now. It's had a couple of big API changes, and the code itself is a ground-up rewrite.

I decided to stick with PhantomJS and HTML CodeSniffer for this release, if we ever move away from them it'll be much further down the line. The core library has been split into a few smaller modules and is a lot cleaner and easier to understand than 1.0; also a lot of attention has been given to the documentation.

I'd like to get feedback on the API changes which are significant (hence the 2.0 bump) before this gets released so that we can make changes if needed. @dotcode, @whymarrh, @stephenmathieson – it'd be much appreciated if you had time to review (the API more than the code itself).

The 2.x README is pretty comprehensive, and I've also written a Migration Guide to highlight the changes and help people make the switch.

Thank you

Release pa11y 2.0

Pa11y 2.0 is currently in development, and viewable on the 2.x branch for now. Issues will appear in the 2.0 milestone, and we'll be aiming for near feature parity with pa11y 1.x.

Pa11y 2.0 is currently in an alpha state, and is not ready to replace 1.x as part of your toolchain. This is mainly because not all of the accessibility rules present in 1.x have been built yet. Also, things may (and are likely to) change before we reach Beta. You can install the alpha version with:

npm install -g https://github.com/nature/pa11y/tarball/2.x

For contributors: feedback is hugely appreciated, and no change to the current 2.0 API/code is too big to consider.

The major changes in this version are as follows:

  • Drop the PhantomJS dependency
  • Drop HTML CodeSniffer as a tester
  • Drop Section508 support (just for initial release – it can be built in later)
  • Allow writing custom rules
  • Allow configuring of existing rules
  • Allow testing of HTML snippets as well as URLs
  • Allow ignoring rules and changing error levels

Document all of the rules you can ignore

This probably involves the joyous task of trawling through HTML CodeSniffer and grabbing each of the rules (code plus message).

At the moment you have to copy rules from the console output which is quite inefficient, and doesn't allow you to ignore rules that you haven't come across yet.

Set Unique User Agent

Investigate setting a unique user agent to allow sites to filter out pa11y traffic from analytics etc.

phantomjs timeout when getting new htmlcodesniffer

trying this
pa11y -c "http://raw.githubusercontent.com/bryanrasmussen/HTML_CodeSniffer/master/HTMLCS.js" www.sundhed.dk
or this
pa11y -c "https://raw.githubusercontent.com/bryanrasmussen/HTML_CodeSniffer/master/HTMLCS.js" www.sundhed.dk

always gives me

Loading page...
Running HTML CodeSniffer...
Error: PhantomJS timeout

another thing is I want to pass a lot more info from htmlcs, for example the html that triggered the warning, an xpath to the element etc.

If I want to the above should I just make sure that it comes out in the message.msg, and then that is adequate ( as I looks like from the code) or will I have to do some adaption of pa11y itself? (if so I would like to know how to compile)

pa11y hard to use from non-internet connected machines

Hi,

Thanks for making pa11y. We're trying to use it for our project but since we have machines with no internet connectivity we have to jump through some hoops to make HTMLCS.js available to download via HTTP.

Is there a reason you're not just including this js file in your code or is there a reason it can't be fetched from a local file system?

Happy to try and make a fix but wanted to understand if there were some reasons for this not being possible.

Thanks,

Tom

PhantomJS Error

Hello,

I cannot launch the tool because i get an error about the path of the phantomjs. However, phantomjs path is on the system environment variables, and like you can see in the image, I can run the commands of phantomjs like for example (phantomjs --version) to check if phantomjs is installed.

Do you know what could be wrong?

Thank you,

phantomjs-error

pa11y installing error

I have installed NodeJS 0.10 but i could not install pa11y tool. I also have installed Windows SDK and VisualStudio.

cmd3

However, when try to install pa11y tool "$ npm install -g pa11y", i got this error and the tool fails to install.

eror

I see that the "weak 2.2" script and package fail to install, but i don't know why.

Pa11y fails with error URL could not be loaded

Pa11y Ignore SSL Certificate warning

Hello, I am trying to integrate Pa11y as part of Build process. However on trying to perform site validation seeing following error.

/pa11y WCAG2AA https://testsiteurl

_-::> Loading page...
_-::> URL could not be loaded

It appears my Local test environment does not have valid SSL Certificate.
for eg: Curl https://testsiteurl throws following message
curl: (60) SSL certificate problem: Invalid certificate chain

Could you please advise, if there is any way to ignore ssl certificate warning, when validating urls with Pa11y.
for eg: Curl -k testsiteurl , using -k we can ignore ssl warning with Curl

Thanks,
Raja

remove heavy dependencies

dependencies such as _ are a bit large for what they're being used for and may become deeply coupled with this module. how would you feel about removing the underscore dependency and relying on smaller, cleaner modules for underscore-esque functionality (_.defaults, _.countBy, etc.)?

Default config file `.pa11yrc`

Allow pa11y to use a default config file <cwd>/.pa11yrc.

The .pa11yrc config file should be used if present, and if a config file hasn't been specified with the --config command-line option.

PhantomJS timeouts

Occasionally (rarely) PhantomJS can hang which causes the command to just sit there doing nothing.

If we can't solve the root issue, it may be worth implementing a simple timeout to prevent this from clogging up CI servers etc. If a timeout is added, make sure it can be specified with an option like this:

-t, --timeout <ms>

Possibly related to #2.

Default to TLSv1 in order to support older versions of PhantomJS

PhantomJS previously (<= 1.9.7) used SSLv3 for all secure connections and since a lot of servers are disabling it due to the 🐩 attack, the --ssl-protocol=tlsv1 flag would need to be used to change the default behaviour.

PhantomJS 1.9.8 (released 5 days ago) changed the default protocol to TLSv1, fixing the issue.

This is more of a question: should the --ssl-protocol=tlsv1 flag be passed by default in order to support older versions of PhantomJS? The alternative would be to require a newer PhantomJS binary (>= 1.9.8) when the server doesn't support SSLv3.

Release 1.0

This is a placeholder issue to prevent the milestone from accidentally closing.

  • Fix all outstanding issues
  • Version, tag etc.
  • Publish to npm

spidering support

i know it's a huge feature request, but spidering support would be extremely helpful.

it'd be nice to also be able to specify a maximum depth of spidered pages:

$ pa11y http://website.org/ --depth 15

thoughts? i'd be happy to contribute, or create a separate module (pa11y-spider?) for such a task.

Ignore not working

Hello,

Hopefully I'm just doing something wrong but I can't get the ignore feature to work. Here is my code:

pa11y.sniff({
    url: url,
    standard: accessibilityStandard,
    useragent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.104 Safari/537.36',
    config: {
        ignore: [
            'WCAG2AA.Principle1.Guideline1_4.1_4_3.G18'
        ]
    },
}, function(err, results) {
    // Do something
});

Whenever I run this command I get nothing but WCAG2AA.Principle1.Guideline1_4.1_4_3.G18 errors (because I've eliminated everything else).

Is there something wrong in my code or is there a defect?

PhantomJS hangs on page redirect

If there's a redirect in the page load, PhantomJS will hang forever (it seems). This may be related to JavaScript redirects but I've experienced with server redirects too.

Release 1.1

This is a placeholder issue to prevent the milestone from accidentally closing.

  • Fix all outstanding issues
  • Version, tag etc.
  • Publish to npm

Write a `pa11y list` command

As rules/suites are now customisable and extendable, it would be useful if the command-line tool could list all of the ones present. Thinking pa11y -l.

Allow HTML source from file system and not just URLs.

HTML Code Sniffer allows for files on file-system to be used as the source HTML.

This is very useful when you need to analyse many HTML files and want to break the process into 2 distinct phases:

  1. Download all HTML
  2. Analyse HTML files for WCAG compliance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.