Accessible Forms Testing

Forms are where accessibility defects cost the most: a sign-up, payment or government application that a screen-reader user cannot complete is not a cosmetic issue, it is a blocked transaction. Most form defects are also easy to find once you know what to look for — a field with no programmatic label, an error shown only in red, a one-time code that cannot be pasted.

This guide gives you the WCAG 2.2 success criteria that apply to forms, what each one means in practice, a repeatable test procedure, a copy-ready checklist and realistic defect titles. Keyboard operation and screen-reader technique are covered in their own guides; here they are applied to forms.

Which WCAG 2.2 criteria apply to forms

No single success criterion is called “forms”. The requirements are spread across the four principles, so a form review is really a pass over a known set of criteria. The ones below are the core set; levels are as published in WCAG 2.2.

  • 1.3.1 Info and Relationships (A) — labels, groups and required state must be available programmatically, not only visually.
  • 1.3.5 Identify Input Purpose (AA) — fields that collect information about the user expose their purpose (in HTML, via the autocomplete attribute).
  • 1.4.1 Use of Color (A) — required fields and errors are not signalled by colour alone.
  • 2.5.3 Label in Name (A) — the accessible name of a control contains its visible label text.
  • 3.2.2 On Input (A) — changing a field does not cause an unexpected change of context, such as submitting the form.
  • 3.3.1 Error Identification (A) — a detected input error identifies the field and describes the error in text.
  • 3.3.2 Labels or Instructions (A) — labels or instructions are provided when content requires user input.
  • 3.3.3 Error Suggestion (AA) — when a correction is known, it is suggested, unless that would jeopardise security or purpose.
  • 3.3.4 Error Prevention (Legal, Financial, Data) (AA) — submissions with legal, financial or data consequences are reversible, checked or confirmed.
  • 3.3.7 Redundant Entry (A) — information already entered in the same process is auto-populated or selectable.
  • 3.3.8 Accessible Authentication (Minimum) (AA) — no step of login requires a cognitive function test unless an allowed alternative or mechanism exists.
  • 4.1.2 Name, Role, Value (A) and 4.1.3 Status Messages (AA) — custom controls expose name, role and state; status and error messages reach assistive technology without moving focus.

Labels, instructions and required fields

Every input needs an accessible name that matches what a sighted user reads next to it. In HTML the robust way is a <label> element tied to the input with for/id, or wrapping the input. Grey hint text inside the empty field is not a label: it disappears when the user types, often fails contrast, and support as an accessible name is inconsistent. aria-label and aria-labelledby are valid when there is no visible label element, but then check Label in Name — a button that shows “Send” and is named “Submit form” breaks voice-control users who say what they see.

Instructions and format hints (“DD/MM/YYYY”, “8+ characters, one digit”) belong before the field or are associated with it, typically via aria-describedby, so they are read when the field receives focus. Instructions that only appear in a tooltip on hover are missed by keyboard and touch users.

Required fields need both a visible and a programmatic signal. A red asterisk alone relies on colour and on the user knowing the convention; explain it once at the top of the form (“Fields marked * are required”) or write “(required)” in the label, and set the required attribute or aria-required="true" so screen readers announce it.

  • Inspect the accessible name of each field in the browser devtools accessibility pane — do not infer it from the markup.
  • Click the visible label: focus should move to the field (a quick check that the label is really associated).

Try it: Validation Test Generator Try it: HTML Accessibility Checker

Grouping related fields with fieldset and legend

A group of radio buttons or checkboxes has two levels of meaning: the question and each answer. If only the answers are labelled, a screen-reader user hears “Yes, radio button, 1 of 2” with no idea what is being asked. Wrap the group in <fieldset> with a <legend>, or use role="group"/role="radiogroup" with aria-labelledby for custom widgets. The same applies to date-of-birth fields split into day, month and year, and to repeated address blocks.

<!-- Defect: the question is plain text, not associated with the radios -->
<p>Do you have a residence permit?</p>
<input type="radio" id="p-yes" name="permit"><label for="p-yes">Yes</label>
<input type="radio" id="p-no" name="permit"><label for="p-no">No</label>

<!-- Fixed: the legend names the group; each option keeps its own label -->
<fieldset>
  <legend>Do you have a residence permit? (required)</legend>
  <input type="radio" id="p-yes" name="permit" required><label for="p-yes">Yes</label>
  <input type="radio" id="p-no" name="permit"><label for="p-no">No</label>
</fieldset>

Error identification, suggestion and announcement

When validation fails, three things must be true. The field in error is identified; the error is described in text (3.3.1); and where a fix is known, it is suggested (3.3.3) — “Enter the date as DD/MM/YYYY, for example 05/03/2026” rather than “Invalid input”. A red border alone fails 1.4.1; an icon alone needs a text alternative; and the message must be programmatically associated with the field (aria-describedby or aria-errormessage together with aria-invalid="true") so it is read when the user returns to it.

An accessible field is tied together in code, not just placed side by side: the label names the input, and the hint and the error text are associated with it.

Date-of-birth field after a wrong-format entry

<label Part 1:for="dob">Part 2:Date of birth (required)</label>
<p id="dob-hint">Part 3:DD/MM/YYYY</p>
<input Part 1:id="dob" Part 4:required
  Part 5:autocomplete="bday"
  Part 6:aria-invalid="true"
  Part 7:aria-describedby="dob-hint dob-error">
<p id="dob-error">Part 8:Enter the date as DD/MM/YYYY, for example 05/03/2026</p>
  1. 1Label tied to the inputfor matches the input’s id: clicking the label moves focus to the field.1.3.1
  2. 2Visible label = accessible nameThe name contains the visible text; (required) is written, not signalled by colour alone.2.5.3 · 3.3.2 · 1.4.1
  3. 3Format hint, before the fieldWritten before the field, not only in a hover tooltip; linked by (7) so it is read on focus.3.3.2
  4. 4Required staterequired or aria-required="true", so screen readers announce it.1.3.1
  5. 5Input purposeThe bday token exposes what the field collects; browsers can fill it.1.3.5
  6. 6Invalid stateSet on the field while its value fails validation.
  7. 7Hint and error associatedPoints to the hint (3) and the error (8), so both are read on the field. Alternative: aria-errormessage with aria-invalid.
  8. 8Error in text, with the fixDescribes the problem and suggests the expected format with an example, not “Invalid input”.3.3.1 · 3.3.3

Styling may add a red border or an icon, but a red border alone fails 1.4.1 and an icon alone needs a text alternative: here the error is in text (8).

Users also need to learn that an error happened. Two common, practical patterns: on submit, render an error summary at the top of the form, move focus to it, and link each entry to its field; or move focus directly to the first invalid field. For messages that appear without moving focus — “Saved”, “3 results”, an asynchronous “username already taken” — use a live region (role="status" or aria-live="polite" for information; role="alert" for urgent errors) so they satisfy 4.1.3 Status Messages. The live region container must exist in the page before the text is inserted, otherwise many screen readers do not announce it.

Watch the timing of inline validation. Announcing an error on every keystroke, or while the user is still typing an email address, is noisy and confusing; validating on blur or on submit is usually calmer. And a field change must not submit the form or navigate away on its own (3.2.2 On Input) unless the user was told beforehand.

  • Submit an empty form: every required field is reported, in text, with the field named in the message.
  • Enter a wrong format: the message says what format is expected, with an example.
  • With a screen reader, submit the invalid form: you hear that errors exist without hunting for them.
  • Server-side errors (for example “card declined”) are announced the same way as client-side ones.

Try it: Negative Test Generator Try it: Mock Error Payload Generator

Error prevention and redundant entry

3.3.4 Error Prevention (Legal, Financial, Data) applies to pages that create legal commitments or financial transactions, modify or delete user-controllable data, or submit test responses. At least one of three options must hold: the submission is reversible; the data is checked and the user can correct it; or the user can review, confirm and correct before finalising. In practice testers verify a review step before payment, an undo or cancellation window, or a confirmation dialog before deleting an account — and that the review screen itself is accessible (headings, readable values, an “Edit” link per section with a clear name).

3.3.7 Redundant Entry (A) is new in WCAG 2.2. If a multi-step process asks again for information the user already gave — the shipping address on the billing step, the national ID on the confirmation step — it must be auto-populated or offered for selection (for example a “Same as shipping address” checkbox). Exceptions exist when re-entry is essential, required for security (such as confirming a new password), or when the earlier information is no longer valid.

Input purpose, autocomplete and accessible authentication

1.3.5 Identify Input Purpose asks that fields collecting information about the user expose their purpose programmatically when the purpose is one listed in WCAG’s “Input Purposes for User Interface Components” section. In HTML this means the autocomplete attribute with the right token: name, given-name, family-name, email, tel, street-address, postal-code, bday, username, current-password, new-password, cc-number and others. Beyond conformance, correct tokens let browsers and password managers fill the form, which directly helps people with motor and cognitive disabilities. Verify the token on each field; autocomplete="off" on a personal-data field is a finding worth raising.

3.3.8 Accessible Authentication (Minimum) says no step of an authentication process may require a cognitive function test — remembering a password, solving a puzzle, transcribing a code — unless the step offers an alternative method without one, a mechanism that assists (WCAG’s own examples are password-manager support and copy and paste), or the test is recognising objects or identifying personal content the user supplied. The Understanding document treats manual transcription of a one-time code as a cognitive function test, so the user must at least be able to paste the code.

  • Password and username fields accept paste and are fillable by password managers (no script blocking paste or autofill).
  • One-time codes can be pasted in full. Split “one box per digit” inputs often fail this: pasting fills only the first box — test it explicitly. The HTML token autocomplete="one-time-code" helps browsers offer the code; it is not in WCAG’s input-purpose list, so treat it as good practice rather than a 1.3.5 requirement.
  • CAPTCHA: a text or puzzle CAPTCHA is a cognitive function test and needs an alternative; an object-recognition CAPTCHA is excepted at AA (not at AAA, 3.3.9 Accessible Authentication (Enhanced)). Any CAPTCHA image still needs a text alternative that identifies its purpose under 1.1.1, plus an alternative form using a different sensory modality.
  • Passwordless options (email link, passkeys/WebAuthn) are alternatives that avoid a cognitive function test — check that they are reachable and operable by keyboard and screen reader.

Try it: Fake User Generator

A practical test procedure

  • Structure pass (devtools): for each field, read the computed accessible name, role, description, required and invalid state in the accessibility tree. Confirm autocomplete tokens.
  • Keyboard pass: complete the form with Tab, Shift+Tab, arrow keys, Space and Enter only — focus order follows the visual order, focus is always visible, custom selects and date pickers are operable (see the keyboard accessibility guide).
  • Screen-reader pass: complete it with NVDA or JAWS on Windows, VoiceOver on macOS/iOS or TalkBack on Android — every field, group, hint and error is announced meaningfully (see the screen-reader testing guide).
  • Error pass: submit empty, submit each wrong format, trigger server-side errors, trigger the timeout. Observe focus movement and announcements.
  • Visual pass: zoom to 200% and check reflow at 320 CSS px wide; labels and errors stay next to their fields; errors do not rely on colour; field borders and focus indicators meet non-text contrast.

Try it: Validation Test Generator Try it: Fake Name Generator

Checklist: accessible form test cases

Copy this into your test management tool as one checklist per form, or turn each line into a test case with the form’s real fields and data.

FORM A11Y CHECKLIST — <form name / URL / build>

Labels & instructions
[ ] Every field has a visible label and a matching accessible name (1.3.1, 3.3.2, 2.5.3)
[ ] Placeholder is never the only label
[ ] Format hints are associated with the field (aria-describedby) and read on focus
[ ] Required fields: visible text or explained marker + required/aria-required (1.3.1, 1.4.1)

Grouping
[ ] Radio/checkbox groups and split fields (date, phone) have fieldset+legend or role=group with a name

Errors
[ ] Empty submit: each error names the field and is in text (3.3.1)
[ ] Wrong format: message suggests the correct format with an example (3.3.3)
[ ] Error is associated with the field; aria-invalid set on invalid fields
[ ] Errors are announced: focus moves to summary/first error, or live region used (4.1.3)
[ ] Errors are not shown by colour alone (1.4.1)
[ ] Changing a field does not submit or navigate unexpectedly (3.2.2)

Prevention & redundant entry
[ ] Legal/financial/data-changing submit: review, undo or check-and-correct exists (3.3.4)
[ ] Data from earlier steps is pre-filled or selectable (3.3.7)
[ ] Session timeout can be extended without data loss (2.2.1)

Purpose & authentication
[ ] autocomplete tokens correct on personal-data fields (1.3.5)
[ ] Paste and password managers work on username/password/OTP fields (3.3.8)
[ ] Pasting a full OTP into split boxes fills all boxes
[ ] CAPTCHA has an alternative and a text alternative (3.3.8, 1.1.1)

Operation
[ ] Whole form completable by keyboard only; focus visible
[ ] Whole form completable with a screen reader
[ ] 200% zoom and 320 CSS px width: no lost labels or errors
[ ] RTL forms: lang="ar" dir="rtl"; LTR data fields use dir="ltr"/"auto"

Try it: AI QA Checklist Generator

Typical defects, written as bug titles

Accessibility bugs get fixed faster when the title names the control, the observable failure and the affected users, and the body cites the success criterion. Full report structure is covered in the bug-report guide; these are realistic titles to model yours on.

  • “Sign-up: Email field has no accessible name — screen readers announce ‘edit text’ only (1.3.1, 4.1.2)”
  • “Checkout: card errors shown only as red border; no text message (1.4.1, 3.3.1)”
  • “Payment: error summary appears after submit but focus stays on button and nothing is announced (4.1.3)”
  • “Login: paste blocked in password field, password managers cannot fill it (3.3.8)”
  • “OTP screen: pasting 6-digit code fills only first box of six (3.3.8)”
  • “Visa application step 3: passport number must be typed again although entered in step 1 (3.3.7)”

Try it: AI Bug Title Generator

Arabic and right-to-left forms

Arabic forms add their own checks on top of the list above. The page or form needs lang="ar" and dir="rtl" so screen readers switch voice and read in the correct order; labels, hints and error summaries must follow the right-to-left reading order, and focus order must match it. Fields that hold left-to-right data — email, URL, IBAN, many phone formats — usually need dir="ltr" (or dir="auto") on the input itself so that characters are not reordered while typing, and error messages that quote such values must not scramble them.

Validation must accept how people actually type in Arabic: Arabic-Indic digits in phone and ID numbers if the system converts them, names in Arabic script, and — where the business accepts it — Hijri dates. An error message such as “Enter a valid name” fired on correct Arabic input is both a functional and an accessibility defect. The right-to-left testing guide covers bidirectional text, mirroring and mixed-direction input in depth.

Try it: Fake Name Generator

Frequently asked questions

Is in-field hint text enough as a label?

No. It disappears when the user starts typing, often has low contrast and is not reliably exposed as an accessible name. Use a visible label associated with the field; keep in-field hint text, if at all, for an example value.

Should errors appear inline, in a summary, or both?

WCAG requires that the field is identified and the error described in text; it does not mandate a layout. Many teams use both: a summary at the top that receives focus after submit, with links to each field, plus a message next to each field that is associated with it programmatically.

aria-live="polite" or role="alert" for form errors?

Use polite announcements (role="status" or aria-live="polite") for status updates and non-urgent messages, and role="alert" sparingly for errors that need immediate attention. Whichever you use, verify with a real screen reader that the message is announced once and not repeated on every keystroke.

Does 3.3.8 ban passwords?

No. It requires that a cognitive function test is not the only way through, or that a mechanism assists. Allowing password managers to fill the field and allowing paste is a mechanism WCAG itself gives as an example.

Is autocomplete="off" a WCAG failure?

For fields that collect information about the user and have a purpose in WCAG’s input-purpose list, the purpose must be programmatically determinable; autocomplete="off" removes that signal, so it is normally reported against 1.3.5. It is legitimate on fields that are not about the user, such as a search box or a one-off reference.

References

  • Web Content Accessibility Guidelines (WCAG) 2.2W3C · 2024The W3C Recommendation that defines the testable success criteria for accessible web content, organised under four principles and three conformance levels (A, AA, AAA).
  • Understanding WCAG 2.2W3C Web Accessibility Initiative (WAI)The informative explanation of each WCAG 2.2 guideline and success criterion: intent, who benefits, examples and techniques (not normative).
  • How to Meet WCAG (Quick Reference)W3C Web Accessibility Initiative (WAI)A filterable checklist of every WCAG 2.2 success criterion with its sufficient techniques and common failures.
  • Accessible Rich Internet Applications (WAI-ARIA) 1.2W3C · 2023The W3C Recommendation that defines ARIA roles, states and properties — how custom widgets expose their meaning to assistive technology.
  • ARIA Authoring Practices Guide (APG)W3C Web Accessibility Initiative (WAI)Patterns for common widgets (tabs, menus, dialogs, comboboxes) with the expected keyboard interaction and ARIA usage — the reference testers compare custom components against.
  • Accessibility — MDNMDN Web Docs (Mozilla)Practical guides to building and checking accessible web pages: semantic HTML, ARIA, keyboard support and testing.
  • Evaluating Web Accessibility OverviewW3C Web Accessibility Initiative (WAI)W3C's entry point for accessibility evaluation: why to evaluate early and throughout development, and how manual checks, tools and user involvement fit together.

Practice exercise

Review a four-step order form against WCAG 2.2 AA

Your task

You test the online order for home fibre internet of a fictional provider in Saudi Arabia. The order has four steps: sign in with a mobile number, your details, installation, and review and pay. The test basis for accessibility is WCAG 2.2 Level AA. Before the release you review the form with the guide’s procedure. The material below gives the markup of Step 2 as it is served and your notes from the keyboard, screen-reader and error passes.

Work on paper with the guide’s list of criteria and its checklist. For every defect, give the success criterion with its number, name and level; for every item that is not a defect, say why. Allow 20–30 minutes.

Material
Home fibre order of an internet provider in Saudi Arabia (fictional) - web, staging
Page: <html lang="en">. Test basis: WCAG 2.2, Level AA.
Steps: 1 Sign in with mobile · 2 Your details · 3 Installation · 4 Review and pay
Step 1 signs the customer in with the mobile number and a 6-digit code sent by SMS;
a new number creates an account.

Step 2 markup (excerpt, as served)

<h2>Step 2 of 4: Your details</h2>
<p>All fields are required.</p>
<form id="details" novalidate>
  <span class="lbl">Full name</span>
  <input id="name" name="name" autocomplete="name" required>

  <label for="email">Email</label>
  <input id="email" name="email" type="email" autocomplete="off" required>

  <input id="mobile" name="mobile" type="tel" placeholder="Mobile number" required>

  <p>Date of birth</p>
  <select id="dob-d" name="dob-d" aria-label="Day" required>…</select>
  <select id="dob-m" name="dob-m" aria-label="Month" required>…</select>
  <select id="dob-y" name="dob-y" aria-label="Year" required>…</select>

  <label for="nid">National ID or Iqama number</label>
  <input id="nid" name="nid" inputmode="numeric" aria-describedby="nid-hint" required>
  <p id="nid-hint">10 digits, starting with 1 (national ID) or 2 (Iqama)</p>

  <button type="submit" aria-label="Submit form">Next</button>
</form>
Each date list shows Day, Month or Year until a value is chosen.
The form validates with its own script (novalidate) when a field loses focus
and when Next is pressed.

Notes from the other passes (keyboard only; NVDA with Chrome on Windows)

N1 Step 1: the code goes into six boxes inside a <fieldset> whose <legend> reads
   "Enter the 6-digit code we sent by SMS". Each box has maxlength="1" and is named
   Digit 1 to Digit 6. Typing a digit moves focus to the next box. Pasting the code
   482913 from the SMS into the first box puts 4 in it; the other five stay empty.
N2 Step 1: the six code boxes have no autocomplete attribute.
N3 Step 2, Next pressed with every field empty: each field gets a red border.
   No text appears anywhere, focus stays on Next and NVDA says nothing.
N4 Step 2, a national ID of 9 digits, then Next: the red text "Invalid input"
   appears under the field and focus moves to the field.
N5 Step 2, leaving the Email field with an address that already has an account:
   "This email is already registered. Sign in instead." appears under the field,
   in a <div class="err"> that the script creates at that moment, with no role
   and no aria-live. NVDA says nothing.
N6 Step 3: the "Installation slot" list (<select>) submits the step as soon as its
   value changes. On the closed list, Down Arrow selects the next slot and Step 4
   opens at once.
N7 Step 4: every value from steps 1 to 3 is listed under a heading per step, and
   each step has its own edit link named after it (for example "Edit installation").
   The order is placed only when the user ticks "I have checked my order" and
   presses "Pay 299.00 SAR". It can be cancelled free of charge for 24 hours.
Steps
  1. Do the structure pass on the Step 2 markup: for each control, write its accessible name, how its group, hint and required state are exposed, and its autocomplete token. Mark every failure with its criterion.
  2. Classify notes N1 to N7: a defect, with the success criterion, or not a defect, with the reason.
  3. Write a bug title for each defect in the guide’s pattern (screen, control, observable failure, criterion), and mark the defects that can stop a group of users from finishing the order.
  4. Write the markup or behaviour change that fixes each defect, then list what you will check in confirmation testing and in regression testing when the fixes arrive.
Show the model answer
Model answer

Structure pass on Step 2, control by control. Full name: the accessible name is empty, because the visible text is a <span> and not a <label> tied to the input, so a screen reader announces an unnamed edit field. This fails 1.3.1 Info and Relationships (A) and 4.1.2 Name, Role, Value (A); its autocomplete="name" and required are correct. Email: named by its <label>, required state exposed, but autocomplete="off" on a field that collects the user’s own address fails 1.3.5 Identify Input Purpose (AA). Mobile number (mobile): its only label is the placeholder, which disappears as soon as the user types and is not reliably exposed as a name, so it breaks the checklist rule that a placeholder is never the only label (3.3.2 Labels or Instructions, A); it also lacks autocomplete="tel" (1.3.5). Above all, the number was entered and verified in Step 1 and is neither pre-filled nor offered for selection: 3.3.7 Redundant Entry (A). No exception applies: re-entry is not essential, not needed for security, and the number is still valid.

Date of birth: each list has a name (Day, Month, Year) that matches its visible text, but the question "Date of birth" is a plain <p>, so a screen-reader user hears "Day, combo box" without knowing which date is meant. The group is not exposed: 1.3.1 (A). The three lists also lack autocomplete="bday-day", "bday-month" and "bday-year", which are in WCAG’s input-purpose list: a second 1.3.5 (AA) failure. National ID or Iqama number: named by its <label>, the format hint is read on focus through aria-describedby, and the required state is exposed — no defect. It has no autocomplete token, and that is correct: a national ID is not one of WCAG’s input purposes. Next button: its accessible name comes from aria-label="Submit form" and does not contain the visible word "Next", so a voice-control user who says "click Next" gets no result: 2.5.3 Label in Name (A). The page declares its language (lang="en", 3.1.1 Language of Page), so screen readers use the right voice: no defect.

The notes. N1 — defect, 3.3.8 Accessible Authentication (Minimum) (AA). Step 1 is the sign-in, and typing a code from an SMS is the transcription that the Understanding document treats as a cognitive function test; paste, the mechanism that would satisfy the criterion, fills only the first box. N2 — not a defect: autocomplete="one-time-code" helps browsers offer the code, but a one-time code is not in WCAG’s input-purpose list, so its absence does not fail 1.3.5; recommend it as good practice in the N1 report. N3 — defect: the errors are shown by colour alone, which fails 1.4.1 Use of Color (A), and no field is identified and no error described in text, which fails 3.3.1 Error Identification (A); a screen-reader user is not even told that the step was rejected. N4 — defect, 3.3.3 Error Suggestion (AA): the correction is known (10 digits, starting with 1 or 2) and the message does not suggest it.

N5 — defect, 4.1.3 Status Messages (AA): an error that appears without moving focus must reach assistive technology through a role or a live region, and a plain <div> created at that moment gives NVDA nothing to announce. N6 — defect, 3.2.2 On Input (A): changing the value of a list must not cause an unexpected change of context, and here a keyboard user who browses the slots with the arrow keys submits the step on the first key press. N7 — not a defect. Payment is a financial transaction, so 3.3.4 Error Prevention (Legal, Financial, Data) (AA) applies, and it is met twice: the user can review, correct and confirm everything before paying, and the order can be cancelled for 24 hours; one of the two would be enough. The review screen still belongs in your keyboard and screen-reader passes.

Bug titles, starting with the four that can stop a group of users: (1) "Step 1 OTP: pasting the 6-digit SMS code fills only the first of six boxes (3.3.8)". (2) "Step 2: Full name field has no accessible name — screen readers announce an unnamed edit field (1.3.1, 4.1.2)". (3) "Step 2: empty submit shows red borders only — no error text, nothing announced (1.4.1, 3.3.1)". (4) "Step 3: Installation slot list submits the step on change — keyboard users cannot choose the slot they want (3.2.2)". Then: (5) "Step 2: Next button is named ‘Submit form’ — voice command ‘click Next’ does nothing (2.5.3)". (6) "Step 2: mobile number verified in Step 1 must be typed again, labelled only by a placeholder (3.3.7, 3.3.2)". (7) "Step 2: date of birth lists not grouped — screen readers announce ‘Day’ without ‘Date of birth’ (1.3.1)". (8) "Step 2: Email has autocomplete="off"; mobile number and date of birth lists have no autocomplete tokens (1.3.5)". (9) "Step 2: national ID error says only ‘Invalid input’ — expected format not suggested (3.3.3)". (10) "Step 2: ‘This email is already registered’ is not announced to screen readers (4.1.3)".

Why those four: N1 stops people who cannot transcribe a code reliably at the very first step, so they never reach the rest of the order. For screen-reader users, the unnamed Full name field and the colour-only errors together mean they cannot tell what to type or why the step is rejected. Keyboard users on Windows cannot choose any slot but the next one, unless they happen to open the list first with Alt+Down Arrow. The other six make the order slower or harder without stopping it; a voice-control user, for example, can still reach the button with other, slower commands. A different split with a recorded reason is fine: some teams count the Label in Name defect as stopping voice-control users.

Fixes. Full name: <label for="name">Full name</label> instead of the <span>. Email: autocomplete="email". Mobile: remove the field from Step 2 and show the verified number as text with a link back to Step 1, or pre-fill it with a visible <label> and autocomplete="tel". Date of birth: wrap the three lists in a <fieldset> with <legend>Date of birth</legend> and add autocomplete="bday-day", "bday-month" and "bday-year". Next: remove the aria-label, so that the name is the visible word. Step 1: one code input with a visible label, inputmode="numeric" and autocomplete="one-time-code", or a paste handler that spreads the six digits over the boxes.

Errors: when Next is pressed, give each invalid field a text message that names it ("Enter your full name"), connect it with aria-describedby and set aria-invalid="true"; then move focus to an error summary at the top that links to each field, or to the first invalid field. The red border can stay as an extra signal. The national ID message becomes "Enter the 10-digit number that starts with 1 (national ID) or 2 (Iqama)". For the email check, put an empty container with role="status" in the page when it loads (or role="alert", if the team treats the message as urgent), insert the text into it and tie it to the field with aria-describedby. Installation slot: changing the list only changes the value, and the step is submitted by its own Next button. Warning users about the behaviour before the list would meet the wording of 3.2.2, but it would not solve the keyboard problem.

Confirmation testing on the fixed build repeats each failed check: the accessibility pane shows "Full name", the group "Date of birth" and the button "Next"; browser autofill fills the email and the date of birth; Step 2 no longer makes the user type the mobile number again; pasting a full 6-digit code fills every digit and the code is accepted; an empty submit and a 9-digit national ID give text messages that NVDA announces and that make sense without colour; the already-registered message is announced once, without focus moving; Down Arrow on the slot list changes the slot and stays on Step 3. Regression testing: one keyboard pass and one screen-reader pass through all four steps, because labels, focus handling and validation changed, plus a check that Step 4 still lists the right values.

If your list differs, check each item against the criterion’s exact wording and level. A defect report names the control, the observable failure and the criterion; something that is only good practice (N2) or already conforms (the national ID without a token, N7) is recorded as a recommendation or a pass, not as a defect.

Your progress on this topic

Part of the QA Roadmap

Tools mentioned in this guide

Check HTML for common accessibility problems — missing alt text, unlabeled fields, nameless buttons and links, ARIA errors, headings, contrast — mapped to WCAG 2.2.

Validation New

Generate validation test cases for form fields: required, format, length, range, pattern and cross-field rules.

Test Design

Generate negative test cases for form fields and APIs: empty, null, wrong type, too long, injection, invalid format.

Test Design

Generate field-level validation error payloads for forms and APIs, in bulk, for UI error-state testing.

Mocking

Generate fake user records (name, username, email, password, avatar seed, role) for test accounts.

Test Data

Generate random first and last names in English, Arabic and Hindi with gender and format options.

Test Data

Generate a tailored QA checklist (functional, UI, API, security, performance, accessibility, release) for any feature with Mutqan AI.

Test Generation AI

Generate clear, searchable bug titles from a messy description with Mutqan AI.

Bug Analysis AI

How Mutqan Soft can help

More guides

More guides