
Accessibility Compliance Accessibility Audit
Run WCAG-oriented automated accessibility audits on live URLs and turn axe-core violation reports into a prioritized fix list before release.
Overview
Accessibility Compliance Accessibility Audit is an agent skill most often used in Ship (also Build frontend, Ship review) that automates WCAG accessibility scans with axe-core and Puppeteer and returns scored violation r
Install
npx skills add https://github.com/sickn33/antigravity-awesome-skills --skill accessibility-compliance-accessibility-auditWhat is this skill?
- Puppeteer-driven full-page scans with axe-core tagged for wcag2a, wcag2aa, wcag21a, and wcag21aa
- Structured violation export with impact, help URLs, node HTML, targets, and failure summaries
- Configurable WCAG level (default AA) and viewport for consistent desktop audits
- Weighted accessibility score from critical, serious, moderate, and minor impact buckets
- Exclude regions such as .no-a11y-check to skip decorative or third-party embeds
- Default WCAG level AA
- Four WCAG tag groups in analyze()
- Impact weights for critical, serious, moderate, and minor
Adoption & trust: 449 installs on skills.sh; 40.1k GitHub stars; 2/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are about to ship UI changes but have no consistent automated pass that maps failures to WCAG rules and severities.
Who is it for?
Indie SaaS or marketing sites where you want axe-core automation you can wire into local scripts or agent-driven QA without buying another dashboard.
Skip if: Teams that only need keyboard-only or screen-reader manual testing with no browser automation, or apps with zero URL-based surfaces to load in Puppeteer.
When should I use this skill?
You need to implement or run automated accessibility audits with axe-core and Puppeteer against production-like viewports.
What do I get? / Deliverables
You get a timestamped audit JSON with categorized violations, node-level targets, and an impact-weighted score to drive fixes before users hit barriers.
- Timestamped audit result object with violations array
- Per-node failure summaries and selectors
- Impact-weighted accessibility score
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Shipping is the canonical shelf because accessibility audits are a pre-release quality gate aligned with QA and launch readiness. Testing subphase fits automated a11y checks that complement manual review and regression suites.
Where it fits
After building a new checkout form, run a full-page axe scan to catch missing labels and contrast failures before merge.
Gate a release candidate by auditing staging URLs and blocking ship when critical impact violations remain.
Attach structured violation JSON to a human PR review so reviewers focus on nodes axe flagged.
Re-run the auditor after a hotfix to confirm regression fixes did not reintroduce serious issues.
How it compares
Use as a procedural axe+Puppeteer audit recipe instead of guessing WCAG checks in chat without executable test harness code.
Common Questions / FAQ
Who is accessibility-compliance-accessibility-audit for?
Solo and indie builders shipping web UIs who want agent-guided WCAG automation patterns with axe-core and Puppeteer rather than ad-hoc checklist reviews.
When should I use accessibility-compliance-accessibility-audit?
During Ship testing before a release, while validating redesigned Build frontend pages, and when re-auditing after component library changes that affect landmarks, contrast, or focus order.
Is accessibility-compliance-accessibility-audit safe to install?
Review the Security Audits panel on this Prism page for the upstream skill package; the playbook itself runs local browser automation against URLs you choose and does not assert third-party audit pass counts here.
SKILL.md
READMESKILL.md - Accessibility Compliance Accessibility Audit
# Accessibility Audit and Testing Implementation Playbook This file contains detailed patterns, checklists, and code samples referenced by the skill. ## Instructions ### 1. Automated Testing with axe-core ```javascript // accessibility-test.js const { AxePuppeteer } = require("@axe-core/puppeteer"); const puppeteer = require("puppeteer"); class AccessibilityAuditor { constructor(options = {}) { this.wcagLevel = options.wcagLevel || "AA"; this.viewport = options.viewport || { width: 1920, height: 1080 }; } async runFullAudit(url) { const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.setViewport(this.viewport); await page.goto(url, { waitUntil: "networkidle2" }); const results = await new AxePuppeteer(page) .withTags(["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"]) .exclude(".no-a11y-check") .analyze(); await browser.close(); return { url, timestamp: new Date().toISOString(), violations: results.violations.map((v) => ({ id: v.id, impact: v.impact, description: v.description, help: v.help, helpUrl: v.helpUrl, nodes: v.nodes.map((n) => ({ html: n.html, target: n.target, failureSummary: n.failureSummary, })), })), score: this.calculateScore(results), }; } calculateScore(results) { const weights = { critical: 10, serious: 5, moderate: 2, minor: 1 }; let totalWeight = 0; results.violations.forEach((v) => { totalWeight += weights[v.impact] || 0; }); return Math.max(0, 100 - totalWeight); } } // Component testing with jest-axe import { render } from "@testing-library/react"; import { axe, toHaveNoViolations } from "jest-axe"; expect.extend(toHaveNoViolations); describe("Accessibility Tests", () => { it("should have no violations", async () => { const { container } = render(<MyComponent />); const results = await axe(container); expect(results).toHaveNoViolations(); }); }); ``` ### 2. Color Contrast Validation ```javascript // color-contrast.js class ColorContrastAnalyzer { constructor() { this.wcagLevels = { 'AA': { normal: 4.5, large: 3 }, 'AAA': { normal: 7, large: 4.5 } }; } async analyzePageContrast(page) { const elements = await page.evaluate(() => { return Array.from(document.querySelectorAll('*')) .filter(el => el.innerText && el.innerText.trim()) .map(el => { const styles = window.getComputedStyle(el); return { text: el.innerText.trim().substring(0, 50), color: styles.color, backgroundColor: styles.backgroundColor, fontSize: parseFloat(styles.fontSize), fontWeight: styles.fontWeight }; }); }); return elements .map(el => { const contrast = this.calculateContrast(el.color, el.backgroundColor); const isLarge = this.isLargeText(el.fontSize, el.fontWeight); const required = isLarge ? this.wcagLevels.AA.large : this.wcagLevels.AA.normal; if (contrast < required) { return { text: el.text, currentContrast: contrast.toFixed(2), requiredContrast: required, foreground: el.color, background: el.backgroundColor }; } return null; }) .filter(Boolean); } calculateContrast(fg, bg) { const l1 = this.relativeLuminance(this.parseColor(fg)); const l2 = this.relativeLuminance(this.parseColor(bg)); const lighter = Math.max(l1, l2); const