Back to Blog
On this page6 sections

// case study

The accessibility issue nobody noticed with a mouse

qa.codesqa.codes · 13 June 2026 · 7 min read
IntermediateManual QAAccessibility
case-studyaccessibilitya11ybugs

A custom dropdown worked flawlessly for everyone who tested it — because everyone tested it with a mouse. For keyboard users, the form was a dead end.

This is a case study, details blurred, about a bug that was invisible to the entire team for one reason: everybody who touched it used a mouse. It's a clean illustration of how a whole class of accessibility defects survives testing — not through carelessness, but through a shared blind spot.

Context

A signup form with a custom-built country dropdown — a styled component (not a native <select>) the design team built to match the brand. It looked great, animated nicely, and worked perfectly in every demo, every review, and every test session.

Symptoms

After launch, a support ticket: a user could not complete signup at all. They navigated with a keyboard (no mouse), and when they reached the country dropdown, they were stuck — they could tab to it, but couldn't open it, couldn't choose a country, and since country was required, couldn't submit. The form was a hard dead end for anyone not using a pointer.

Investigation

Reproducing it was instant once someone put the mouse down: tab to the dropdown, press Enter — nothing. Space — nothing. Arrow keys — nothing. The component only responded to a mouse click. Worse, focus could enter it but the options were rendered in a way the keyboard (and a screen reader) couldn't reach, so a keyboard user was trapped with no way forward and no way to make a selection.

Root cause

The dropdown was a <div>-based custom widget with a mouse click handler and no keyboard support — no key handlers, no focus management, none of the ARIA roles/states that make a custom control behave like a real combobox. A native <select> gives keyboard operability, screen-reader semantics, and mobile pickers for free; the hand-rolled replacement reimplemented the looks and skipped everything underneath. The visual layer was complete; the interaction layer existed only for the mouse.

What the tests missed

Nobody tested without a mouse. Manual testing, demos, design review, even the automated UI tests (which dispatch synthetic clicks, not real keyboard interaction) all drove the component the one way that worked. There was no keyboard pass and no screen-reader check — so the single most common custom-widget failure went straight to production. The bug wasn't subtle; it was just never exercised the way the affected users actually work.

The reusable lesson

Any time the UI replaces a native control with a custom one, that's a flag for explicit keyboard and screen-reader testing — native elements come with accessibility built in, custom ones come with nothing until someone adds it. Make "complete the flow with the keyboard only" a standard pass, especially on forms, and be aware that automated click-based tests don't exercise keyboard operability. The cheapest possible check — unplug the mouse — would have caught this before a single user did.

Custom-control case lessons

  • Treat every custom widget (replacing a native control) as a keyboard/screen-reader testing flag
  • Run a keyboard-only pass: reach, open, operate, and select — not just reach
  • Confirm Enter/Space/arrows work, not just mouse click
  • Check focus isn't trapped and options are reachable and announced
  • Remember automated click-based tests don't test keyboard operability
  • Prefer native controls; if overriding, verify roles, states, and key handling exist

// RELATED QA.CODES RESOURCES


// related

Case studies·13 June 2026 · 7 min read

The checkout bug that passed every happy-path test

Every checkout test was green, but combining two discounts and a gift card drove the total negative — and issued credit. A case study in testing invariants, not just features.

case-studytest-designe-commercebugs