Teach agents to automate accessibility testing in CI with pa11y and pa11y-ci, including thresholds, sitemap crawling, GitHub Actions gating, and WCAG rule tuning.
npx skills add https://github.com/PramodDutta/qaskills --skill Pa11y Accessibility CI
You are an accessibility automation engineer who adds reliable pa11y and pa11y-ci checks to web delivery pipelines without treating scanners as a replacement for manual WCAG review.
WCAG2AA or stricter rules in config so upgrades do not silently change expectations.Install pa11y-ci into the web project.
npm install --save-dev pa11y pa11y-ci start-server-and-test
npm pkg set scripts.a11y='pa11y-ci --config .pa11yci.cjs'
npm pkg set scripts.preview='vite --host 127.0.0.1'
npm pkg set scripts.a11y:local='start-server-and-test preview http://127.0.0.1:5173 a11y'
Use a dedicated config file instead of long CLI flags.
// .pa11yci.cjs
const baseUrl = process.env.PREVIEW_URL || 'http://127.0.0.1:5173';
module.exports = {
defaults: {
standard: 'WCAG2AA',
timeout: 30000,
wait: 500,
chromeLaunchConfig: {
args: ['--no-sandbox', '--disable-dev-shm-usage'],
},
hideElements: '.third-party-chat, .cookie-banner-test-only',
},
urls: [
`${baseUrl}/`,
`${baseUrl}/pricing`,
`${baseUrl}/login`,
`${baseUrl}/dashboard`,
],
threshold: 0,
reporters: ['cli', 'json'],
};
Create a small accessibility automation area that the whole team can understand.
.
.github/
workflows/
accessibility.yml
accessibility/
urls.json
crawl-sitemap.mjs
known-issues.md
.pa11yci.cjs
package.json
Use sitemap crawling when the product has many public pages.
sitemap.xml from the preview deployment.// accessibility/crawl-sitemap.mjs
import { writeFile } from 'node:fs/promises';
const origin = process.env.PREVIEW_URL || 'http://127.0.0.1:5173';
const sitemapUrl = `${origin}/sitemap.xml`;
const response = await fetch(sitemapUrl);
if (!response.ok) {
throw new Error(`Could not fetch sitemap: ${response.status}`);
}
const xml = await response.text();
const urls = [...xml.matchAll(/<loc>(.*?)<\/loc>/g)]
.map((match) => match[1])
.filter((url) => url.startsWith(origin))
.filter((url) => !url.includes('/logout'))
.slice(0, Number(process.env.PA11Y_MAX_URLS || 50));
await writeFile('accessibility/urls.json', `${JSON.stringify(urls, null, 2)}\n`);
console.log(`Wrote ${urls.length} URLs for pa11y-ci`);
Point the config at the generated list when required.
// .pa11yci.cjs
const urls = require('./accessibility/urls.json');
module.exports = {
defaults: {
standard: 'WCAG2AA',
timeout: 30000,
},
urls,
threshold: Number(process.env.PA11Y_THRESHOLD || 0),
};
Run the accessibility gate after the app builds and the preview server starts.
name: accessibility
on:
pull_request:
push:
branches: [main]
jobs:
pa11y:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npm run build
- run: npm run a11y:local
- uses: actions/upload-artifact@v4
if: always()
with:
name: pa11y-results
path: pa11y-ci-results.json
Use ignore only when there is a documented reason.
module.exports = {
defaults: {
standard: 'WCAG2AA',
ignore: [
// Temporary until design system token QA-1284 is fixed.
'color-contrast',
],
},
urls: ['http://127.0.0.1:5173/'],
threshold: 0,
};
When pa11y fails, inspect the page, selector, context, and rule.
npm run a11y:local.| Need | Pa11y Choice | Agent Action |
|---|---|---|
| Small public site | Static urls list | Keep direct route coverage explicit |
| Large marketing site | Sitemap crawler | Cap URL count and exclude unsafe paths |
| Pull request gate | threshold: 0 | Fail new violations immediately |
| Legacy app | Temporary threshold | Track debt and lower threshold over time |
| Third-party widget noise | hideElements | Hide only non-product widgets |
| Rule exception | ignore | Require issue link and expiry |
threshold high forever.hideElements.10. Not pinning Node and browser versions in CI.
WCAG2AA or stricter.Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.
Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.
Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
Guidance for distinctive, intentional visual design when building new UI or reshaping an existing one. Helps with aesthetic direction, typography, and making choices that don't read as templated defaults.
Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling
Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally.
Take pramoddutta/pa11y accessibility ci from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.
The instructions reference npm.
Without those the skill loads but fails at the first command.