Blog

How to Add Accessibility Testing to Your CI/CD Pipeline

TestParty
TestParty
October 31, 2025

Adding accessibility testing to your CI/CD pipeline prevents WCAG violations from reaching production. This tutorial walks through implementation step by step—from choosing your testing approach to configuring GitHub Actions to handling failures effectively. Development teams using CI/CD accessibility integration catch issues when fixes cost minutes instead of thousands of dollars in lawsuit settlements.

The shift-left approach catches violations during development, before users encounter barriers or plaintiff attorneys document violations.


What You'll Learn

This tutorial covers everything needed for CI/CD accessibility integration.

  • Choosing between testing approaches
  • Setting up GitHub Actions workflows
  • Configuring TestParty Bouncer
  • Using open source alternatives
  • Handling test failures effectively
  • Transitioning from advisory to blocking mode

Prerequisites

Before starting, ensure you have:

  • A GitHub repository with your web project
  • Node.js installed (for build processes)
  • Basic familiarity with GitHub Actions
  • Repository admin access (for secrets and workflow configuration)

Step 1: Choose Your Testing Approach

Multiple approaches exist for CI/CD accessibility testing. Your choice depends on your needs and resources.

Option A: TestParty Bouncer (Recommended)

TestParty's Bouncer provides integrated CI/CD accessibility testing with expert remediation support.

Best for: Teams wanting complete accessibility coverage without building custom solutions.

Includes:

  • GitHub-native integration with PR comments
  • Expert context for violations (not just error codes)
  • Connection to Spotlight production scanning
  • Access to professional remediation
  • <1% of customers sued track record

Option B: Open Source Tools

Tools like axe-core, Pa11y, and Lighthouse provide free accessibility testing.

Best for: Teams with accessibility expertise who can implement fixes internally.

Includes:

  • Detection capability (70-80% of WCAG)
  • Configurable rules and thresholds
  • No subscription cost

Does not include:

  • Remediation (your team fixes everything)
  • Expert guidance
  • Production monitoring integration

Decision Matrix

+---------------------------+-------------------+----------------------------+
|            Need           |      Bouncer      |        Open Source         |
+---------------------------+-------------------+----------------------------+
|       Detection only      |         âś“         |             âś“              |
+---------------------------+-------------------+----------------------------+
|     Expert remediation    |         âś“         |             âś—              |
+---------------------------+-------------------+----------------------------+
|       PR integration      |         âś“         |       Requires setup       |
+---------------------------+-------------------+----------------------------+
|   Production monitoring   |   âś“ (Spotlight)   |       Separate tool        |
+---------------------------+-------------------+----------------------------+
|        Ongoing cost       |    Subscription   |   Free (+ internal time)   |
+---------------------------+-------------------+----------------------------+

Step 2: Set Up GitHub Actions (Bouncer)

If using TestParty Bouncer, follow these steps.

2A: Connect Your Repository

  1. Sign in to TestParty at testparty.ai
  2. Navigate to Integrations → GitHub
  3. Authorize TestParty's GitHub App
  4. Select repositories to connect

This grants TestParty access to create PR comments and workflow integration.

2B: Generate API Key

  1. In TestParty dashboard, go to Settings → API
  2. Generate a new API key
  3. Copy the key (you won't see it again)

2C: Add Secret to GitHub

  1. In your GitHub repository, go to Settings → Secrets → Actions
  2. Click "New repository secret"
  3. Name: `TESTPARTYAPIKEY`
  4. Value: Paste your API key
  5. Click "Add secret"

2D: Create Workflow File

Create `.github/workflows/accessibility.yml`:

name: Accessibility Testing
on:
  pull_request:
    branches: [main, develop]

jobs:
  bouncer:
    name: TestParty Bouncer
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Build project
        run: npm run build

      - name: Start server
        run: npm run start &

      - name: Wait for server
        run: npx wait-on http://localhost:3000

      - name: Run Bouncer
        uses: testparty/bouncer-action@v1
        with:
          api-key: ${{ secrets.TESTPARTY_API_KEY }}
          url: http://localhost:3000

2E: Commit and Test

  1. Commit the workflow file to a new branch
  2. Open a pull request
  3. Watch the Bouncer check run
  4. Review results in PR comments

Step 3: Set Up GitHub Actions (Open Source)

If using open source tools, follow these steps.

3A: Install Testing Dependencies

Add axe-core and Playwright (for browser automation) to your project:

npm install --save-dev @axe-core/playwright playwright

3B: Create Test File

Create `tests/accessibility.spec.js`:

const { test, expect } = require('@playwright/test');
const AxeBuilder = require('@axe-core/playwright').default;

test.describe('Accessibility', () => {
  test('homepage has no violations', async ({ page }) => {
    await page.goto('/');

    const results = await new AxeBuilder({ page })
      .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
      .analyze();

    expect(results.violations).toEqual([]);
  });

  test('product page has no violations', async ({ page }) => {
    await page.goto('/products/example');

    const results = await new AxeBuilder({ page })
      .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
      .analyze();

    expect(results.violations).toEqual([]);
  });

  // Add tests for other critical pages
});

3C: Add Test Script

In `package.json`, add:

{
  "scripts": {
    "test:a11y": "playwright test tests/accessibility.spec.js"
  }
}

3D: Create Workflow File

Create `.github/workflows/accessibility.yml`:

name: Accessibility Testing
on:
  pull_request:
    branches: [main, develop]

jobs:
  accessibility:
    name: Accessibility Checks
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Install Playwright browsers
        run: npx playwright install --with-deps chromium

      - name: Build project
        run: npm run build

      - name: Start server
        run: npm run start &

      - name: Wait for server
        run: npx wait-on http://localhost:3000

      - name: Run accessibility tests
        run: npm run test:a11y

3E: Commit and Test

  1. Commit dependencies, test file, and workflow
  2. Open a pull request
  3. Watch the accessibility check run
  4. Review any failures in the Actions log

Step 4: Configure Testing Scope

Decide what pages to test in CI/CD.

Critical Path Testing

Test the most important user journeys rather than every page.

For e-commerce sites, critical paths typically include homepage, product listing page, product detail page, cart, checkout flow, account pages, and search results.

const criticalPaths = [
  '/',
  '/products',
  '/products/example-product',
  '/cart',
  '/checkout',
  '/account',
  '/search?q=test'
];

criticalPaths.forEach(path => {
  test(`${path} has no violations`, async ({ page }) => {
    await page.goto(path);
    const results = await new AxeBuilder({ page }).analyze();
    expect(results.violations).toEqual([]);
  });
});

Component Testing

For faster feedback, test components in isolation.

test('Button component is accessible', async ({ page }) => {
  // Render component in isolation
  await page.goto('/storybook/button');

  const results = await new AxeBuilder({ page })
    .include('.button-component')
    .analyze();

  expect(results.violations).toEqual([]);
});

Viewport Testing

Test multiple viewports to catch mobile-specific issues.

const viewports = [
  { width: 1280, height: 720, name: 'desktop' },
  { width: 768, height: 1024, name: 'tablet' },
  { width: 375, height: 667, name: 'mobile' }
];

viewports.forEach(viewport => {
  test(`homepage accessible at ${viewport.name}`, async ({ page }) => {
    await page.setViewportSize({
      width: viewport.width,
      height: viewport.height
    });
    await page.goto('/');

    const results = await new AxeBuilder({ page }).analyze();
    expect(results.violations).toEqual([]);
  });
});

Step 5: Handle Test Failures

Effective CI/CD accessibility requires clear failure handling.

Understanding Failure Output

When tests fail, you'll see output like:

Violations found:
  - color-contrast (critical): 2 occurrences
    Elements must have sufficient color contrast
    Elements:
      - #header-text (contrast ratio: 3.2:1, expected 4.5:1)
      - .footer-link (contrast ratio: 2.8:1, expected 4.5:1)

  - label (serious): 1 occurrence
    Form elements must have labels
    Elements:
      - input#email-subscribe

Each violation includes the rule violated, severity, number of occurrences, and specific elements.

Fixing Violations

For each violation, determine if it's a new issue introduced by the PR, an existing issue exposed by new tests, or a false positive (rare but possible).

New issues should be fixed before merge. Existing issues may be acceptable to document and address separately. False positives can be suppressed with rule configuration.

Suppressing False Positives

If you encounter false positives, suppress specific rules:

const results = await new AxeBuilder({ page })
  .disableRules(['specific-false-positive-rule'])
  .analyze();

Use suppression sparingly—most "false positives" are real issues worth fixing.


Step 6: Transition from Advisory to Blocking

Start in advisory mode during adoption, then transition to blocking.

Advisory Mode (Starting Point)

In advisory mode, tests run and report results but don't block merge.

jobs:
  accessibility:
    runs-on: ubuntu-latest
    continue-on-error: true  # Don't fail the workflow
    steps:
      - name: Run accessibility tests
        run: npm run test:a11y

Use advisory mode when:

  • First adopting CI/CD accessibility
  • Clearing backlog of existing violations
  • Training team on accessibility requirements

Blocking Mode (Target State)

In blocking mode, accessibility failures prevent merge.

jobs:
  accessibility:
    runs-on: ubuntu-latest
    # No continue-on-error, failures block merge
    steps:
      - name: Run accessibility tests
        run: npm run test:a11y

Use blocking mode when:

  • Existing violations are cleared
  • Team understands what triggers failures
  • You're ready to maintain standards going forward

Transition Process

  1. Enable advisory mode and monitor for 2-4 weeks
  2. Track violations and address existing issues
  3. Train team on common violations and fixes
  4. Announce transition date
  5. Enable blocking mode
  6. Maintain standards going forward

Step 7: Monitor and Improve

CI/CD accessibility is ongoing, not one-time setup.

Track Trends

Monitor metrics over time: violations per PR (should decrease), false positive rate (should be low), fix time (should decrease as team learns), and rule coverage (should expand).

Expand Coverage

Start with critical paths, then expand to all public pages, authenticated user flows, admin interfaces, and error states.

Integrate with Production Monitoring

CI/CD catches issues during development. Production monitoring catches issues from content changes and edge cases CI/CD missed.

TestParty's Spotlight provides daily production scanning. Other tools require separate production monitoring setup.

Update Dependencies

Keep accessibility testing tools updated. New versions catch more issues and reduce false positives.

npm update @axe-core/playwright playwright

Common Issues and Solutions

Troubleshooting common CI/CD accessibility problems.

Server Not Ready

Symptom: Tests fail with connection errors.

Solution: Ensure server is fully started before tests run.

- name: Start server
  run: npm run start &
- name: Wait for server
  run: npx wait-on http://localhost:3000 --timeout 60000

Tests Too Slow

Symptom: CI/CD pipeline times out or is excessively slow.

Solution:

  • Test fewer pages in CI/CD
  • Run comprehensive tests nightly instead of per-PR
  • Use component testing for fast feedback

Inconsistent Results

Symptom: Tests pass locally but fail in CI (or vice versa).

Solution:

  • Ensure CI and local environments match
  • Check for timing-dependent issues
  • Use consistent browser versions

Too Many Violations

Symptom: First run shows hundreds of violations.

Solution:

  • Start with advisory mode
  • Prioritize critical violations
  • Address violations in batches
  • Consider TestParty for expert remediation help

Next Steps

After implementing CI/CD accessibility testing:

  1. Clear existing violations using TestParty remediation or internal resources
  2. Enable blocking mode once baseline is clean
  3. Add production monitoring with Spotlight or equivalent
  4. Schedule periodic manual audits for non-automatable criteria
  5. Train team on accessibility fundamentals

Frequently Asked Questions

How do I add accessibility testing to my CI/CD pipeline?

Add accessibility testing to CI/CD by creating a GitHub Actions workflow that runs automated checks on pull requests. Use TestParty Bouncer for integrated testing with expert support, or open source tools like axe-core with Playwright for detection-only testing. Configure the workflow to build your project, start a server, and run accessibility checks before allowing merge.

Should accessibility tests block PRs from merging?

Eventually, yes—blocking mode prevents regressions. Start with advisory mode during adoption to clear existing violations without blocking development. Transition to blocking mode once existing issues are addressed and the team understands accessibility requirements. Most teams transition within 2-4 weeks of initial setup.

What's the difference between Bouncer and axe-core?

Both provide automated accessibility detection. Axe-core is an open source library—you build the testing infrastructure and implement fixes yourself. TestParty Bouncer is an integrated solution including GitHub-native PR comments, expert remediation access, connection to production monitoring (Spotlight), and a zero-lawsuit customer track record. Bouncer is a complete solution; axe-core is a building block.

How many pages should CI/CD test?

Test critical user paths rather than every page—homepage, product pages, cart, checkout, and account flows for e-commerce. Component-level tests provide fast feedback. Reserve comprehensive full-site testing for nightly runs or production monitoring. Balance coverage against CI/CD execution time.

What percentage of violations can CI/CD testing catch?

CI/CD accessibility testing catches 70-80% of WCAG violations—the objective, measurable criteria. The remaining 20-30% requires human judgment (alt text quality, content clarity, cognitive accessibility). CI/CD testing is essential but not sufficient alone—combine with periodic manual audits for complete coverage.

How do I fix violations found in CI/CD?

For simple violations (missing alt text, color contrast), developers can fix directly. For complex violations or high volume, TestParty's expert remediation team creates source code fixes delivered via PRs. Open source tools provide detection only—all fixes require your team's implementation.


For more CI/CD accessibility information:

Like all TestParty blog posts, this content was created through human-AI collaboration—what we call our cyborg approach. The information provided is for educational purposes only and reflects our research at the time of writing. We recommend doing your own due diligence and speaking directly with accessibility vendors to determine the best solution for your specific needs.

Stay informed

Accessibility insights delivered
straight to your inbox.

Contact Us

Automate the software work for accessibility compliance, end-to-end.

Empowering businesses with seamless digital accessibility solutions—simple, inclusive, effective.

Book a Demo