End-to-End Accessibility Testing with Cypress and cypress-axe: Automated PR Gating

Master end-to-end accessibility testing with Cypress and cypress-axe. Learn how to test dynamic components, modals, and multi-step checkouts across states.

Static HTML scanners only test the initial load state of a web page. However, the majority of modern accessibility barriers occur inside dynamic states: open modal dialogs, revealed accordion panels, multi-step checkout sequences, and client-side error states. **Cypress paired with `cypress-axe`** enables end-to-end accessibility assertions across every user interaction state.

Dynamic State Assertion

With `cypress-axe`, you can run `cy.checkA11y()` after opening a modal, submitting an invalid form, or filtering an e-commerce catalog, guaranteeing that interactive transitions maintain compliance.

Testing Dynamic UI States with cypress-axe

`cypress-axe` injects the industry-standard `axe-core` rule engine directly into the browser DOM during Cypress execution, evaluating live rendered styles, calculated contrast ratios, and runtime ARIA bindings.

Installation and Global Command Configuration

// In cypress/support/e2e.js
import 'cypress-axe';

// In cypress/e2e/checkout-a11y.cy.js
describe('Checkout Funnel Accessibility', () => {
  beforeEach(() => {
    cy.visit('/checkout');
    cy.injectAxe();
  });

  it('Passes initial load audit', () => {
    cy.checkA11y();
  });

  it('Passes audit with validation errors displayed', () => {
    cy.get('button[type="submit"]').click();
    cy.get('.error-message').should('be.visible');
    // Audit error state
    cy.checkA11y();
  });
});

Auditing Modals, Accordions & Dynamic Dropdowns

Scope accessibility checks to specific component containers using CSS selectors to isolate issues:

cy.get('#openModalBtn').click();
cy.get('#modalDialog').should('be.visible');
// Check only the active modal
cy.checkA11y('#modalDialog');

Custom Violation Formatting and Reporting

Customize violation callback handlers to output clear diagnostic logs in the Cypress terminal runner with rule descriptions, help URLs, and failing DOM nodes.

5 Best Practices for cypress-axe Test Suites

  1. Inject Axe Once per Page: Call cy.injectAxe() after navigation completes.
  2. Test Interactive States: Trigger hover, open, and error states before running checks.
  3. Target Specific Containers: Narrow checks to avoid duplicate parent alerts.
  4. Integrate with CI: Run headless Cypress suites on pull requests.
  5. Combine with Manual Keyboard Testing: Automated tools verify attributes; manual testing verifies cognitive clarity.

Audit Your Website for WCAG 2.2 Compliance Today

Scan your domain in 60 seconds with Rogabot and get instant PR-ready code diffs to prevent ADA lawsuit exposure.

View Pricing Plans