Code Monkey home page Code Monkey logo

pa11y-ci's Introduction

Pa11y CI

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

Pa11y CI is an accessibility test runner built using Pa11y, designed to run in Continuous Integration environments. Automated testing of your application can help to prevent accessibility issues reaching production.

Use this tool to test against a list of URLs or a sitemap, and report on issues it finds.

Requirements

This command line tool requires a stable (even-numbered) Node.js version of 18 or above.

Pa11y CI 3 and Ubuntu

To use version 3 of Pa11y CI with a version of Ubuntu above 20.04, a path for the Chrome executable must be defined in your Pa11y CI config, as defaults.chromeLaunchConfig.executablePath. Version 4 of Pa11y CI, which will use Pa11y 7 along with a more recent version of Puppeteer, will resolve this issue.

Usage

Pa11y CI is provided as a command line tool, pa11y-ci. To install it globally with npm:

npm install -g pa11y-ci
$ pa11y-ci --help

Usage: pa11y-ci [options] <paths>

Options:
  -V, --version                    output the version number
  -c, --config <path>              the path to a JSON or JavaScript config file
  -s, --sitemap <url>              the path to a sitemap
  -f, --sitemap-find <pattern>     a pattern to find in sitemaps. Use with --sitemap-replace
  -r, --sitemap-replace <string>   a replacement to apply in sitemaps. Use with --sitemap-find
  -x, --sitemap-exclude <pattern>  a pattern to find in sitemaps and exclude any url that matches
  -j, --json                       Output results as JSON
  -T, --threshold <number>         permit this number of errors, warnings, or notices, otherwise fail with exit code 2
                                   (default: "0")
  --reporter <reporter>            the reporter to use. Can be a npm module or a path to a local file.
  -h, --help                       display help for command

Configuration

Pa11y CI checks the current working directory for a JSON config file named .pa11yci. An example:

{
    "urls": [
        "https://pa11y.org/",
        "https://pa11y.org/contributing"
    ]
}

Pa11y CI will visit each URL in the urls array, together with any path provided as a CLI argument. A path can be relative, absolute, or a glob pattern.

Specify a different configuration file, JSON or JavaScript, using the command-line parameter --config:

pa11y-ci --config path/to/config.json

Default configuration

You can specify a default set of pa11y configurations that should be used for each test run. Attach this to a defaults property in your config; for example:

{
    "defaults": {
        "timeout": 1000,
        "viewport": {
            "width": 320,
            "height": 480
        }
    },
    "urls": [
        "https://pa11y.org/",
        "https://pa11y.org/contributing"
    ]
}

Pa11y CI supports two additional options here:

  • concurrency: The number of tests that should be run in parallel. Defaults to 1.
  • useIncognitoBrowserContext: Run test with an isolated incognito browser context; stops cookies being shared and modified between tests. Defaults to true.

URL configuration

A URL can be a string, or an object; in its object form, part or all of the default pa11y configuration can be overridden per URL. For example, this allows the timeout to be increased for a slow-loading page, or to take a screenshot for a page of particular interest:

{
    "defaults": {
        "timeout": 1000
    },
    "urls": [
        "https://pa11y.org/",
        {
            "url": "https://pa11y.org/contributing",
            "timeout": 50000,
            "screenCapture": "myDir/my-screen-capture.png"
        }
    ]
}

Using a JavaScript configuration file

If a JavaScript configuration file is used, it should be a CommonJS module that exports a configuration object. This can be used to dynamically update configuration parameters, for example taking data from environment variables as shown in the example below.

module.exports = {
    defaults: {
        timeout: 1000,
        headers: {
            token: process.env.TOKEN
        }
    },
    urls: [
        "https://pa11y.org/"
    ]
};

Sitemaps

Provide a --sitemap argument to retrieve a sitemap and then test each URL within:

pa11y-ci --sitemap https://pa11y.org/sitemap.xml

Pa11y will be run against the text content of each <loc/> in the sitemap's XML.

Note

Providing a sitemap will cause the urls property in your JSON config to be ignored.

Transforming URLs retrieved from a sitemap before testing

Pa11y CI can replace a string within each URL found in a sitemap, before beginning to test. This can be useful when your sitemap contains production URLs, but you'd actually like to test those pages in another environment. Use the flags --sitemap-find and sitemap-replace:

pa11y-ci --sitemap https://pa11y.org/sitemap.xml --sitemap-find pa11y.org --sitemap-replace localhost

Excluding URLs

Exclude URLs from the test run with the flag --sitemap-exclude.

Reporters

Pa11y CI includes two reporters:

  • (default) cli, a reporter that outputs pa11y results to the console
  • json, which outputs JSON-formatted results, either to the console or a file

Custom reporters are also supported.

Choose a specific reporter with the flag --reporter. The value of this flag can also be:

  • a path to a locally installed npm package (ie: pa11y-reporter-html)
  • a path to a local node module; either an absolute path, or one relative to the current working directory (for example ./reporters/my-reporter.js)

Example:

npm install pa11y-reporter-html --save
pa11y-ci https://pa11y.org/ --reporter=pa11y-reporter-html 

Use multiple reporters

You can use multiple reporters by setting them on the defaults.reporters array in your config. The shorthand cli and json can be included to select the included reporters.

{
    "defaults": {
        "reporters": [
            "cli", // <-- this is the default reporter
            "pa11y-reporter-html",
            "./my-local-reporter.js"
        ]
    },
    "urls": [
        "https://pa11y.org/",
        {
            "url": "https://pa11y.org/contributing",
            "timeout": 50000,
            "screenCapture": "myDir/my-screen-capture.png"
        }
    ]
}

Note

If the --reporter flag is provided on the command line, all appearances of reporters in the config file will be overridden.

Reporter options

Reporters can be configured, when supported, by settings the reporter as an array with its options as the second item:

{
    "defaults": {
        "reporters": [
            "pa11y-reporter-html",
            ["./my-local-reporter.js", { "option1": true }] // <-- note that this is an array
        ]
    },
    "urls": [
        "https://pa11y.org/",
        {
            "url": "https://pa11y.org/contributing",
            "timeout": 50000,
            "screenCapture": "myDir/my-screen-capture.png"
        }
    ]
}

The included CLI reporter does not support any options.

The included JSON reporter outputs the results to the console by default. It can also accept a fileName with a relative or absolute file name where the JSON results will be written. Relative file name will be resolved from the current working directory.

{
    "defaults": {
        "reporters": [
            ["json", { "fileName": "./results.json" }] // <-- note that this is an array
        ]
    },
    "urls": [
        "https://pa11y.org/"
    ]
}

Write a custom reporter

Pa11y CI reporters use an interface similar to pa11y reporters and support the following optional methods:

  • beforeAll(urls): called at the beginning of the process. urls is the URLs array defined in your config
  • afterAll(report) called at the very end of the process with the following arguments:
    • report: pa11y-ci report object
    • config: pa11y-ci configuration object
  • begin(url): called before processing each URL. url is the URL being processed
  • results(results, config) called after pa11y test run with the following arguments:
  • error(error, url, config): called when a test run fails with the following arguments:

Here is an example of a custom reporter writing pa11y-ci report and errors to files:

const fs = require('fs');
const { createHash } = require('crypto');

// create a unique filename from URL
function fileName(url: any, prefix = '') {
    const hash = createHash('md5').update(url).digest('hex');
    return `${prefix}${hash}.json`;
}

exports.afterAll = function (report) {
    return fs.promises.writeFile('report.json', JSON.stringify(report), 'utf8');
}

// write error details to an individual log for each URL
exports.error = function (error, url) {
    const data = JSON.stringify({url, error});
    return fs.promises.writeFile(fileName(url, 'error-'), data, 'utf8');
}

Configurable reporters

A configurable reporter is a special kind of pa11y-ci reporter exporting a single factory function as its default export.

When initialized, the function receives the user configured options (if any) and pa11y-ci configuration object as argument.

For example, here is a reporter writing all results to a single configurable file:

// ./my-reporter.js

const fs = require('fs');

module.exports = function (options) {
    // initialize an empty report data
    const customReport = {
        results: {},
        errors: [],
        violations: 0,
    }

    const fileName = options.fileName

    return {
        // add results to the report
        results(results) {
            customReport.results[results.pageUrl] = results;
            customReport.violations += results.issues.length;
        },

        // add errors too
        error(error, url) {
            customReport.errors.push({ error, url });
        },

        // write everything to a file
        afterAll() {
            const data = JSON.stringify(customReport);
            return fs.promises.writeFile(fileName, data, 'utf8');
        }
    }
};
// configuration file
{
    "defaults": {
        "reporters": [
            ["./my-reporter.js", { "fileName": "./my-report.json" }]
        ]
    },
    "urls": [
        ...
    ]
}

Docker

If you want to run pa11y-ci in a Docker container then you can use the buildkite/puppeteer image as this installs Chrome and all the required libs to run headless chrome on Linux.

You will need a config.json that sets the --no-sandbox Chromium launch arguments:

{
    "defaults": {
        "chromeLaunchConfig": {
            "args": [
                "--no-sandbox"
            ]
        }
    },
    "urls": [
        "https://pa11y.org/",
        "https://pa11y.org/contributing"
    ]
}

And then a Dockerfile that installs pa11y-ci and adds the config.json

FROM buildkite/puppeteer:v1.15.0

RUN npm install --global --unsafe-perm pa11y-ci
ADD config.json /usr/config.json

ENTRYPOINT ["pa11y-ci", "-c", "/usr/config.json"]

Tutorials and articles

Here are some useful articles written by Pa11y users and contributors:

Contributing

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

If you're ready to contribute some code, clone this repo locally and commit your code on a new branch.

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 verifications and tests individually:

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

Support and migration

Note

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 release Node.js LTS support Support end date
๐Ÿ”œ 4 >= 18
3 Imminent >= 12 (Ubuntu caveat) May 2024
2 2.4.2 >= 8 2022-05-26
1 1.3 >= 4 2018-04-18

Licence

Licensed under the Lesser General Public License (LGPL-3.0-only).
Copyright ยฉ 2016-2023, Team Pa11y and contributors

pa11y-ci's People

Contributors

42tte avatar aarongoldenthal avatar andrewmee avatar andygout avatar danyalaytekin avatar dependabot[bot] avatar dwightjack avatar einselbst avatar glynnphillips avatar greggles avatar hollsk avatar joeyciechanowicz avatar josebolos avatar ker-an avatar kkoskelin avatar lc512k avatar liamkeaton avatar lorenzoancora avatar mfranzke avatar phillbaker avatar rowanmanning 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

pa11y-ci's Issues

Documentation error for "Viewport"

{
    "defaults": {
        "timeout": 1000,
        "page": {
            "viewport": {
                "width": 320,
                "height": 480
            }
        }
    },
    "urls": [
        "http://pa11y.org/",
        "http://pa11y.org/contributing"
    ]
}

Will make the pa11y-ci to fail on not recognizing "page" object.
I made it to work putting "viewport" dirrectly under the "defaults":

{
    "defaults": {
        "timeout": 1000,
        "viewport": {
            "width": 320,
            "height": 480
        }
    },
    "urls": [
        "http://pa11y.org/",
        "http://pa11y.org/contributing"
    ]
}

Error: failed to launch chrome! with Travis CI

Description

I'm trying to use pa11y-ci to run tests on some local HTML. I created an npm script (pa11y-ci ./src/**/*.html) that runs great locally, but when I try to run pa11y-ci ./src/**/*.html as part of my Travis CI build, I get the following error (which doesn't error my build either):

(node:2604) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!
[0909/041700.423583:FATAL:zygote_host_impl_linux.cc(116)] No usable sandbox! Update your kernel or see https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md for more information on developing with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-sandbox.

Link to build in question: https://travis-ci.org/erickzhao/static-html-webpack-boilerplate/jobs/426233215#L477

Specifications

  • I have pa11y-ci installed as a local package instead of globally
  • I don't have a .pa11yci file
  • pa11y-ci version: ^2.1.1
  • Node versions: v8.11.4 and v10.10.0

Tests that rely on a Cookie header fail after first tests run

We have a test suite that sets a Cookie header with a different value for each test. With the default concurrency of 2, what happens is:

  1. First two tests run, with the correct cookie, all is well
  2. Subsequent tests run, they have a different set of cookies, not the ones that are set in the header.

What I think is happening is that some JS from the first two pages is setting cookies that's overriding what the header tries to use.

We've worked around this by bumping up the concurrency so all the tests are run at once - but wondering if there's a better way to make the tests more idempotent (e.g. clearing cookies after each test?)

/cc @remybach

Pa11y-CI and --sitemap only shows errors and no warnings

I have been trying to get Pa11y-CI to show warnings to me as well while using the --sitemap feature. It will only show errors for some reason.

pa11y-ci --sitemap http://domainname/sitemap --include-warnings fails with error: unknown option --include-warnings'`

pa11y-ci http://domainname --include-warnings works as expected

How can I get warnings to also show when using the --sitemap option?

Ignore specific rules

Hi!
Is there a way to ignore a specific rule?
For example if would like to ignore WCAG2AA.Principle1.Guideline1_4.1_4_3.G18 where should I specify this?

Unable to add rules in config

pa11y-ci 2.1.1

Using the below config.

{
    "defaults": {
        "standard": "WCAG2A",
        "rules": ["Principle1.Guideline1_1.1_1_1.H37"],
        "hideElements": "",
        "ignore": [],
        "includeWarnings": true,
        "timeout": 5000,
        "threshold": 0
    },
    "urls": [
        {
            "url": "https://www.ecster.se",
            "actions": [
            ]
        }]
}

I get:

 Error: Evaluation failed: Error: Principle1.Guideline1_1.1_1_1.H37 is not a valid WCAG 2.0 rule
   at configureHtmlCodeSniffer (<anonymous>:60:13)
   at runPa11y (<anonymous>:30:3)

As far as I understand this is according to the documentation:
https://github.com/pa11y/pa11y#rules-array

Variable name in screenCapture path ?

In the .pa11y config file is there anyway to configure the default to create a screenCapture for each URL checked? I'm loading the URLs from a sitemap.xml but would like to have a snapshot of each page that was checked. Anyway to use a wildcard or variable name in the config?

"level" configuration appears to be ignored

According to the pa11y documentation you should be able to pass level in your configuration file to support a few different use-cases:

  • 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

This does not appear to be respected by pa11y-ci: https://github.com/pa11y/pa11y-ci/blob/master/bin/pa11y-ci.js#L94-L98

In our use-case, we'd like to configure pa11y-ci to with level set to "none" so that we can view errors in accessibility, fix them, and once we hit 0, then change level to "error"

Fails to pass login page since it fails to detect changes in input field.

Hi,
Im trying to setup pa11y-ci in an web application Im working on which has written in AngularJS(1.5.X).
The issue is in the login. Even though pa11y-ci fills the login credentials and hit Sign-in button, the app fails to detect the values in input field and it fails the validations. Looks like keyup or onChange events are not firing hence angular can't trigger digest cycle. I have attached the captured image after pa11y-ci hit Sign-in buttion.

example1

Any heads-up or workarounds for this issue ?

Show errors even when under threshold

I noticed that when errors shown are under the threshold specified, the errors no longer show. Is it possible to make an enhancement to this to add the option of showing these errors anyways? I think it will be good in terms of trying to improve and get rid of these errors before pushing the code to build in our CI pipelines.

Globbing doesn't work in config file

According to #38 globbing got implemented and should work like

pa11y-ci "**/*.html"

This works fine for me. It doesn't work when used in the config file though:

{
    "defaults": {
        "timeout": 10000,
        "threshold": 10
    },
    "urls": [
        "**/*.html"
    ]
}

Throws the error
Error: net::ERR_NAME_NOT_RESOLVED at http://**/*.html

Is globbing just implemented for CLI?

Error: page.on is not a function

Im new to pa11y-ci and getting following error when i run pa11y-ci --config .pa11yci.json command.
Node -v v8.15.0
Any idea on this ?

Running Pa11y on 2 URLs:
 > http://pa11y.org/ - Failed to run
 > http://pa11y.org/contributing - Failed to run

Errors in http://pa11y.org/:

 โ€ข Error: page.on is not a function

Errors in http://pa11y.org/contributing:

 โ€ข Error: page.on is not a function

โœ˜ 0/2 URLs passed

.pa11yci.json file is same as the example given in github repo.

{ "defaults": { "timeout": 1000, "page": { "viewport": { "width": 320, "height": 480 } } }, "urls": [ "http://pa11y.org/", "http://pa11y.org/contributing" ] }

Request for feedback - badges, '--init' flag, environment variables [enhancement ideas]

Hi,

I'm loving and using pa11y-ci. Thank you to all contributors, and the pa11y team!

I've got some suggestions and ideas, that I'd like some feedback on.

Then I may be able to implement them, and create a pull request ...

  1. Suggest badges (via https://shields.io) in the documentation for use in READMEs to promote pa11y-ci, for example, Accessibility testing

    [![Accessibility testing](https://img.shields.io/badge/accessibility-pa11y--ci-blue.svg)](https://github.com/pa11y/pa11y-ci)
    
  2. An --init or --defaults flag.
    pa11y-ci --init would interactively create a .pa11yci.json file, rather like npm init
    pa11y-ci --defaults > .pa11yci.json would dump a default configuration to file.
    (Example, https://gist.github.com/nfreear/785dce9698bcd9656b6d3fa5ffee9b47)

  3. Support for environment variables in .pa11yci.json files.
    Why? Useful when running tests on multiple URLs on a visible, but un-advertised test-server,

    Example,

    export TEST_SRV=https://test.example.org  # Or, set via Travis-CI user-interface.
    
    pa11y-ci -C .pa11yci.json

    Then,

    {
      "defaults": { },
      "urls": [
        "${TEST_SRV}/page1.html",
        "${TEST_SRV}/page2.html",
        "${TEST_SRV}/page3.html",
      ]
    }

Yours,

Nick

(FYI, I've recently blogged about my use of pa11y-ci.)


Running against sitemap index doesn't validate any URLS

Many sites have large sitemaps that are broken up into individual files and coordinated by a sitemap index file. A common example of this is the functionality of the Yoast SEO plugin for WordPress.

More information here about how this works:
https://support.google.com/webmasters/answer/75712?hl=en

When Pa11y CI runs against an index file, it does not find any pages to run against and exits. This means that in order to scan an entire site, you need to run the tool against each individual sitemap listed in the index file.

The desired behavior would be to work recursively and conduct a full site scan when given an index file.

CLI output + save json file?

Is there a way to generate the standard CLI output and save a JSON file without having to run the test twice?

Right now, if I run pa11y-ci --json > pa11y-results.json I get a JSON file, but none of the standard CLI output.

TypeError while printing out accessibility violations

Since upgrading to the latest 2.0.0 release of pa11y-ci I get the following error whenever pa11y-ci is run using a standard other than WCAG2AA (the default). While pa11y-ci runs through the tests just fine, the issue seems to come from one of the dependencies when printing out errors from the test run as seen below.

Note: This errors does not seem to occur when I run the regular non-ci centric pa11y

Environment:

Pa11y:      5.0.3
Node.js:    8.9.4
npm:        5.6.0
OS:         16.7.0 (darwin)
> pa11y-ci -V
2.0.0

Error:

> pa11y-ci --config tests/pa11y/pa11y.json

Running Pa11y on 1 URLs:
 > http://localhost:9090/services - 2 errors

Errors in http://localhost:9090/services:

 โ€ข The heading structure is not logically nested. This h2 element appears to be the primary document heading, so should be an h1 element.

   (#burger-menu-container > div:nth-child(2) > ul > div > h2)

   <h2><a href="javascript:void();">Pr...</h2>
   
/Users/macbookpro/work/project-tr12/node_modules/pa11y-ci/node_modules/async/asyncify.js:108
    throw error;
    ^

TypeError: Cannot read property 'replace' of null
    at report.results.(anonymous function).forEach.result (/Users/macbookpro/work/project-tr12/node_modules/pa11y-ci/lib/pa11y-ci.js:136:40)
    at Array.forEach (native)
    at Object.keys.forEach.url (/Users/macbookpro/work/project-tr12/node_modules/pa11y-ci/lib/pa11y-ci.js:125:27)
    at Array.forEach (native)
    at Object.testRunComplete [as drain] (/Users/macbookpro/work/project-tr12/node_modules/pa11y-ci/lib/pa11y-ci.js:122:33)
    at /Users/macbookpro/work/project-tr12/node_modules/pa11y-ci/node_modules/async/internal/queue.js:113:19
    at /Users/macbookpro/work/project-tr12/node_modules/pa11y-ci/node_modules/async/internal/onlyOnce.js:12:16
    at invokeCallback (/Users/macbookpro/work/project-tr12/node_modules/pa11y-ci/node_modules/async/asyncify.js:101:9)
    at /Users/macbookpro/work/project-tr12/node_modules/pa11y-ci/node_modules/async/asyncify.js:89:17
    at process._tickCallback (internal/process/next_tick.js:109:7)

Use a different runner such as Axe

Can I change the runner for pa11y-ci to AXE I see the default is HTML CodeSniffer?

I may be missing something so I apologize, if I am. I see that with pa11y I can specify a running

pa11y --runner=axe http://localhost:4200/landing

I don't see how to change the runner with Pa11y-ci.

Thank you very much for your help (sry if I shouldn't be using issues to ask this questions)

Allow pa11y-ci to show failed actions & debug logs

Expected Behavior

When running pa11y-ci with a sitemap or multiple urls, I would like to be able to determine which actions failed if a test fails or use browser logs from the tests run if the failure is unrelated to any actions. This would provide for a much easier debugging experience when dealing with 5+ urls.

Similar to how pa11y shows logs when enabled inside the config file. A simple flag or option can easily be used to enable logging for tests in pa11y-ci.

Below is an example of logging from pa11y which could be introduced in pa11y-ci:

Welcome to Pa11y

 > Running Pa11y on URL http://localhost:9090/
 > Debug: Launching Headless Chrome
 > Debug: Opening URL in Headless Chrome
 > Debug: Browser Console: You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html
 > Debug: Browser Console: TEMP: currentuser not set
 > Running actions
 > Debug: Running action: wait for url to be http://localhost:9090/
 > Debug:   โœ”๏ธŽ action complete
 > Debug: Running action: wait for element #loader to be hidden

Note: This could be tied to Issue #15 for easier CI support for logging.

Current Behavior

Currently logs are deleted regardless of any options passed in the config for pa11y-ci. The lines below in pa11y-ci outline where the logging option in the config file is deleted inside pa11y-ci.js:

pa11y-ci/lib/pa11y-ci.js

Lines 47 to 51 in 8dd46ed

// We delete options.log because we don't want it to
// get passed into Pa11y โ€“ we don't want super verbose
// logs from it
const log = options.log;
delete options.log;

When a test does fail because of an action or something else on the page, a generic error is put in place, this makes it very difficult to determine which action failed if there are multiple actions for a particular test or if the issue was unrelated to the actions and had something to do with the test page itself.

Running Pa11y on 1 URLs:
 > http://localhost:9090/ - Failed to run

Errors in http://localhost:9090/:

 โ€ข Error: waiting for function failed: timeout 30000ms exceeded

Impact

Lately while reviewing accessibility violationss found by pa11y-ci it has become increasing difficult to debug issues if a particular test has multiple actions or if the error is related to something on the page instead of an action. I've found myself using pa11y on numerous occasions to get better debug output, but this is both tedious & time consuming when testing multiple urls.

Handling a sitemap that contains pdfs

I would like to use pa11y-ci in a jekyll site. The easiest way seems to be using it with a sitemap, however the site has some pdf files which are included in the sitemap, and pa11y-ci gets an error when it tries to check these:

Error: Error opening url
   "http://localhost:4000/files/file.pdf" :
   undefined

I could possibly remove the pdf files from the sitemap, but AFAIK it's better to include them for search engines to index. Maybe pa11y-ci needs an option to exclude certain files from the sitemap e.g. with a regex? Or is there another way I can handle these?

Error running pa11y-ci against a url with basic authentication.

Hi, I am working to run pa11y-ci using a custom config file with credential. I referred to "How can Pa11y log in if my site's behind basic auth?" from pa11y github but an error "pa11y is not defined" returns.

config.js script:
const credentials = 'mycredential:mypassword';
const encodedCredentials = new Buffer(credentials).toString('base64');

pa11y('https://my.example.com', {
headers: {
Authorization: Basic ${encodedCredentials}
}
});

pa11y-ci -c config.js output:
There was a problem loading "/opt/pa11y-ci/pa11y-ci-master/config":
ReferenceError: pa11y is not defined
at Object. (/opt/pa11y-ci/pa11y-ci-master/config.js:4:1)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at loadLocalConfigWithJs (/usr/lib/node_modules/pa11y-ci/bin/pa11y-ci.js:166:10)
at Promise (/usr/lib/node_modules/pa11y-ci/bin/pa11y-ci.js:120:14)

Please let me know if you need more information.
Thank you in advance !

Running Pa11y-ci with sitemap

@paul-ks commented on Thu Aug 02 2018

Hi, I am running pa11y-ci with a sitemap like that: pa11y-ci --sitemap url of sitemap and I am getting the following message: The sitemap "url of sitemap" could not be loaded.

Also, how can I tell pa11y-ci to point to a sitemap on the filesystem instead of an url?

Thanks,
Paul

Display errors even when the number of errors is within the specified threshold

The new option to allow threshold per URL is ๐Ÿ’ฏ, thanks ๐Ÿ™‡.

I just wondered whether it would be of use to still show what pa11y errors there were, as well as the positive message to say you were within threshold.

Otherwise, you need to change / remove those thresholds and run pa11y again to see what needs fixing. Plus it serves as a reminder that although you're within threshold, you do still have errors that should be addressed.

Default configuration section in Readme has wrong key name

A recent PR (#89) changed the json key of the default configuration option from defaults to default.
As far as I can tell this is incorrect? Config options are not picked up if specified under the default key. Using the previous value of defaults works correctly however.

For example, according to the current documentation this should set the timeout to 1ms (and therefore immediately timeout as an easily reproducible test case). But the config is not picked up, and the request works fine

{
  "default": {
    "timeout": 1
  },
  "urls": [
    "http://pa11y.org/",
    "http://pa11y.org/contributing"
  ]
}

Using the previous key of defaults works fine however, and the short timeout is correctly picked up here (and so the request immediately timeout).

{
  "defaults": {
    "timeout": 1
  },
  "urls": [
    "http://pa11y.org/",
    "http://pa11y.org/contributing"
  ]
}

See https://github.com/pa11y/pa11y-ci/blob/master/bin/pa11y-ci.js#L192 which is referencing config.defaults.
The integration tests also still reference defaults. See https://github.com/pa11y/pa11y-ci/blob/master/test/integration/mock/config/defaults.json

Tested using pally-cli 2.3.0

Could the documentation change please be reverted? Or the code updated to look for the default key.

Thanks for a very useful tool!

Allow --config .myconfig.js

At the moment, passing a JS config fails. It'd be nice if you could pass something other than JSON!


Note: there's a known workaround.

This will load .pa11yci.js if it exists:

$ pa11y-ci

pa11y-ci ends with an npm error after the displaying the results

I have spent hours trying to overcome this issue where the pa11y-ci ends with an error. It throws out the errors and ends with this error below


   (#mat-input-1)

   <input _ngcontent-fgs-c4="" class="mat-input-element
   mat-form-field-autofill-control cdk-text-field-autofill-monitored
   ng-untouched ng-pristine ng-invalid" formcontrolname="password" matinput=""
   onpaste="return false" placeholder="Password" type="pas...

โœ˜ 2/3 URLs passed
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! @[email protected] a11y-report: `pa11y-ci`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the @[email protected] a11y-report script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     C:\Users\M1030316\AppData\Roaming\npm-cache\_logs\2019-06-11T08_10_41_881Z-debug.log


Need quick help in fixing this problem; I am blocked because of this.

this is my .pa11yci

{
  "defaults": {
    "ignore": ["notice"],
    "standard": "WCAG2A"
  },
  "urls": [
    "http://localhost:4200/not-found",
    "http://localhost:4200/not-authorized",
    "http://localhost:4200/admin"
  ]
}

I am just running "pa11y-ci" from the terminal.

When I use pally-ci with localhost I get NO errors, but external urls I get correct errors

When I use pally-ci with localhost I get NO errors, but external urls I get correct errors and warnings.

Does anyone have this issue also.

my .pa11yci.js

module.exports = {
    urls: [
        'http://localhost:8080/#?mpb=topografie&mpz=11&mpv=52.3731081:4.8932945&pgn=home',
        'http://localhost:8080/#?dsd=bag&dsp=1&dsv=TABLE&mpb=topografie&mpz=11&mpv=52.3731081:4.8932945'
    ]
}

external:

module.exports = {
    urls: [
        'http://data.amsterdam.nl/#?mpb=topografie&mpz=11&mpv=52.3731081:4.8932945&pgn=home',
        'http://data.amsterdam.nl/#?dsd=bag&dsp=1&dsv=TABLE&mpb=topografie&mpz=11&mpv=52.3731081:4.8932945'
    ]
}

pa11y-ci error output not as descriptive as pa11y error output

As first noted as a comment in issue 60:

pally-ci does not output the specific guides that fail in the same way pa11y does, instead just a suggestion of how to fix. This means if you want to ignore one rather than fix it then it takes additional research to find out what it is.

Specifically, this was painful when having to search through pa11y issues to discover that WCAG2AA.Principle1.Guideline1_4.1_4_3.G18 is actually added as an ignored rules of WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail - whereas in pa11y main it lists the exact code that fails.

Would it be possible to output the ones that fail, as they are not always exactly the same (as proven) in the list of CodeSniffer Rules?

An example ignore list:

"ignore": [
          "WCAG2AA.Principle2.Guideline2_4.2_4_2.H25.1.NoTitleEl",
          "WCAG2AA.Principle3.Guideline3_1.3_1_1.H57.2",
          "WCAG2AA.Principle1.Guideline1_4.1_4_3.G145.Fail",
          "WCAG2AA.Principle1.Guideline1_4.1_4_3.G18.Fail"
        ],

Is there a way to generate html report using pa11y-ci

is there any way to generate html page output using multiple urls?

I have multiple url in pa11yci.sjon file and I want to save reports to html file so that I can easily embed to Jenkins for report. Is there any way to do?

Run into "Protocol error (Target.createTarget): Target closed" with node 8.11.2

We're running a set of three tests in our project.
The first one seems to run just fine, however, all the other tests fail to run:

Running Pa11y on 3 URLs:
 > https://video-qa.springernature.app/video - 0 errors
 > https://video-qa.springernature.app/video/segment/10.1007/978-1-4842-3635-2_2 - Failed to run
 > https://video-qa.springernature.app/video/10.1007/978-1-4842-3635-2 - Failed to run

Errors in https://video-qa.springernature.app/video/segment/10.1007/978-1-4842-3635-2_2:
 โ€ข Error: Protocol error (Target.createTarget): Target closed.

Errors in https://video-qa.springernature.app/video/10.1007/978-1-4842-3635-2:
 โ€ข Error: Navigation failed because browser has disconnected!

I found out (by chance) that downgrading node to 8.0.0 makes the error go away.
This currently happens with pa11y-ci 1.2.1
Happy to provide more details if required. Thank you!

--config option example?

I'm having trouble figuring out how to use a config file with a simple command line test (or whether one can). I need to go to a URL, click a link, and test the resulting page. Let's say it's the "More information..." link on http://example.com (which goes to https://www.iana.org/domains/reserved).

With this saved in example-test.json

pa11y({
  actions: [
    'click element body > div > p:nth-child(3) > a',
    'wait for url to be https://www.iana.org/domains/reserved'
  ]
});

I would expect that pa11y -c example-test.json http://example.com would output the results for https://www.iana.org/domains/reserved (25 errors), but instead I just get the results for example.com (1 error), as if there was no config file. The examples and sample code are either ambiguous or seem to be aimed at running tests from your own JS so I'm having a hard time seeing what's wrong.

Pa11y-CI cannot be run on https with self-signed certificate

When running Pa11y-CI on test environment with self-signed certificate - then the exception:
"Error: net::ERR_CERT_AUTHORITY_INVALID at https://_ _ _" is thrown. Had tried to use "ignoreHTTPSErrors" but it had no effect.

Is there no way currently to "ignore" the cert errors? Also I think that ignoring cert errors should be default behavior.

Recommended way to pass in a standard

What's the recommended way to pass in a standard to pa11y-ci? For example, with regular pa11y, I can run pa11y --standard 'WCAG2AA' 'someurl.com'. Can I do something similar with pa11y-ci? Maybe in the .pa11y-ci config file? Seems like it's defaulting to 508.

Sitemap find/replace

Sometimes a sitemap's URLs aren't correct when running in a CI environment. E.g if the site is running on localhost:4000 but each URL in it has the live domain name.

We need a way to find/replace in the sitemap URLs I think. Something like this?

pa11y-ci --sitemap http://localhost:4000/ --sitemap-find mysite.com --sitemap-replace localhost:4000

Timeout is ignored (on Jenkins)

I am trying to run the accessibility tests on Jenkins (with CentOS) and I am having a weird issue with the config files. When I use a .json configuration file, works fine. But when I use a .js file to dynamically generate the urls it ignores the timeout set for the url. I just get

Error: waiting for function failed: timeout 30000ms exceeded

no matter the timeout that I specify. I tried also to put the timeout under default, but is the same result. Locally everything runs fine.

Here is the part where I set the urls and actions. After, there is a loop that replaces ${TEST_URL} for the real one. Sadly, I cannot give the real urls.

let urls = [
    {
        url: '${TEST_URL}',
        timeout: 5000000, //Big timeout just to test
        actions: [
            "navigate to ${TEST_URL}/stuff/stuff...", // Intermediate url to add sth to the cart
            "navigate to ${TEST_URL}", //Go back to the main url
            "click element #goToAnotherPageBtn",
            "wait for .some__box to be visible"
        ]
    }
];

Pa11y overrides the specific default HideElements configuration for each individual URL

Hello pa11y team ๐Ÿ‘‹ how are you?

I am a QA engineer trying to use Pa11y in our framework to improve the accessibility levels for our projects. I am really enjoying this tool so far. But today I came across a specific case that is the reason of this 'issue', or as I might say "an improvement".

Let's consider the following .pa11yci config file:

{
"defaults": {
"timeout": 1000,
"hideElements": ".hiddingAGlobalElement", ".alsoHiddingAnotherGlobalOne"
},
"urls": [
"http://pa11y.org/",
{
"url": "http://pa11y.org/contributing",
"hideElements": ".advert, #modal, div[aria-role=presentation]"
},
{
"url": "http://pa11y.org/news/",
"hideElements": ".someOtherElement, #ignoreMe"
]
}
]
}

When I run it, Pa11y seems to be overriding the local hideElements values when I have a global HideElements defined. And in my current example I would like to have global HideElements as they appear for every page I am testing, but also I would like to hide unique elements (that are not conform with the accessibility standards) for every page I am testing.

A current workaround is duplicating every global HideElement for each individual URLs (what I think it's not great).

Let me know if you need more info and please share your thoughts about this suggestion ๐Ÿ˜„

Thank you guys ๐Ÿ‘

Save to file even if the job fails

Use case: in a CI Job it would be nice to have an artifact with reported errors/warnings/etc. and also let the job fail.

At the moment, using the redirection (eg. > accessibility-report.html), pa11y-ci fails and it doesn't write anything to file.

Using pa11y-ci v2.3.0 and pa11y-reporter-html v1.0.0 in a GitLab pipeline.

Running from Docker

I have created Docker image base on mode:10-jessie and installed all pre-requisites for Chrome. This should be used to run in Concourse CI.

Now when I run:

/node_modules/.bin/pa11y-ci --json

I get:

(node:3142) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!
[1008/134337.709535:ERROR:zygote_host_impl_linux.cc(89)] Running as root without --no-sandbox is not supported. See https://crbug.com/638180.


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

    at onClose (/node_modules/puppeteer/lib/Launcher.js:339:14)
    at Interface.helper.addEventListener (/node_modules/puppeteer/lib/Launcher.js:328:50)
    at Interface.emit (events.js:187:15)
    at Interface.close (readline.js:379:8)
    at Socket.onend (readline.js:157:10)
    at Socket.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1092:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
(node:3142) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:3142) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

If I run with unprivileged node user:

su -l node -c "/node_modules/.bin/pa11y-ci --json"

I get this output:

(node:3156) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!
[1008/134509.521725:FATAL:zygote_host_impl_linux.cc(116)] No usable sandbox! Update your kernel or see https://chro
mium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md for more information on developi
ng with the SUID sandbox. If you want to live dangerously and need an immediate workaround, you can try using --no-
sandbox.
#0 0x55eb1afcecac base::debug::StackTrace::StackTrace()
#1 0x55eb1af48670 logging::LogMessage::~LogMessage()
#2 0x55eb1c44c050 service_manager::ZygoteHostImpl::Init()
#3 0x55eb1ac11d7e content::ContentMainRunnerImpl::Initialize()
#4 0x55eb1ac453e8 service_manager::Main()
#5 0x55eb1ac105c1 content::ContentMain()
#6 0x55eb1f0e9ae8 headless::(anonymous namespace)::RunContentMain()
#7 0x55eb1f0e9b78 headless::HeadlessBrowserMain()
#8 0x55eb1ac429db headless::HeadlessShellMain()
#9 0x55eb18f501ac ChromeMain
#10 0x7f2a1bc69b45 __libc_start_main
#11 0x55eb18f5002a _start

Received signal 6                                                                                         [15/7885]
#0 0x55eb1afcecac base::debug::StackTrace::StackTrace()
#1 0x55eb1afce821 base::debug::(anonymous namespace)::StackDumpSignalHandler()
#2 0x7f2a21d1b890 <unknown>
#3 0x7f2a1bc7d067 gsignal
#4 0x7f2a1bc7e448 abort
#5 0x55eb1afcd645 base::debug::BreakDebugger()
#6 0x55eb1af48ae8 logging::LogMessage::~LogMessage()
#7 0x55eb1c44c050 service_manager::ZygoteHostImpl::Init()
#8 0x55eb1ac11d7e content::ContentMainRunnerImpl::Initialize()
#9 0x55eb1ac453e8 service_manager::Main()
#10 0x55eb1ac105c1 content::ContentMain()
#11 0x55eb1f0e9ae8 headless::(anonymous namespace)::RunContentMain()
#12 0x55eb1f0e9b78 headless::HeadlessBrowserMain()
#13 0x55eb1ac429db headless::HeadlessShellMain()
#14 0x55eb18f501ac ChromeMain
#15 0x7f2a1bc69b45 __libc_start_main
#16 0x55eb18f5002a _start
  r8: 00007f2a2231ca00  r9: 00001b0a2297a000 r10: 0000000000000008 r11: 0000000000000202
 r12: 00007fffc0c061c8 r13: 0000000000000161 r14: 00007fffc0c061d0 r15: 00007fffc0c061d8
  di: 0000000000000c61  si: 0000000000000c61  bp: 00007fffc0c05bf0  bx: 00007fffc0c05c50
  dx: 0000000000000006  ax: 0000000000000000  cx: 00007f2a1bc7d067  sp: 00007fffc0c05ab8
  ip: 00007f2a1bc7d067 efl: 0000000000000202 cgf: 002b000000000033 erf: 0000000000000000
 trp: 0000000000000000 msk: 0000000000000000 cr2: 0000000000000000
[end of stack trace]
Calling _exit(1). Core file will not be generated.


TROUBLESHOOTING: https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md

    at onClose (/node_modules/puppeteer/lib/Launcher.js:339:14)
    at Interface.helper.addEventListener (/node_modules/puppeteer/lib/Launcher.js:328:50)
    at Interface.emit (events.js:187:15)
    at Interface.close (readline.js:379:8)
    at Socket.onend (readline.js:157:10)
    at Socket.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1092:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)
(node:3156) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:3156) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Only WCAG2AA

Pa11y has options for Section508, WCAG2A & WCAG2AA. I don't see anywhere in the docs or code for Pa11y-ci to use the other options

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.