Accessible Forms with Tests

Form roles cheatsheet
Role name HTML snippet
form<form>
search<form role=search>
group<fieldset>
button<button>
button<input type=button>
button<button type=submit>, <input type=submit>
textbox<textarea>
textbox<input type=text>
textbox<input type=email>
textbox<input type=tel>
textbox<input type=url>
searchbox<input type=search> without list attribute
radiogroup<fieldset role=radiogroup>
radio<input type=radio>
checkbox<input type=checkbox>
combobox<select> without multiple attribute
listbox<select> with multiple attribute
option<option>
slider<input type=range>
none<input type=password>
progressbar<progress>
status<output>

Note: The code examples here use Testing Library, which works with React, Vue, Preact, Angular, Puppeteer, and more.


Form

<form aria-labelledby=sign-up-heading>
  <h1 id=sign-up-heading>Sign Up</h1>
  …
</form>
screen.getByRole('form', { name: 'Sign up' });

Button

<button>Save</button>
screen.getByRole('button', { name: 'Save' });

Disabled

<button disabled>Save</button>
expect(screen.getByRole('button', { name: 'Save' })).toBeDisabled();

Textbox

<label>Name <input type=text></label>
screen.getByRole('textbox', { name: 'Name' });

Multilined

<label>Bio <textarea></textarea></label>
screen.getByRole('textbox', { name: 'Bio' });

Specific types

<label>Email <input type=email></label>
<label>Website <input type=url></label>
<label>Phone <input type=tel></label>
const emailTextbox = screen.getByRole('textbox', { name: 'Email' });
const websiteTextbox = screen.getByRole('textbox', { name: 'Website' });
const phoneTextbox = screen.getByRole('textbox', { name: 'Phone' });

Expect value to match

<label>Bio <textarea>Some bio</textarea></label>
expect(
  screen.getByRole('textbox', { name: 'Bio' })
).toHaveValue("Some bio");

Searchbox

<label>Search <input type=search></label>
screen.getByRole('searchbox', { name: 'Search' });

Checkbox

<label><input type=checkbox> Receive email alerts</label>
screen.getByRole('checkbox', { name: 'Receive email alerts' });

Expect to be checked

<label><input type=checkbox checked> Receive email alerts</label>
expect(
  screen.getByRole('checkbox', { name: 'Receive email alerts' })
).toBeChecked();

Radio & Radiogroup

<fieldset role=radiogroup>
  <legend>Favorite color</legend>
  <label><input type=radio name=fave-color value=green> Green</label>
  <label><input type=radio name=fave-color value=red checked> Red</label>
  <label><input type=radio name=fave-color value=yellow> Yellow</label>
  <label><input type=radio name=fave-color value=blue> Blue</label>
</fieldset>
screen.getByRole('radiogroup', { name: 'Favorite color' });
expect(screen.getByRole('radio', { name: 'Red' })).toBeChecked();
expect(
  screen.getByRole('radiogroup', { name: 'Favorite color' })
).toHaveFormValues({ 'fave-color': 'red' });