Ch.07 · Why it matters
Break this page.
Every defect below is real and gets injected into this actual page. The suite underneath runs against the rendered DOM and has no idea the switch exists. Flip it and watch it go red — then fix them one at a time and watch it come back.

Break this page.
Every defect below is real and gets injected into this actual page. The suite underneath runs against the rendered DOM and has no idea this section exists. Flip the switch and watch it go red.
page is clean — 16 assertions holding
- 01
Unreadable body text
fixedCopy set at 1.9:1 contrast. Passes a designer’s eye on a bright monitor, fails WCAG AA and fails anyone reading outdoors.
caught by → text contrast meets WCAG AA
- 02
Image with no alt text
fixedA screen reader announces “image”. The content is simply gone for that visitor.
caught by → every image has alt text
- 03
Button with no accessible name
fixedAn icon-only control with no label. Keyboard and screen-reader users get “button”, and nothing else.
caught by → controls have accessible names
- 04
Positive tabindex
fixedtabindex="5" yanks this element to the front of the tab order, so keyboard focus jumps out of reading order.
caught by → no positive tabindex
- 05
target="_blank" without rel="noopener"
fixedThe opened page gets a handle on this one via window.opener. A real phishing vector, and a performance cost.
caught by → external links are rel="noopener"
- 06
Skipped heading level
fixedAn h5 directly under an h2. Anyone navigating by headings loses the document outline.
caught by → exactly one h1, no skipped levels
Six defects, none of them exotic, all of them shipped by someone this week. That is the job: not opinions about quality, but the assertion that catches it before a customer does.
Sixteen commits. One broke payouts.
This is a simulation, but the method is the real one. Click a commit to test it. Binary search finds the culprit in four goes, not sixteen.
0 tested · 16 commits still suspect
Next
What I check →Seven payment rails, five assertions each, and the coverage grid with the blanks left in.