Cypress accessibility testing lets you catch WCAG violations and usability barriers directly in your end-to-end test suite. You add an accessibility plugin, write a few commands, and get a pass/fail report for every page you visit. This article covers the practical tips and recent updates you need to integrate axe-core with Cypress effectively.
What Is Cypress Accessibility Testing?
Cypress is a JavaScript end-to-end testing framework that runs in the browser. Accessibility testing in Cypress usually means integrating axe-core, the same engine behind the Axe browser extension, into your test runner. The most common package is cypress-axe, which adds two commands: cy.injectAxe() and cy.checkA11y(). When you call cy.checkA11y(), it scans the current DOM for WCAG 2.1 AA violations and fails the test if any are found. You can also run it in a “no fail” mode to collect violations without breaking the build.
Why Use Cypress for Accessibility?
Automated accessibility testing in Cypress gives you continuous feedback during development, not just at audit time. It runs on every commit in CI, so regressions are caught immediately. Unlike a separate audit tool, you can test real user flows: log in, navigate to a specific state, open a modal, and then run the scan. This catches issues that only appear after certain interactions, like a focus trap or a missing label that only shows after a button click.
However, automated tools only catch about 30–50% of WCAG issues. They miss things like keyboard focus order, color contrast in complex gradients, and screen reader announcements. So use Cypress accessibility tests as a safety net, not a substitute for manual testing with a screen reader and keyboard.
How to Set Up Cypress Accessibility Testing
Setting up is straightforward. Here are the steps:
- Install the packages:
npm install cypress-axe axe-core --save-dev. - In your Cypress support file (e.g.,
cypress/support/e2e.js), addimport 'cypress-axe'. - In each test, call
cy.visit('/page')and thency.injectAxe()before the scan. This injects the axe script into the page. - Call
cy.checkA11y()to run the scan. You can pass options to exclude certain elements or set a different severity level.
Example test:
it('has no accessibility violations', () => {
cy.visit('/login');
cy.injectAxe();
cy.checkA11y();
});
You can also run cy.checkA11y(null, { includedImpacts: ['critical'] }) to only fail on critical issues, or cy.checkA11y('.main-content') to scan a specific region.
Practical Tips for Effective Testing
- Scan after every interaction – call
cy.checkA11y()after opening modals, expanding accordions, or submitting forms, not just on page load. - Use
cy.pause()during debugging – when a test fails, Cypress pauses and shows you the violation details in the command log. You can click on the violation to see the affected element. - Set a global default – in your support file, override
cy.checkA11yto always include certain rules or exclude known false positives, so you don’t repeat options in every test. - Exclude third-party content – if your page embeds a widget or an iframe that you don’t control, exclude it with
{ exclude: ['.third-party-widget'] }to avoid noise. - Run in CI with a dedicated job – even if you run other tests in parallel, keep accessibility tests separate so they can use a consistent viewport and don’t interfere.
Common Problems and How to Fix Them
Problem: cy.injectAxe() fails because the page has a strict Content Security Policy. Axe injects a script tag, which some CSPs block. Solution: add the axe script to your page’s allowed sources, or use cy.visit(url, { onBeforeLoad: (win) => { win.__axe = axe; } }) if you have a custom setup.
Problem: Tests pass locally but fail in CI. This is often due to different viewport sizes or fonts. Axe checks color contrast based on computed styles, which can change with different font rendering. Set a fixed viewport in your test (cy.viewport(1280, 720)) and use the same browser version in CI.
Problem: Too many violations to fix at once. Use cy.checkA11y(null, { includedImpacts: ['critical', 'serious'] }) to start with the most severe issues. You can also write a custom test that logs all violations to a file for triage.
Recent Updates in Cypress and axe-core
Cypress 12 and later introduced cy.session(), which can be used to cache login states for accessibility tests, saving time. Cypress 13 added experimental web vitals, but that’s not directly related to a11y. As of 2024, cypress-axe v1.5.0 supports Cypress 13 and axe-core 4.9.0. Axe-core 4.9 added new rules for ARIA attributes and improved color contrast detection. Always check the cypress-axe changelog for compatibility with your Cypress version.
Another update: axe-core 4.8 and later changed some rule IDs. If you have custom rules or exclusions, verify they still work after upgrading.
Comparing Cypress Accessibility to Other Tools
Other options include:
- Jest + jest-axe – runs unit-level checks on rendered HTML, but doesn’t test real browser interactions.
- Playwright + @axe-core/playwright – similar to Cypress, but Playwright has a different API and is faster for parallel tests.
- Lighthouse CI – gives an overall accessibility score but doesn’t integrate with your functional tests.
- axe DevTools browser extension – great for manual audits, but not automated.
Cypress’s advantage is that it’s already in your test flow, so you don’t need a separate tool. Its disadvantage is that it runs in a real browser, which can be slower than unit tests.
Costs and Limitations
There is no cost for the open-source packages. The main cost is test execution time – each cy.checkA11y() call adds a few hundred milliseconds to a test, which can add up across a large suite. To mitigate, run accessibility scans on a subset of critical pages or only after major interactions.
Limitations: axe-core cannot detect all WCAG criteria, such as meaningful link text or alternative text that is accurate. It also cannot test keyboard navigation thoroughly. For those, you need manual testing or additional tools like cy.tab() to simulate keyboard presses (though that’s not built into cypress-axe).
Frequently Asked Questions
Does Cypress have built-in accessibility testing?
No, Cypress does not include accessibility testing out of the box. You need to install cypress-axe and axe-core to add the cy.checkA11y() command.
Can I test keyboard navigation with Cypress?
Yes, but not with axe. You can use cy.get('button').focus() and then cy.type('{enter}') to simulate keyboard interaction. For full tab order testing, you can write a custom command that repeatedly calls cy.focused() and compares it to an expected sequence.
What is the difference between cy.injectAxe() and cy.checkA11y()?
cy.injectAxe() loads the axe script into the page. cy.checkA11y() runs the scan and reports violations. You must call injectAxe before checkA11y on each page you test.
How do I ignore a specific rule?
Pass { rules: { 'color-contrast': { enabled: false } } } as the second argument to cy.checkA11y(). You can also exclude elements with { exclude: ['.selector'] }.
Can I use Cypress accessibility testing on a single-page app?
Yes, but you need to call cy.checkA11y() after each route change or dynamic content update, because axe only scans the current DOM. Consider using cy.checkA11y() inside a custom command that you call after every navigation.
Does cypress-axe work with Cypress 14?
As of late 2024, cypress-axe v1.5.0 supports Cypress 13 and 14. Always check the package’s peer dependencies before upgrading.
Related
Formula used
in t | Time limit (min) | min | 30 | 0 in p | Pages to test | count | 10 | 1 | 1000 out time_per_page | Minutes per page | min | t / p | 2 out tests_per_hour | Pages per hour | pages/h | p / (t / 60) | 0
Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work
Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.
More cards in this drawer
- Campus Tech Innovation Hubs: What They Are
- Poco C51 Airtel Prepaid Locked Variant India?
- Jenkins vs GitHub Actions: Which CI/CD Fits Your Team?
- Turn Off Backup Encryption in iTunes?
- Shared VPS Hosting: Is It Better?
- Disk Defrag Pro: What It Does and Whether You Need It