Accessibility as a Build Barrier: axe-core in CI In short: finds about 57% of WCAG issues automatically, with very few false positives. That is not most of the problem, but it is the half a machine can own — so it should block a merge rather than fill a backlog. The visual gate proves the page looks as designed. It says nothing about whether a dispatcher can reach the approve button with a keyboard, or whether a farmer can read a status in direct sunlight. Accessibility is usually handled as a periodic audit that produces a ticket backlog nobody schedules. Automate the automatable half instead, and make it a build failure. The engine , by Deque, is the industry standard. Deque's own research puts automated coverage at around 57% of WCAG issues — and the number is credible precisely because axe is deliberately conservative: it reports an element as "incomplete" rather than guessing, so false positives are rare. That conservatism is what makes it usable as a gate. A checker that cried wolf would be switched off within a fortnight. Chapter 3 already did the hard part. Components built on and native elements pass most of these checks by construction; this lesson is about proving it stays true. Layer 1: while authoring The fastest feedback is in Storybook itself: Now every story shows contrast failures and missing attributes live, in the panel, while you build the component. A problem found here costs a minute; the same problem found in a quarterly audit costs a ticket, a sprint slot, and a regression risk. Layer 2: every story, in CI The stories are already enumerable from the visual gate, so scanning all of them is a small addition: scopes the scan to the component, so Storybook's own chrome does not produce noise. Scan every theme Contrast is the most common violation and the one most likely to differ by theme. Chapter 6 warned that a theme swap does not preserve contrast ratios for free: A dark theme that has not been contrast-checked is a colour experiment, not a theme. Layer 3: whole pages Component-level scanning cannot see page-level structure: heading order, landmark regions, duplicate ids across components, or focus order through an assembled screen. Reuse the page specs from the previous lesson: Rolling this out without stopping the team Turn this on for an existing application and you will get hundreds of violations on day one. The build goes permanently red, everyone learns to ignore it, and the gate is dead. The workable policy is no new violations , not zero violations. Baseline what exists, fail on anything new: Counts can only go down. Every refactor that fixes a few lets you lower the baseline, and the number becomes a visible debt figure rather than an abstract intention. For a genuinely untouchable legacy area, exclude it explicitly and leave a note: An exclusion with a ticket number is a decision. An exclusion without one is a hiding place. New code gets no baseline. Anything under starts at zero and stays there. Keyboard behaviour still needs a test checks the static DOM. It cannot press Tab. Chapter 3's point was that ARIA attributes are a promise about behaviour — and axe verifies the promise is well-formed, not that you kept it. So test the behaviour: Because Chapter 3's components use , this passes without any key-handling code of your own — and the test proves the framework is doing it. Three behaviours worth testing on every interactive component: 1. It can be reached with . 2. It can be operated with the keyboard alone. 3. Focus goes somewhere sensible after a dialog closes. "But I thought passing axe meant the component was accessible" This is the belief a green pipeline actively encourages, and it is worth dismantling carefully because the tooling gives no signal that it is wrong. Deque's own figure is the answer: about 57% of issues. Which means a component with zero axe violations can still be substantially unusable. What automation cannot judge: Whether an text is meaningful. passes. It tells a screen reader user nothing. Whether focus order makes sense. Axe checks that things are focusable, not that tabbing through them follows the visual reading order. Whether an ARIA promise was kept. This is Chapter 3's central point. A with no arrow keys passes every automated check and is completely unusable — worse than a plain , because the user was told it is a listbox. Whether an error message is comprehensible. "Validation failed on field 3" is announced correctly and helps nobody. Whether the flow works. Each screen can pass individually while the journey through them is impossible. axe-core A person with a screen reader --- --- --- Contrast ratios Yes Yes Missing labels and alt attributes Yes Yes Invalid ARIA, duplicate ids Yes Yes Whether the label is useful No Yes Whether arrow keys work No Yes Whether focus order is logical No Yes Whether the task can be completed No Yes So the honest framing is: axe is the floor, not the ceiling. It should be a build barrier because it is cheap,…