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.
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
- Inject Axe Once per Page: Call
cy.injectAxe()after navigation completes. - Test Interactive States: Trigger hover, open, and error states before running checks.
- Target Specific Containers: Narrow checks to avoid duplicate parent alerts.
- Integrate with CI: Run headless Cypress suites on pull requests.
- 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.