Use three layers: automated tools, a manual check, and assistive technology.
1. Automated tools. Examples are axe (as a browser extension, or in tests with jest-axe or Playwright), Lighthouse (which uses axe inside) and eslint-plugin-jsx-a11y in the editor. Run them in CI (continuous integration: the checks that run on every pull request). They find problems that a rule can detect, for example:
- missing alt text and missing form labels
- low colour contrast
- invalid ARIA and duplicate ids
They catch only part of all problems. Common estimates are roughly a third to a half.
What they miss: anything that needs judgement. Is the alt text useful? Is the focus order logical? Does focus move to the dialog and back? Is the error message clear? Does a custom widget work with the keyboard?
2. Manual checks.
- Put the mouse away and do everything with the keyboard. Watch that focus is always visible.
- Zoom to 200% and 400%.
- Turn on reduced motion and Windows contrast themes.
3. Screen reader. Try key flows with a real screen reader: NVDA on Windows, VoiceOver on Mac and iPhone, TalkBack on Android. Even a short check finds bugs no tool can.
Best of all, test with disabled users when you can.
- Automated tools like axe and Lighthouse find rule-based issues such as missing labels and low contrast.
- Automated tools find only part of the problems, so a clean score is not proof.
- A keyboard-only pass checks focus order, visible focus and traps.
- Zoom, reduced motion and contrast settings should be checked by hand.
- Key flows should be tested with a real screen reader such as NVDA or VoiceOver.