Accessibility Lab
Find planted accessibility problems with axe, prove a fixed form is clean, and complete a form with the keyboard alone. Each task ticks itself when your script gets it right.
1.Find the Planted Problems
Scan the form below with axe-core, then tick exactly the rules it reports and press Check.
- Ticking exactly the reported rules turns the result green.
- Ticking a rule the form does not break, or missing one, fails.
Scroll the form into view, scan only #a11y-broken with the wcag2a and wcag2aa tags, and tick each violations[].id.
import AxeBuilder from '@axe-core/playwright';
await page.locator('#a11y-broken').scrollIntoViewIfNeeded(); // axe skips contrast for off-screen text
const { violations } = await new AxeBuilder({ page })
.include('#a11y-broken').withTags(['wcag2a', 'wcag2aa']).analyze();
for (const v of violations) await page.locator(`#rule-${v.id}`).check();
await page.locator('#check-a11y').click();2.The Fixed Version
Scan this form with axe and assert the violations list is empty. This task ticks once axe has been loaded into the page; the assertion itself lives in your test.
- axe reports no violations for this form.
- Scanning the whole page instead of this form mixes in other sections.
Run the same scan on #a11y-fixed and assert that the violations list is empty.
const { violations } = await new AxeBuilder({ page })
.include('#a11y-fixed').withTags(['wcag2a', 'wcag2aa']).analyze();
expect(violations).toEqual([]);3.Keyboard Only
Favourite tool
- Playwright
- Selenium
- Cypress
- WebdriverIO
Fill in the form, pick Cypress, accept the terms and submit, using only the keyboard. The confirm dialog traps focus: Tab stays inside it and Escape closes it.
- Confirming with the keyboard turns the result green.
- Any mouse click or tap in this section fails the task until you press Reset.
Focus the name field with focus(), not a click. Then type, Tab, ArrowDown twice, Tab, Space, Tab, Enter and Enter again.
await page.locator('#kb-name').focus();
await page.keyboard.type('Ada');
await page.keyboard.press('Tab');
await page.keyboard.press('ArrowDown');
await page.keyboard.press('ArrowDown'); // listbox: Cypress
await page.keyboard.press('Tab');
await page.keyboard.press('Space'); // terms checkbox
await page.keyboard.press('Tab');
await page.keyboard.press('Enter'); // opens the dialog
await page.keyboard.press('Escape'); // focus returns to Submit
await page.keyboard.press('Enter');
await expect(page.locator('#kb-confirm')).toBeFocused();
await page.keyboard.press('Enter');4. Solutions
Try the challenges yourself first. Reference solutions are hidden until you ask for them.
About this Accessibility Lab page
Accessibility testing checks that people using screen readers, keyboards and other assistive tools can use a page. You practice it by running axe-core against a page with known WCAG violations, fixing or asserting on them, and then completing a form with the keyboard only. This free lab does that and works with Playwright, Selenium and Cypress.

Frequently asked questions
How do I run axe accessibility tests in Playwright?
Install @axe-core/playwright, create an AxeBuilder with your page, call analyze(), and assert that results.violations is empty. You can scope the scan with include() or limit rules with withTags(['wcag2a', 'wcag2aa']). Run the scan after the page reaches the state you want to check.
Can Selenium run axe-core accessibility scans?
Yes. Selenium Java has the com.deque.html.axe-core:selenium package with AxeBuilder, and Python has axe-selenium-python. Both inject axe-core into the page and return a violations list you can assert on. Selenium has no built-in accessibility audit.
What can automated accessibility tests not catch?
Automated tools such as axe find roughly a third to half of WCAG issues, mainly missing labels, bad contrast and invalid ARIA. They cannot judge whether alt text is meaningful, whether focus order makes sense or whether a screen reader flow is usable. Manual and keyboard checks are still needed.
How do I test keyboard navigation in an automated test?
Send Tab, Shift+Tab, Enter and Space key presses and assert which element has focus after each one. In Playwright use page.keyboard.press('Tab') and expect(locator).toBeFocused(). In Selenium use Actions or send_keys with Keys.TAB, then compare the active element.
Where can I practice accessibility testing for free?
The Accessibility Lab on QA Playground has planted axe violations, a task to assert a clean scan after fixes, and a keyboard-only form task. It needs no signup, runs in the browser, and includes reference solutions in Playwright, Selenium Java, Selenium Python and Cypress.
Free developer tools on Randomly.online
QA Playground is part of Randomly.online. These tools help while you write and debug tests:
