npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

playwright-a11y-runner

v1.3.0

Published

Unified accessibility testing for Playwright - plug-and-play Axe Core integration with zero test code changes

Readme

Playwright A11y Runner

A simple plug-and-play accessibility testing solution for Playwright that automatically scans your web pages for accessibility issues using axe-core.


Table of Contents

  1. What is this?
  2. Why This Package? (axe-core vs this)
  3. How it Works
  4. Installation
  5. Quick Start
  6. Configuration Options
  7. Usage Methods
  8. Environment Variables
  9. WCAG Standards
  10. Understanding Results
  11. Examples
  12. Troubleshooting

What is this?

This package adds automatic accessibility testing to your Playwright tests.

When you run your tests, it will:

  • Scan each page for accessibility problems
  • Report issues in the console
  • Optionally fail tests if issues are found

Why use it?

| Without this package | With this package | |---------------------|-------------------| | Manual accessibility testing | Automatic scanning | | Issues found late in development | Issues caught during testing | | Requires accessibility expertise | Built-in WCAG standards | | Extra code needed | Zero code changes |


Why This Package?

You might ask: "Why do I need this package when axe-core and @axe-core/playwright already exist?"

Great question! Here's the answer:

The Problem with Using axe-core Directly

When you use @axe-core/playwright directly, every test needs boilerplate code:

// ❌ Using @axe-core/playwright directly - LOTS OF CODE!
const { test, expect } = require('@playwright/test');
const AxeBuilder = require('@axe-core/playwright').default;

test('homepage', async ({ page }) => {
  await page.goto('https://example.com');
  
  // You have to add ALL of this to EVERY test:
  const accessibilityScanResults = await new AxeBuilder({ page })
    .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
    .analyze();
  
  expect(accessibilityScanResults.violations).toEqual([]);
});

test('about page', async ({ page }) => {
  await page.goto('https://example.com/about');
  
  // Same boilerplate AGAIN:
  const accessibilityScanResults = await new AxeBuilder({ page })
    .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
    .analyze();
  
  expect(accessibilityScanResults.violations).toEqual([]);
});

// Repeat for EVERY test... 😫

The Solution: This Package

// ✅ Using this package - ZERO EXTRA CODE!
const { test, expect } = require('@org/playwright-a11y');

test('homepage', async ({ page }) => {
  await page.goto('https://example.com');
  // Accessibility scan happens automatically! ✨
});

test('about page', async ({ page }) => {
  await page.goto('https://example.com/about');
  // Accessibility scan happens automatically! ✨
});

Side-by-Side Comparison

| Aspect | axe-core directly | This package | |--------|-------------------|--------------| | Setup per test | 5-10 lines of code | 0 lines | | Configuration | Manual in each test | Central config file | | WCAG standards | Must specify tags manually | Pre-configured | | Existing tests | Rewrite every test | Change 1 import line | | Consistency | Varies by developer | Always consistent | | Forgot to add scan? | No accessibility check | Always scans | | Learning curve | Learn axe-core API | Just works |

Visual Comparison

┌─────────────────────────────────────────────────────────────────┐
│                    USING AXE-CORE DIRECTLY                       │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   Test 1          Test 2          Test 3          Test 4        │
│   ┌──────┐        ┌──────┐        ┌──────┐        ┌──────┐     │
│   │ Your │        │ Your │        │ Your │        │ Your │     │
│   │ Code │        │ Code │        │ Code │        │ Code │     │
│   ├──────┤        ├──────┤        ├──────┤        ├──────┤     │
│   │ Axe  │        │ Axe  │        │ Axe  │        │ Axe  │     │
│   │Setup │        │Setup │        │Setup │        │Setup │     │
│   │ Code │        │ Code │        │ Code │        │ Code │     │
│   └──────┘        └──────┘        └──────┘        └──────┘     │
│                                                                  │
│   ⚠️ Boilerplate repeated in EVERY test                         │
│   ⚠️ Easy to forget                                              │
│   ⚠️ Inconsistent configuration                                  │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐
│                    USING THIS PACKAGE                            │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│              ┌─────────────────────────────┐                    │
│              │     Central Config          │                    │
│              │     (a11y.config.js)        │                    │
│              └──────────────┬──────────────┘                    │
│                             │                                    │
│         ┌───────────────────┼───────────────────┐               │
│         │                   │                   │               │
│         ▼                   ▼                   ▼               │
│   ┌──────────┐        ┌──────────┐        ┌──────────┐         │
│   │  Test 1  │        │  Test 2  │        │  Test 3  │         │
│   │ (just    │        │ (just    │        │ (just    │         │
│   │  your    │        │  your    │        │  your    │         │
│   │  code)   │        │  code)   │        │  code)   │         │
│   └──────────┘        └──────────┘        └──────────┘         │
│                             │                                    │
│              ┌──────────────┴──────────────┐                    │
│              │   Automatic A11y Scanning   │                    │
│              │   (handled by package)      │                    │
│              └─────────────────────────────┘                    │
│                                                                  │
│   ✅ Zero boilerplate                                            │
│   ✅ Never forgotten                                             │
│   ✅ Always consistent                                           │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

Key Benefits Over Raw axe-core

| Benefit | Description | |---------|-------------| | 🚀 Zero Config | Works out of the box with sensible defaults | | 🔄 Automatic | Scans run without adding any code to tests | | 📁 Central Config | One config file controls all tests | | 🎯 Consistent | Same scanning rules across entire project | | ⚡ Instant Setup | Change one import, get full coverage | | 🛡️ Never Forget | Can't accidentally skip accessibility checks | | 📊 Better Output | Formatted, readable console output | | 🔧 Environment Control | Enable/disable via environment variables | | 🎛️ Flexible | Manual scanning when you need control |

When to Use What

| Scenario | Recommendation | |----------|----------------| | New project with many tests | ✅ Use this package | | Existing test suite | ✅ Use this package (just change import) | | Need automatic scanning | ✅ Use this package | | Want central configuration | ✅ Use this package | | Need custom axe-core plugins | ⚠️ Use axe-core directly | | One-off script | Either works | | Complex custom scanning logic | ⚠️ Use axe-core directly |

Summary

This package = axe-core + automation + configuration + convenience

We use axe-core under the hood. We just make it effortless to use in Playwright tests.

┌────────────────────────────────────────┐
│           THIS PACKAGE                 │
│  ┌──────────────────────────────────┐  │
│  │        Your Tests                │  │
│  │  ┌────────────────────────────┐  │  │
│  │  │     Playwright Fixtures    │  │  │
│  │  │  ┌──────────────────────┐  │  │  │
│  │  │  │  @axe-core/playwright│  │  │  │
│  │  │  │  ┌────────────────┐  │  │  │  │
│  │  │  │  │    axe-core    │  │  │  │  │
│  │  │  │  └────────────────┘  │  │  │  │
│  │  │  └──────────────────────┘  │  │  │
│  │  └────────────────────────────┘  │  │
│  └──────────────────────────────────┘  │
└────────────────────────────────────────┘

We wrap axe-core to make YOUR life easier.

How it Works

┌─────────────────────────────────────────────────────────────────┐
│                        YOUR TEST RUNS                           │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                    TEST NAVIGATES TO PAGE                        │
│                    (e.g., page.goto('/home'))                   │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                     YOUR TEST COMPLETES                          │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│              AUTOMATIC ACCESSIBILITY SCAN                        │
│                                                                  │
│  ┌────────────────┐    ┌────────────────┐    ┌───────────────┐ │
│  │   axe-core     │ => │  Analyze DOM   │ => │ Report Issues │ │
│  │   injected     │    │  for issues    │    │ to console    │ │
│  └────────────────┘    └────────────────┘    └───────────────┘ │
└─────────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌─────────────────────────────────────────────────────────────────┐
│                 RESULTS IN PLAYWRIGHT REPORT                     │
└─────────────────────────────────────────────────────────────────┘

Simple Explanation

  1. You write tests - Just normal Playwright tests
  2. Import our test - Use our test instead of Playwright's
  3. Tests run normally - Your tests work exactly the same
  4. We scan automatically - After each test, we check for accessibility issues
  5. See results - Issues appear in console and Playwright's report

Installation

Step 1: Install the package

npm install @org/playwright-a11y

Step 2: Install peer dependencies (if not already installed)

npm install @playwright/test

What gets installed?

| Package | Purpose | |---------|---------| | @org/playwright-a11y | This package | | @axe-core/playwright | Accessibility scanning engine | | axe-core | Accessibility rules database |


Quick Start

Use the CLI

Run your tests with the accessibility CLI wrapper:

npx playwright-a11y test

This runs Playwright with accessibility testing enabled.


WCAG Standards

WCAG (Web Content Accessibility Guidelines) are international standards for web accessibility.

Available Standards

| Standard | Description | Best For | |----------|-------------|----------| | wcag2a | WCAG 2.0 Level A | Minimum compliance | | wcag2aa | WCAG 2.0 Level AA | Legal compliance (most common) | | wcag21a | WCAG 2.1 Level A | Mobile accessibility basics | | wcag21aa | WCAG 2.1 Level AA | Recommended - Modern standard | | wcag22aa | WCAG 2.2 Level AA | Latest standard | | best-practice | Best practices | Beyond WCAG requirements | | all | All rules | Maximum coverage |

Choosing a Standard

┌─────────────────────────────────────────────────────────────────┐
│                    WCAG COMPLIANCE LEVELS                        │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│   Level A    ──────────>   Level AA   ──────────>   Level AAA   │
│   (Minimum)                (Standard)               (Highest)    │
│                                                                  │
│   • Basic                  • Required by            • Ideal but  │
│     accessibility            most laws               not always  │
│   • Must have              • Industry                possible    │
│                              standard                            │
│                                                                  │
└─────────────────────────────────────────────────────────────────┘

RECOMMENDATION: Use 'wcag21aa' for most projects

Understanding Results

Severity Levels

Issues are categorized by how much they impact users:

| Level | Icon | Impact | Example | |-------|------|--------|---------| | Critical | 🔴 | Blocks users completely | Missing form labels | | Serious | 🟠 | Major difficulty | Low color contrast | | Moderate | 🟡 | Some difficulty | Missing skip links | | Minor | 🔵 | Slight inconvenience | Redundant alt text |

Console Output Example

📋 Accessibility scan for: homepage loads correctly
   URL: https://example.com/
  ✗ Found 3 accessibility violation(s):

  1. 🔴 [CRITICAL] image-alt
     Images must have alternate text
     Help: https://dequeuniversity.com/rules/axe/4.8/image-alt
     Affected elements (2):
       - img.hero-image
       - img.product-photo

  2. 🟠 [SERIOUS] color-contrast
     Elements must have sufficient color contrast
     Help: https://dequeuniversity.com/rules/axe/4.8/color-contrast
     Affected elements (1):
       - p.disclaimer

  3. 🟡 [MODERATE] region
     All page content should be contained by landmarks
     Help: https://dequeuniversity.com/rules/axe/4.8/region
     Affected elements (1):
       - div.floating-banner

When No Issues Found

📋 Accessibility scan for: contact page
   URL: https://example.com/contact
  ✓ No accessibility violations found

Troubleshooting

Common Issues

| Problem | Cause | Solution | |---------|-------|----------| | "Cannot find module" | Package not installed | Run npm install @org/playwright-a11y | | Scans not running | Disabled in config | Check enabled: true in config | | Too many violations | Scanning third-party content | Add exclusions to scope.exclude | | Tests too slow | Scanning every page | Use scanTiming: 'manual' | | False positives | Rules too strict | Add to rules.exclude |

File Structure

your-project/
├── node_modules/
│   └── @org/playwright-a11y/
│       ├── bin/
│       │   └── playwright-a11y.js    # CLI entry point
│       ├── src/
│       │   ├── index.js              # Main exports
│       │   ├── axe-runner.js         # Axe scanning logic
│       │   ├── cli.js                # CLI implementation
│       │   ├── config.js             # Configuration handling
│       │   └── fixtures.js           # Playwright fixtures
│       ├── package.json
│       └── README.md
├── tests/
│   └── example.spec.js               # Your tests
├── a11y.config.js                    # Optional config file
└── playwright.config.js              # Playwright config

Quick Reference Card

Imports

const { test, expect } = require('@org/playwright-a11y');        // Basic
const { withA11y } = require('@org/playwright-a11y');            // Wrapper
const { scanPage } = require('@org/playwright-a11y');            // Standalone

Fixtures Available in Tests

| Fixture | Purpose | |---------|---------| | page | Standard Playwright page (with auto-scan) | | a11yConfig | Current accessibility configuration | | a11yResults | Array of scan results | | runA11yScan | Function to trigger manual scan | | checkA11y | Function to check specific elements |

CLI Commands

npx playwright-a11y test                    # Run all tests
npx playwright-a11y test tests/home.spec.js # Run specific file
npx playwright-a11y --help                  # Show help
npx playwright-a11y --version               # Show version

Need Help?

  1. Check the troubleshooting section
  2. Review axe-core rules documentation
  3. Read WCAG guidelines