{"_id":"@a11y-pulse/audit-runner","_rev":"4-3451aa92bbbcc44194106684be799371","name":"@a11y-pulse/audit-runner","dist-tags":{"latest":"0.4.0"},"versions":{"0.1.0":{"name":"@a11y-pulse/audit-runner","version":"0.1.0","keywords":["accessibility","a11y","wcag","audit","cli","puppeteer"],"author":{"name":"A11y Pulse"},"license":"SEE LICENSE IN LICENSE.md","_id":"@a11y-pulse/audit-runner@0.1.0","maintainers":[{"name":"wildlyinaccurate","email":"joseph@wildlyinaccurate.com"}],"homepage":"https://github.com/A11y-Pulse/audits/tree/main/packages/audit-runner#readme","bugs":{"url":"https://github.com/A11y-Pulse/audits/issues"},"bin":{"a11y-pulse-runner":"dist/cli.js"},"dist":{"shasum":"ea9c871c23edc3676fa51d8fc50276d4edcc37df","tarball":"https://registry.npmjs.org/@a11y-pulse/audit-runner/-/audit-runner-0.1.0.tgz","fileCount":14,"integrity":"sha512-Bpi2v6N556N2ycG9Rl7rA1Qm6rVPuLmIvRxxWbKXVW5Sxsw3zF4loUfI3b+7vWuS2kbEUylH4IGp+RDzemQDFw==","signatures":[{"sig":"MEUCICOGclGZoAFysad78r8indMhrT/43yS75xZMIr1LV9+wAiEArEJqrqhfbiX+twQp5M/p85+ttfZszEt+AWg769xExDY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":32268},"type":"module","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"2e5aee53c3cf02c4878ad76572eabfefe206c141","scripts":{"lint":"biome check","test":"npm run typecheck && npm run test:unit","build":"tsup && tsc -p tsconfig.build.json","lint:fix":"biome check --fix","test:unit":"vitest run","typecheck":"tsc --noEmit","prepublishOnly":"npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"wildlyinaccurate","email":"joseph@wildlyinaccurate.com"},"repository":{"url":"git+https://github.com/A11y-Pulse/audits.git","type":"git","directory":"packages/audit-runner"},"_npmVersion":"11.11.0","description":"Simple example tool that runs all A11y Pulse accessibility audits","directories":{},"_nodeVersion":"24.13.0","dependencies":{"puppeteer":"^25.9.0","@a11y-pulse/reflow-audit":"*","@a11y-pulse/browser-adaptor":"*","@a11y-pulse/skip-link-audit":"*","@a11y-pulse/tab-orchestrator":"*","@a11y-pulse/text-spacing-audit":"*","@a11y-pulse/focus-appearance-audit":"*","@a11y-pulse/focus-not-obscured-audit":"*","@a11y-pulse/context-change-on-focus-audit":"*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/audit-runner_0.1.0_1788827481909_0.8637858185406135","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@a11y-pulse/audit-runner","version":"0.2.0","keywords":["accessibility","a11y","wcag","audit","cli","puppeteer"],"author":{"name":"A11y Pulse"},"license":"SEE LICENSE IN LICENSE.md","_id":"@a11y-pulse/audit-runner@0.2.0","maintainers":[{"name":"wildlyinaccurate","email":"joseph@wildlyinaccurate.com"}],"homepage":"https://github.com/A11y-Pulse/audits/tree/main/packages/audit-runner#readme","bugs":{"url":"https://github.com/A11y-Pulse/audits/issues"},"bin":{"a11y-pulse-runner":"dist/cli.js"},"dist":{"shasum":"e2aa4087898be061962c7045c212604f4fca078a","tarball":"https://registry.npmjs.org/@a11y-pulse/audit-runner/-/audit-runner-0.2.0.tgz","fileCount":14,"integrity":"sha512-aTePOU/9MJ9cCKcaUu0Vwk7rl4+sClYOdE0HZAoobpBEEEabspoNfeO8yA1BChzwIaL8jnx0SiJtunS7vpNNjg==","signatures":[{"sig":"MEUCIHNdJ32Zt7bKkqkL8NPXC57drzTcVSBvTRoixlY9Of91AiEA1vH73IDkdBmOhNpntOPYw0mbOXkBFO+AtUYJb6ZzXtg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@a11y-pulse%2faudit-runner@0.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":32268},"type":"module","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"8431177b6098e09064306dc08bddfb59796b444d","scripts":{"lint":"biome check","test":"npm run typecheck && npm run test:unit","build":"tsup && tsc -p tsconfig.build.json","lint:fix":"biome check --fix","test:unit":"vitest run","typecheck":"tsc --noEmit","prepublishOnly":"npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b84920e9-8444-4761-b884-da71e1ffb065"}},"repository":{"url":"git+https://github.com/A11y-Pulse/audits.git","type":"git","directory":"packages/audit-runner"},"_npmVersion":"12.0.2","description":"Simple example tool that runs all A11y Pulse accessibility audits","directories":{},"_nodeVersion":"22.23.2","dependencies":{"puppeteer":"^25.9.0","@a11y-pulse/reflow-audit":"*","@a11y-pulse/browser-adaptor":"*","@a11y-pulse/skip-link-audit":"*","@a11y-pulse/tab-orchestrator":"*","@a11y-pulse/text-spacing-audit":"*","@a11y-pulse/focus-appearance-audit":"*","@a11y-pulse/focus-not-obscured-audit":"*","@a11y-pulse/context-change-on-focus-audit":"*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/audit-runner_0.2.0_1788834846436_0.710732403024843","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@a11y-pulse/audit-runner","version":"0.3.0","keywords":["accessibility","a11y","wcag","audit","cli","puppeteer"],"author":{"name":"A11y Pulse"},"license":"MIT","_id":"@a11y-pulse/audit-runner@0.3.0","maintainers":[{"name":"wildlyinaccurate","email":"joseph@wildlyinaccurate.com"}],"homepage":"https://github.com/A11y-Pulse/audits/tree/main/packages/audit-runner#readme","bugs":{"url":"https://github.com/A11y-Pulse/audits/issues"},"bin":{"a11y-pulse-runner":"dist/cli.js"},"dist":{"shasum":"e1f839cc78cea45e12e55f406259be88f4760fea","tarball":"https://registry.npmjs.org/@a11y-pulse/audit-runner/-/audit-runner-0.3.0.tgz","fileCount":14,"integrity":"sha512-yr65vEJs4eGYgzIctpkTXkDUNm8XLk45te26uj8oGwmIZMANLWHgKF3ygMpsuZkeIzhQBFmHzI6ZSb8a68002w==","signatures":[{"sig":"MEQCIFmK6fbdUbHQ0KaQDlhIaT670l8LY5Z7slSdD5tIrKUFAiBmfTdF/BlUKPAjNMZL321x5zujHkF/VFOj8Z0RfFXpWA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@a11y-pulse%2faudit-runner@0.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":27075},"type":"module","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"3c0154a99848ea8c609ebec30fca8faf6226bc69","scripts":{"lint":"biome check","test":"npm run typecheck && npm run test:unit","build":"tsup && tsc -p tsconfig.build.json","lint:fix":"biome check --fix","test:unit":"vitest run","typecheck":"tsc --noEmit","prepublishOnly":"npm run build","test:integration":"vitest run --config vitest.integration.config.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b84920e9-8444-4761-b884-da71e1ffb065"}},"repository":{"url":"git+https://github.com/A11y-Pulse/audits.git","type":"git","directory":"packages/audit-runner"},"_npmVersion":"12.0.2","description":"Simple example tool that runs all A11y Pulse accessibility audits","directories":{},"_nodeVersion":"22.23.2","dependencies":{"puppeteer":"^25.9.0","@a11y-pulse/reflow-audit":"*","@a11y-pulse/browser-adaptor":"*","@a11y-pulse/skip-link-audit":"*","@a11y-pulse/tab-orchestrator":"*","@a11y-pulse/text-spacing-audit":"*","@a11y-pulse/focus-appearance-audit":"*","@a11y-pulse/focus-not-obscured-audit":"*","@a11y-pulse/context-change-on-focus-audit":"*"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/audit-runner_0.3.0_1789121897597_0.5635563170988094","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@a11y-pulse/audit-runner","version":"0.4.0","description":"Simple example tool that runs all A11y Pulse accessibility audits","type":"module","license":"MIT","author":{"name":"A11y Pulse"},"homepage":"https://github.com/A11y-Pulse/audits/tree/main/packages/audit-runner#readme","repository":{"type":"git","url":"git+https://github.com/A11y-Pulse/audits.git","directory":"packages/audit-runner"},"bugs":{"url":"https://github.com/A11y-Pulse/audits/issues"},"keywords":["accessibility","a11y","wcag","audit","cli","puppeteer","playwright"],"engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"bin":{"a11y-pulse-runner":"dist/cli.js"},"scripts":{"build":"tsup && tsc -p tsconfig.build.json","typecheck":"tsc --noEmit","lint":"biome check","lint:fix":"biome check --fix","test:unit":"vitest run","test:integration":"vitest run --config vitest.integration.config.ts","test":"npm run typecheck && npm run test:unit","prepublishOnly":"npm run build"},"publishConfig":{"access":"public"},"dependencies":{"@a11y-pulse/browser-adaptor":"*","@a11y-pulse/context-change-on-focus-audit":"*","@a11y-pulse/focus-appearance-audit":"*","@a11y-pulse/focus-not-obscured-audit":"*","@a11y-pulse/reflow-audit":"*","@a11y-pulse/skip-link-audit":"*","@a11y-pulse/tab-orchestrator":"*","@a11y-pulse/text-spacing-audit":"*","axe-core":"^4.13.0","puppeteer":"^25.10.0"},"peerDependencies":{"playwright-core":">=1.40"},"peerDependenciesMeta":{"playwright-core":{"optional":true}},"devDependencies":{"playwright-core":"^1.63.0"},"gitHead":"facc34c09fbb3982d29a1dc04944b5d035af7780","_id":"@a11y-pulse/audit-runner@0.4.0","_nodeVersion":"22.23.2","_npmVersion":"12.0.2","dist":{"integrity":"sha512-ej8pTRX1G1mg3KL6hqvDFABWWeSrvpbDrIWQjsEOCr75BRNEKL8IhqueTUVn6c1Fw7U2gJ/ClcqeCcpLjRzXkQ==","shasum":"dcc3ec0f1b28583a03a617a26075d7edcb156357","tarball":"https://registry.npmjs.org/@a11y-pulse/audit-runner/-/audit-runner-0.4.0.tgz","fileCount":23,"unpackedSize":89449,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@a11y-pulse%2faudit-runner@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFxN7NiTsl6KTDMseqvfV8i5ZQlpQ2QJSesAHGLMGJtEAiAhO3MzLPhKjHxpvEMrWYFj922B3JsZBBXucZkGXcK9Hg=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b84920e9-8444-4761-b884-da71e1ffb065"}},"directories":{},"maintainers":[{"name":"wildlyinaccurate","email":"joseph@wildlyinaccurate.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/audit-runner_0.4.0_1789286278193_0.6270612182316921"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-08T00:31:21.688Z","modified":"2026-09-13T07:57:58.647Z","0.1.0":"2026-09-08T00:31:22.037Z","0.2.0":"2026-09-08T02:34:06.562Z","0.3.0":"2026-09-11T10:18:17.737Z","0.4.0":"2026-09-13T07:57:58.329Z"},"bugs":{"url":"https://github.com/A11y-Pulse/audits/issues"},"author":{"name":"A11y Pulse"},"license":"MIT","homepage":"https://github.com/A11y-Pulse/audits/tree/main/packages/audit-runner#readme","keywords":["accessibility","a11y","wcag","audit","cli","puppeteer","playwright"],"repository":{"type":"git","url":"git+https://github.com/A11y-Pulse/audits.git","directory":"packages/audit-runner"},"description":"Simple example tool that runs all A11y Pulse accessibility audits","maintainers":[{"name":"wildlyinaccurate","email":"joseph@wildlyinaccurate.com"}],"readme":"# @a11y-pulse/audit-runner\n\n[![npm version](https://img.shields.io/npm/v/@a11y-pulse/audit-runner)](https://www.npmjs.com/package/@a11y-pulse/audit-runner)\n[![CI](https://github.com/A11y-Pulse/audits/actions/workflows/ci.yml/badge.svg)](https://github.com/A11y-Pulse/audits/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/license-MIT-green)](./LICENSE.md)\n\nA simple command line interface that runs axe-core and all A11y Pulse audits against a single page. Results are reported in the axe-core format.\n\nThis package also exists as a reference for your own audit pipeline. If you would like to explore the code, a good starting point is [`src/run-audits.ts`](./src/run-audits.ts).\n\n## Install\n\n```bash\nnpm install @a11y-pulse/audit-runner\n```\n\nBy default this package runs audits using Puppeteer. If you would like to use Playwright, you will need to install it with `npm install playwright-core && npx playwright-core install`.\n\n## CLI\n\n```bash\nnpx @a11y-pulse/audit-runner https://who.likesdogs.nz/\n```\n\nLaunches headless Chromium at a 1280x800 viewport, loads the URL, runs every audit, and writes the combined axe-core report to stdout as JSON. Pipe it wherever you like:\n\n```bash\nnpx @a11y-pulse/audit-runner https://who.likesdogs.nz/ | jq '.violations[].id'\n```\n\n`--engine playwright` drives the page with Playwright rather than Puppeteer, and `--browser` then picks the engine to launch:\n\n```bash\nnpx @a11y-pulse/audit-runner https://who.likesdogs.nz/ --engine playwright --browser webkit\n```\n\n| Option | Values | Default |\n| --- | --- | --- |\n| `--engine` | `puppeteer`, `playwright` | `puppeteer` |\n| `--browser` | `chromium`, `firefox`, `webkit` | `chromium` |\n\n`--browser` requires `--engine playwright`. Firefox and WebKit tab in their own order and apply their own `:focus-visible` heuristics, so results will not match Chromium's element for element.\n\nThe exit code reports whether the run itself succeeded, not whether the page passed: a page with violations still exits `0`. A bad URL or a crashed browser exits `1`, with the message on stderr.\n\n## Browser support\n\n| Adaptor | Browser | Supported |\n| --- | --- | --- |\n| Puppeteer | Chrome | Yes |\n| Playwright | Chromium | Yes |\n| Playwright | WebKit | **No.** The keyboard-driven audits it runs are unsupported on WebKit, which does not move focus to links when Tab is pressed. |\n| Playwright | Firefox | **Partial.** Reflow, text spacing, skip link and context change match Chromium; focus appearance and focus not obscured differ in the cases noted in their own READMEs. |\n\n## `runAllAudits`\n\n```js\nimport { runAllAudits } from \"@a11y-pulse/audit-runner\";\nimport { PuppeteerAdaptor } from \"@a11y-pulse/browser-adaptor/puppeteer\";\nimport { PuppeteerAdaptor as ReflowAdaptor } from \"@a11y-pulse/reflow-audit/puppeteer\";\nimport { PuppeteerAdaptor as TextSpacingAdaptor } from \"@a11y-pulse/text-spacing-audit/puppeteer\";\nimport puppeteer from \"puppeteer\";\n\nconst browser = await puppeteer.launch();\nconst page = await browser.newPage();\nawait page.goto(\"https://who.likesdogs.nz/\");\n\nconst results = await runAllAudits({\n\tbrowser: new PuppeteerAdaptor(page),\n\treflow: new ReflowAdaptor(page),\n\ttextSpacing: new TextSpacingAdaptor(page),\n});\n\nconsole.log(results.violations.map((audit) => audit.id));\n// ['color-contrast', 'focus-appearance', 'reflow']\n\nawait browser.close();\n```\n\n`runAllAudits(adaptors, options?)` takes one adaptor per audit interface, all three wrapping the same already-loaded page. Swap in the `PlaywrightAdaptor` from each of those subpaths to run the same audits under Playwright; nothing else changes.\n\n`options` takes each audit's own options object under its key, all optional. `axe` is passed straight to `axe.run()`:\n\n```js\nconst results = await runAllAudits(adaptors, {\n\taxe: { runOnly: [\"wcag2a\", \"wcag2aa\"] },\n\tfocusAppearance: { elementLimit: 50, skipStyleCheck: true },\n\treflow: { screenshotLimit: 3 },\n});\n```\n\n## Results\n\nThe return value is in the shape of [axe-core's results object](https://github.com/dequelabs/axe-core/blob/develop/doc/API.md#results-object). The A11y Pulse audit results included with the following audit IDs:\n\n| Audit | `id` |\n| --- | --- |\n| Focus appearance (WCAG 2.4.7) | `focus-appearance` |\n| Focus not obscured (WCAG 2.4.11) | `focus-not-obscured` |\n| Context change on focus (WCAG 3.2.1) | `context-change-on-focus` |\n| Skip link activation (WCAG 2.4.1) | `skip-link-activation` |\n| Reflow (WCAG 1.4.10) | `reflow` |\n| Text spacing (WCAG 1.4.12) | `text-spacing` |\n\n## JSON output\n\nAudit evidence is attached to the node it belongs to, as a single axe-core check under `any`, carrying PNG bytes as raw `Uint8Array`s. `toJson` is a thin `JSON.stringify` wrapper that encodes those as base64:\n\n```json\n{\n  \"url\": \"https://who.likesdogs.nz/\",\n  \"violations\": [\n    {\n      \"id\": \"reflow\",\n      \"help\": \"Content must reflow without two-dimensional scrolling\",\n      \"impact\": \"serious\",\n      \"tags\": [\"wcag21aa\", \"wcag1410\", \"cat.structure\"],\n      \"nodes\": [\n        {\n          \"target\": [\"#wide\"],\n          \"html\": \"<div id=\\\"wide\\\">\",\n          \"failureSummary\": \"Element is overflowing the viewport by 580px…\",\n          \"any\": [\n            {\n              \"id\": \"reflow-evidence\",\n              \"impact\": \"serious\",\n              \"message\": \"Element overflows the 320px reflow viewport\",\n              \"data\": { \"screenshot\": \"iVBORw0KGgoAAAANSUhEUg…\" }\n            }\n          ],\n          \"all\": [],\n          \"none\": []\n        }\n      ]\n    }\n  ]\n}\n```\n\n## Releasing\n\nReleases are managed in the [A11y-Pulse/audits](https://github.com/A11y-Pulse/audits) monorepo with [Changesets](https://github.com/changesets/changesets). Publishing uses [npm trusted publishing](https://docs.npmjs.com/trusted-publishers/) (OIDC). There is no long-lived `NPM_TOKEN`.\n\n### Ship a change\n\n1. Open a PR against `main` that includes a changeset (`npx changeset`) naming `@a11y-pulse/audit-runner`.\n2. After merge, the Release workflow opens a Version PR. Merging that PR publishes this package to npm and tags `@a11y-pulse/audit-runner@<version>`.\n\nTrusted Publisher on npm must stay configured for:\n\n| Field | Value |\n| --- | --- |\n| Organization or user | `A11y-Pulse` |\n| Repository | `audits` |\n| Workflow filename | `release.yml` |\n\n## License\n\n[MIT](./LICENSE.md). Use it however you like, including in commercial and competing products.\n\nThe audit packages in this repository are licensed separately, under the\n[PolyForm Shield License 1.0.0](../../LICENSE.md).\n","readmeFilename":"README.md"}