Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
version: 2
updates:
- package-ecosystem: 'npm'
allow:
- dependency-type: 'production'
directory: '/'
schedule:
interval: 'weekly'
labels:
- 'dependencies'
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'daily'
labels:
- 'dependencies'
9 changes: 6 additions & 3 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ on:
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
registry-url: https://registry.npmjs.org
- run: npm ci

Expand All @@ -26,7 +29,7 @@ jobs:
if: >
(github.event_name == 'release' && github.event.action == 'published') ||
(github.event_name == 'workflow_dispatch' && !inputs.dryRun)
run: npm publish
run: npm publish --provenance --access public

- name: Publish package (dry run)
env:
Expand Down
16 changes: 12 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,17 @@ on:
- main
pull_request:

permissions:
contents: read

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: 18
node-version: 22
- run: npm ci
- run: npm run lint

Expand All @@ -22,15 +25,20 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
node-version: [18, 20]
node-version: [20.0.0]
steps:
- name: Normalise line-ending handling in Git
shell: bash
run: |
git config --global core.autocrlf false
if: runner.os == 'Windows'
- name: Disable AppArmor User Namespace Restrictions, required to open
Chrome on Ubuntu 23.10+ without --no-sandbox). See
https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md.
run: echo 0 | sudo tee /proc/sys/kernel/apparmor_restrict_unprivileged_userns
if: runner.os == 'Linux'
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci
Expand Down
1 change: 0 additions & 1 deletion .npmrc

This file was deleted.

1 change: 0 additions & 1 deletion .nvmrc

This file was deleted.

24 changes: 24 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
# Changelog

## 4.0.0 (2025-07-22)

Pa11y CI 4.0.0 requires a stable (even-numbered) Node.js version of `20` or above, updates to the latest version of Pa11y (`9`) and Puppeteer (`24`), updates several other dependencies, and includes some GitHub actions and documentation cleanup. See the [migration guide](https://github.com/pa11y/pa11y-ci/blob/main/MIGRATION.md#migrating-from-30-to-40) for details.

### Changes

* **Breaking**: Upgrade Node.js support: Pa11y CI 4 requires a stable (even-numbered) Node.js version of `20` or above, dropping support for Node 12, 14, 16, 18.
* **Breaking**: Upgrade `pa11y` to `9` (from `6`), which updates numerous dependencies, fixes issues with Pa11y CI failing to run on Ubuntu 24.04, and resolves several vulnerabilities and deprecated packages (closing [#198](https://github.com/pa11y/pa11y-ci/issues/198), [#227](https://github.com/pa11y/pa11y-ci/issues/227), [#242](https://github.com/pa11y/pa11y-ci/issues/242), [#247](https://github.com/pa11y/pa11y-ci/issues/247)).
* Upgrade `puppeteer` to `24` (from `9.1`), which updates to the current Chrome. This changes Chrome's default headless mode, see the [migration guide](https://github.com/pa11y/pa11y-ci/blob/main/MIGRATION.md#migrating-from-30-to-40) for details. Also expand the `puppeteer` dependency compatibility to caret (patch and minor releases) to allow upgrades to a more recent compatible version upon install (which frequently contains Chrome updates and security patches).
* Upgrade `axe-core` to `4.10` from `4.2`. This includes rule fixes that may change results when using the `axe` runner. See axe-core [releases](https://github.com/dequelabs/axe-core/releases) for complete details.
* Upgrade `semver` to `7.7` from `7.3`, resolving [CVE-2022-25883](https://github.com/advisories/GHSA-c2qf-rxjj-qqgw).
* Fixed issue with `pa11y-ci` process hanging if `browser` passed from config file. (#248)
* Other dependency upgrades: `commander` to `14.0`, `async` to `3.2`, `cheerio` to `1.1`, and `node-fetch` to `2.7`.
* GitHub Actions changes: Update workflows for supported Node version, [Ubuntu 24.04 compatibility](https://chromium.googlesource.com/chromium/src/+/main/docs/security/apparmor-userns-restrictions.md), and [publishing package with provenance](https://github.blog/security/supply-chain-security/introducing-npm-package-provenance/).
* Other changes: Refactor code and tests for dependency compatibility, update support table and fix some links in the README.

See the [migration guide](https://github.com/pa11y/pa11y-ci/blob/main/MIGRATION.md#migrating-from-30-to-40) for details.

### Full changelog

[3.1.0...4.0.0](https://github.com/pa11y/pa11y-ci/compare/3.1.0...4.0.0)

### Changes

## 3.1.0 (2023-11-14)

### Changes
Expand Down
15 changes: 15 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

Major versions of Pa11y CI can bring API or compatibility changes. This is a guide to help you make the switch when that happens.

## Migrating from 3.0 to 4.0

Pa11y CI v4 requires a stable (even-numbered) Node.js version of 20 or above.

We've also upgraded to Pa11y 9 (from 6), which includes upgrading to Puppeteer 24 (from 20) and Axe 4.10 (from 4.8), as well as more recent major versions of several other dependencies - see the Pa11y CI [changelog](https://github.com/pa11y/pa11y-ci/blob/main/CHANGELOG.md) for the complete list.

Puppeteer v22 and subs default to Chrome's [_new_ headless mode](https://developer.chrome.com/docs/chromium/new-headless) to more closely mimic the behavior of headful Chrome. This may affect performance; see the [Puppeteer docs](https://github.com/puppeteer/puppeteer?tab=readme-ov-file#default-runtime-settings) for more information.

* If you were using a `chromeLaunchConfig` with `headless: 'new'`, change to `headless: true` or remove the `headless` setting as `true` is now the default.
* If you were using a `chromeLaunchConfig` with `headless: true` or no `headless` setting, and want to continue use the previous headless mode, change to `headless: 'shell'`.

The Pa11y upgrade incorporates an upgrade of `axe-core` to `4.10` from `4.2`, which contains rule fixes that may change results when using the `axe` runner. See axe-core [releases](https://github.com/dequelabs/axe-core/releases) for complete details.

See the `pa11y` [migration guide](https://github.com/pa11y/pa11y/blob/main/MIGRATION.md) for details on other changes from 6.0 to 9.0, which should not affect most users of Pa11y CI.

## Migrating from 2.0 to 3.0

### New defaults for `concurrency` and `useIncognitoBrowserContext`
Expand Down
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@ Use this tool to test against a list of URLs or a sitemap, and report on issues

## Requirements

This command line tool requires a stable (even-numbered) [Node.js] version of 18 or above.
This command line tool requires a stable (even-numbered) [Node.js] version of 20 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][ubuntu-fix], 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.
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][ubuntu-fix], as `defaults.chromeLaunchConfig.executablePath`. Version 4 of Pa11y CI, which uses Pa11y 9 along with a more recent version of Puppeteer, resolves this issue.

## Usage

Expand Down Expand Up @@ -409,17 +409,17 @@ When we release a new major version we will continue to support the previous maj

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](#pa11y-ci-3-and-ubuntu))| May 2024 |
| `2` | `2.4.2` | `>= 8` | 2022-05-26 |
| `1` | `1.3` | `>= 4` | 2018-04-18 |
| Major version | Final minor release | Node.js LTS support | Support end date |
| :------------ | :------------------ | :------------------ | :----------------------- |
| `4` | | `20`, `22`, `24` | ✅ Current major version |
| `3` | `3.1.0` | `>= 12` ([Ubuntu caveat](#pa11y-ci-3-and-ubuntu))| 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)](LICENSE).
Copyright © 2016-2023, Team Pa11y and contributors
Copyright © 2016-2025, Team Pa11y and contributors

[glob]: https://github.com/isaacs/node-glob#glob
[node.js]: https://nodejs.org/
Expand Down
11 changes: 6 additions & 5 deletions bin/pa11y-ci.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const path = require('path');
const globby = require('globby');
const protocolify = require('protocolify');
const pkg = require('../package.json');
const commander = require('commander');

const {Command} = require('commander');
const commander = new Command();

// Here we're using Commander to specify the CLI options
commander
Expand Down Expand Up @@ -55,6 +55,7 @@ commander
'--reporter <reporter>',
'the reporter to use. Can be a npm module or a path to a local file.'
)
.allowExcessArguments()
.parse(process.argv);

// Parse the args into valid paths using glob and protocolify
Expand Down Expand Up @@ -100,15 +101,15 @@ Promise.resolve()
// Decide on an exit code based on whether
// errors are below threshold or everything passes
if (report.errors >= parseInt(options.threshold, 10) && report.passes < report.total) {
process.exitCode = 2;
process.exit(2);
} else {
process.exitCode = 0;
process.exit(0);
}
})
.catch(error => {
// Handle any errors
console.error(error.message);
process.exitCode = 1;
process.exit(1);
});

// This function loads the JSON or JavaScript config
Expand Down
10 changes: 5 additions & 5 deletions lib/pa11y-ci.js
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@

// This is the actual test runner, which the queue will
// execute on each of the URLs
async function testRunner(config) {

Check warning on line 108 in lib/pa11y-ci.js

View workflow job for this annotation

GitHub Actions / lint

Async function 'testRunner' has too many statements (16). Maximum allowed is 15
let url;
if (typeof config === 'string') {
url = config;
Expand All @@ -118,7 +118,7 @@
await cycleReporters(reporters, 'begin', url);

config.browser = config.useIncognitoBrowserContext ?
await testBrowser.createIncognitoBrowserContext() :
await testBrowser.createBrowserContext() :
testBrowser;

// Run the Pa11y test on the current URL and add
Expand All @@ -140,11 +140,11 @@
// This function is called once all of the URLs in the
// queue have been tested. It outputs the actual errors
// that occurred in the test as well as a pass/fail ratio
function testRunComplete() {
testBrowser.close();

async function testRunComplete() {
await testBrowser.close();
await cycleReporters(reporters, 'afterAll', report, options);
// Resolve the promise with the report
cycleReporters(reporters, 'afterAll', report, options).then(() => resolve(report));
resolve(report);
}

});
Expand Down
Loading
Loading