Accessibility Testing (WCAG)
Verify that a system can be used by people with disabilities — including visual, hearing, motor, and cognitive impairments. In New Zealand, 1 in 4 people has a disability. Accessibility is not optional.
1 The Hook
A Te Whatu Ora team launches an online form for booking a vaccination. It is tested the usual way: a sighted tester opens it with a mouse, fills the fields, clicks submit, sees the confirmation. Looks great. Signed off.
Then a blind nurse using NVDA tries to book. She tabs to the date field — but it is a custom <div> dropdown that only opens on mouse hover, so the keyboard cannot reach it. The submit button is an image with no label, announced only as “button.” When she submits with a missing field, the error shows as red text with no aria-live region, so her screen reader says nothing at all. From her side, the form is simply broken. She cannot book a basic health appointment online.
None of this showed up in the original test because the test was done the way the developer built it: sighted, with a mouse. A quarter of New Zealanders have a disability, and for many of them the mouse-and-eyes happy path is exactly the path they cannot take. Accessibility testing is testing the paths the original team never used.
2 The Rule
Test the system the way people with disabilities actually use it — by keyboard, by screen reader, at 200% zoom — against WCAG 2.1 AA, because the happy path built with a mouse and working eyes hides the defects that lock people out.
3 The Analogy
A building with a grand front staircase and no ramp.
A new Auckland library opens with a beautiful stone staircase at the entrance. The architect walked up it, the builders walked up it, the official who cut the ribbon walked up it — everyone who signed off could climb stairs, so nobody noticed there is no ramp, no lift, and the door is too narrow for a wheelchair. The building “works” for everyone who tested it, and is unusable for the person who arrives in a wheelchair or pushing a pram.
Accessibility testing is sending someone in a wheelchair to the door before opening day. A keyboard-only run, a screen-reader pass, a zoom check — those are the wheelchair at the entrance, finding the missing ramp while it can still be built, instead of after the doors are open.
What it is
Accessibility testing checks whether a system works for people who use it differently — via keyboard instead of mouse, via screen reader instead of eyes, via switch control instead of touchscreen, or with cognitive differences that require clear language and consistent layout.
The standard that governs this work is the Web Content Accessibility Guidelines (WCAG), currently at version 2.1. In most professional contexts, WCAG 2.1 Level AA is the target. Level A is the minimum; Level AAA is aspirational. AA is what government, healthcare, and most enterprise systems are expected to meet.
Automated tools catch only ~30% of accessibility issues. The rest require human judgement — reading the page with a screen reader, tabbing through a form, checking that an error message is actually useful. This is why accessibility testing is a skill, not just a tool run.
NZ context
New Zealand has strong legal and policy foundations for accessibility:
- 1 in 4 New Zealanders has a disability. This is not a niche requirement — it affects a quarter of your user base.
- Human Rights Act 1993 prohibits discrimination on the grounds of disability in the provision of goods and services. An inaccessible website can constitute unlawful discrimination.
- NZ Government Web Standards require all government websites to meet WCAG 2.1 AA. If you work on any government or public sector project in NZ, AA compliance is mandatory.
- NZ Disability Strategy 2016–2026 sets a national vision for a fully inclusive New Zealand society.
- Te reo Māori is an official language of New Zealand. Accessibility must also consider bilingual content — screen readers need correct language tagging (
lang="mi"on Māori text blocks) to pronounce te reo correctly.
WCAG 2.1 AA — the four principles (POUR)
All WCAG success criteria are organised under four principles. Understanding these helps you reason about why a particular requirement exists, not just what it requires.
| Principle | What it means | Key examples |
|---|---|---|
| Perceivable | Content must be presentable to users in ways they can perceive. Nothing should be invisible to all of a user’s senses. | Alt text for images; captions for video; colour contrast ratio minimum 4.5:1 for normal text; don’t convey information by colour alone |
| Operable | All functionality must be operable via keyboard (or other input besides mouse). No content should cause seizures. | All interactive elements reachable by Tab; no keyboard traps; skip navigation link; no flashing content faster than 3 times/second; sufficient time to complete tasks |
| Understandable | Content and operation must be understandable. Users must be able to understand both the information and how to operate the interface. | Language of page declared (lang="en-NZ"); form labels are visible and associated; error messages are descriptive; consistent navigation across pages |
| Robust | Content must be robust enough to be interpreted by a wide variety of user agents, including assistive technologies. | Valid HTML; ARIA used correctly; custom components have proper roles, names, and states; works with current screen readers (NVDA, JAWS, VoiceOver) |
Manual checks every tester should do
These checks require no specialist tools — just a browser and keyboard:
| Check | How to test | What a bug looks like |
|---|---|---|
| Keyboard navigation | Put your mouse aside. Tab through the entire page. Shift+Tab to go back. Enter/Space to activate buttons and links. | Any interactive element unreachable by keyboard; focus disappears; wrong Tab order; modal opens but focus doesn’t move into it |
| Focus indicator visible | Tab through the page and watch the focus ring (the outline around focused elements). | Focus ring removed with CSS (outline: none); focused element is visually indistinguishable from unfocused element |
| Colour contrast | Use browser DevTools Accessibility panel, or the free Colour Contrast Analyser tool. Check text against its background. | Contrast ratio below 4.5:1 for normal text, or below 3:1 for large text (18pt+ or 14pt+ bold) |
| Image alt text | Right-click each image → Inspect. Check the alt attribute. |
Missing alt attribute; alt="image" or alt="photo" (meaningless); decorative images without alt="" |
| Form labels | Click on the label text for each form field. The cursor should jump to the input. | Clicking the label does nothing (label not associated with input); placeholder used instead of a real label |
| Error messages | Submit a form with invalid data. Read the error message. | “Invalid input” (doesn’t say what’s wrong); error only indicated by red colour; error not linked to the field it describes |
| Heading structure | Use the headings panel in browser DevTools or the WAVE extension to view the heading outline. | No h1 on the page; h1 jumps straight to h3 (skipped levels); headings used for styling rather than structure |
| Link text | Read the link text out of context. Does it make sense? | “Click here”, “Read more”, “Learn more” with no surrounding context; screen reader users hear a list of “click here click here click here” |
ARIA: when to use it and when not to
ARIA (Accessible Rich Internet Applications) is a set of HTML attributes that add accessibility metadata to elements — roles, states, and properties that assistive technologies use when native HTML doesn’t provide enough information.
The first rule of ARIA is: don’t use ARIA if you can use a native HTML element instead. A <button> is focusable, activatable by Enter/Space, and announces itself as a button to screen readers — automatically. A <div role="button"> requires you to manually handle all of that. Native HTML is always more reliable.
Where ARIA is appropriate: custom widgets that have no native HTML equivalent (data grid, combobox with autocomplete, drag-and-drop interface, date picker). Use ARIA to communicate state: aria-expanded="true/false" on accordion headers, aria-selected on tabs, aria-live regions to announce dynamic content updates to screen readers.
When reviewing ARIA usage in a product, the key check is: does the ARIA match the visual state? If a dropdown is open and aria-expanded is still "false", that’s a bug.
Tools
- axe DevTools (browser extension, free) — runs automated checks on the current page and reports violations with explanations and links to WCAG criteria. The most widely used accessibility automated tool.
- WAVE (browser extension, free) — overlays visual indicators directly on the page; good for quickly spotting missing labels, empty links, and contrast issues
- Lighthouse (built into Chrome DevTools) — accessibility audit as part of a broader performance/quality report; good for CI integration
- Colour Contrast Analyser (desktop app, free from The Paciello Group) — lets you pick any two colours on screen and get the contrast ratio instantly
- Screen readers — NVDA (Windows, free), JAWS (Windows, paid), VoiceOver (macOS/iOS, built-in), TalkBack (Android, built-in). At minimum, run through the main user journey with NVDA + Chrome to catch the most impactful issues.
Common bugs
- Placeholder used as label — placeholder text disappears when the user starts typing, leaving no visible label; screen readers may not announce it at all in some contexts
- Colour as the only differentiator — red = error, green = success, with no other indicator. Red-green colour blindness affects approximately 8% of men. Use icons, text labels, or patterns in addition to colour.
- Button with no accessible name —
<button><img src="close.png"></button>is announced as “button” by screen readers with no context. Addaria-label="Close"or use a visually-hidden text span. - Modal that doesn’t return focus — modal opens, focus moves into it correctly. Modal closes. Focus drops to the top of the page instead of returning to the element that opened the modal.
- Custom dropdown not keyboard accessible — a dropdown built with
<div>and<ul>that requires mouse hover to open and can’t be used with Tab or arrow keys - Dynamic content not announced — an error message appears on screen after form submission, but no
aria-liveregion announces it to screen reader users who can’t see the page change
Tips
Automate first, then test manually. Install the axe DevTools browser extension and run it on every page before releasing. It’ll catch the mechanical issues (missing alt text, duplicate IDs, invalid ARIA). Then put your mouse away and tab through the whole page — automated tools miss what keyboard testing catches, especially focus management in dynamic components.
- Include accessibility in your definition of done — axe DevTools passes + keyboard navigation check should be checklist items before any story is marked done
- Raise contrast failures with actual values — when reporting a contrast bug, include the foreground colour, background colour, and the measured ratio (e.g. 2.8:1 against required 4.5:1). This gives designers exactly what they need to fix it.
- Test with zoom at 200% — WCAG 1.4.4 requires content to be readable at 200% zoom without loss of content or functionality. Many layouts break at high zoom and are never tested.
- Te reo Māori content — if your product includes te reo Māori text, ensure it is wrapped in
<span lang="mi">so screen readers switch to the correct language voice engine. Without this, the Māori text is mispronounced in English phonetics.
4 Now You Try
Three graded exercises — spot, fix, then build. Write your answer, run it for AI feedback, then compare to the model answer.
An IRD myIR login page has the five issues below. For each, name which POUR principle it breaks (Perceivable, Operable, Understandable, or Robust) and one sentence on the harm. (a) the password field has no <label>, only a placeholder; (b) the “Log in” button cannot be reached by Tab; (c) grey help text at 2.5:1 contrast; (d) a custom date picker built from <div>s with role="button" that is never focusable; (e) the form error appears as red text with no aria-live.
Show model answer
(a) No label, placeholder only — UNDERSTANDABLE (form labels must be visible and associated). Placeholder text vanishes once the user types and is not reliably announced, so the user loses track of what the field is for. (Also touches Perceivable.) (b) Button unreachable by Tab — OPERABLE (all functionality must work by keyboard). A keyboard-only user simply cannot log in. (c) Grey text at 2.5:1 — PERCEIVABLE (contrast must be at least 4.5:1 for normal text). Low-vision users and anyone in bright light cannot read the help text. (d) Custom div date picker, never focusable — ROBUST and OPERABLE. A div with role="button" that is not focusable or keyboard-operable is broken for assistive tech and the keyboard; native HTML would have been reliable. (e) Error with no aria-live — PERCEIVABLE / ROBUST. A screen reader user never hears the error because nothing announces the dynamic change; wrap it in an aria-live region (or move focus to it). Mapping issues to POUR is how you explain WHY each is a defect, not just that it is one.
The KiwiSaver provider’s “close” control below is inaccessible. Rewrite it so it works for keyboard and screen-reader users, and say what was wrong.
<div class="close" onclick="closeModal()"><img src="x.png"></div>It only responds to mouse clicks, the image has no alt text, and the div is not focusable.
Rewrite it and explain the fixes:
Show model answer
Rewritten markup: <button type="button" class="close" aria-label="Close" onclick="closeModal()"> <img src="x.png" alt=""> </button> (The icon is decorative, so alt="" plus aria-label="Close" on the button; or use a visually-hidden text span.) What was wrong: - A div is not focusable and not activatable by Enter/Space, so keyboard users cannot reach or trigger it. A native <button> is focusable and activatable automatically. - onclick only fires for mouse/touch; the div had no keyboard handling. - The image had no alt and the control had no accessible name, so a screen reader announced nothing useful. What a screen reader announces after the fix: "Close, button." Focus handling when the modal closes: return focus to the element that opened the modal (not the top of the page), so the keyboard user is not dumped back to the start. First rule of ARIA: prefer the native element — here, a real button removes most of the work.
You have a Waka Kotahi online licence-renewal form (name, address, date of birth, payment, submit). Design a manual accessibility test pass — no automated tool — that a tester could run in 15 minutes. List the checks, how to perform each, and what a failure looks like. Include keyboard, focus, contrast, labels, errors, and te reo Māori handling.
Show model answer
A 15-minute manual pass for the licence-renewal form: Check 1 (keyboard) — Put the mouse aside and Tab through every field and the submit button; Shift+Tab back; Enter/Space to activate. Failure: any field or control unreachable; a keyboard trap you cannot Tab out of; the date picker that needs a mouse. Check 2 (focus order / ring) — Watch the focus ring as you Tab. Failure: focus ring removed (outline:none); focus order jumps around illogically; focused element looks identical to unfocused. Check 3 (form labels) — Click each label; the cursor should jump into its field. Failure: clicking the label does nothing (not associated); a placeholder used instead of a real label. Check 4 (error messages) — Submit with a missing/invalid field and read the message. Failure: "Invalid input" with no detail; error shown only by red colour; error not linked to its field; nothing announced (no aria-live). Check 5 (contrast / zoom) — Eyeball low-contrast text (confirm with the Colour Contrast Analyser), then set browser zoom to 200%. Failure: text below 4.5:1; layout breaks or content is lost/cut off at 200%. Check 6 (te reo Māori) — Inspect any te reo text. Failure: Māori words not wrapped in lang="mi", so a screen reader mispronounces them in English phonetics. Bonus a senior would add: run the main renewal flow once with NVDA + Chrome to hear how it actually sounds — automation catches only ~30% of issues.
Self-Check
Click each question to reveal the answer.
Q1: Why does the standard mouse-and-eyes happy path miss most accessibility defects?
Because keyboard-only and screen-reader users take paths the sighted, mouse-using developer never exercises. A custom dropdown that only opens on hover, an unlabelled icon button, or an error shown only in red all “work” for the person who built them and lock out the quarter of New Zealanders who interact differently.
Q2: What do the four POUR principles stand for, and why use them?
Perceivable, Operable, Understandable, Robust. They organise every WCAG success criterion, so mapping a bug to a principle lets you explain why it is a barrier (e.g. low contrast is a Perceivable failure; a keyboard-unreachable button is an Operable failure) rather than just citing a rule number.
Q3: What level of WCAG 2.1 is the usual target, and why does it matter in NZ?
WCAG 2.1 Level AA. The NZ Government Web Standards require all government websites to meet AA, so for any public-sector project AA compliance is mandatory; Level A is the floor and AAA is aspirational.
Q4: Roughly how much of accessibility can automated tools catch, and what is the implication?
About 30%. The rest — keyboard reachability, focus management, whether a screen reader announcement is actually useful, whether alt text is meaningful — needs human judgement. Automation is layer one; manual keyboard and screen-reader testing covers the gap.
Q5: Why must te reo Māori text be wrapped in <span lang="mi">?
So a screen reader switches to the correct language voice engine and pronounces the te reo correctly. Without the language tag, Māori words are read with English phonetics and become unintelligible — and te reo Māori is an official language of New Zealand.
Practice this technique: Try Senior Practice 01 — Accessibility (a11y).