# How do I check an AI-built page with a keyboard and screen reader?

> Review an agent-built form and dialog with keyboard, accessible-name, error, and screen-reader checks before accepting the PR.

Canonical HTML: https://canopyide.dev/guides/test-ai-built-ui-keyboard-screen-reader-before-merge
Article date: 2026-09-28

A screenshot can prove layout but cannot show whether a person can reach a control, understand its label, escape a dialog, or hear a form error. For an agent-built signup page, review one complete keyboard and assistive-technology journey before merging. This is a practical release check, not a claim that a few tests establish full accessibility conformance. Use the same running commit and browser state that the pull request will ship.

## Start with a real journey, not a scan score

Choose the main user action and one failure state. In the signup example, a person opens the page, reaches the form, fills required fields, submits, sees a validation error, corrects it, and reaches a confirmation dialog. Run the current branch in Canopy Preview, record the viewport and commit, and note which controls the mouse route uses. W3C's preliminary checks include keyboard access, visible focus, and form labels. If a designer supplied a Figma frame, check its states as inputs to implementation, but evaluate the working page rather than assuming the design file supplies behavior.

- Use a test account and non-sensitive data.
- Name the exact action that should work and the error the user should understand.
- Keep the agent's final diff and the running preview tied to the same checkout.

## Walk the journey by keyboard

Put the pointer aside and move through the page with Tab and Shift+Tab. At each step, identify the focused control and whether focus is visibly indicated and not hidden behind a sticky element. Activate buttons and links from the keyboard using their expected keys, then fill and submit the form. Check that focus order follows a useful reading and action order, and that no component traps focus with no way out. W3C distinguishes an intentional modal focus loop from a keyboard trap: a modal can keep Tab inside while open, but users must be able to close it and continue. For the signup dialog, check focus moves inside when it opens, Escape or the available close control dismisses it, and focus returns to a sensible element afterward.

*Record observations against one signup journey.*

| Step | Expected | Failure evidence |
| --- | --- | --- |
| Enter page | First meaningful control can be reached; focus visible | Tab skips action or focus disappears |
| Complete form | Labels identify fields; keyboard can submit | Only pointer click works or control has no usable name |
| Validation | Error identifies field and can be found | Red border alone; error is not announced or associated |
| Confirmation dialog | Focus enters, remains usable, and returns after close | Focus stays behind overlay or cannot escape |

## Check names, roles, and errors

Inspect the browser's accessibility information or use a screen reader available on your test platform for a short pass through the same form. A visible icon may be read as an unlabeled button; placeholder text may disappear when a person types; a red outline may not explain which value is wrong. W3C's form guidance recommends explicit label associations and accessible error notifications. Ask the agent to use native controls where possible and to connect field errors to their controls. A custom clickable div with an ARIA role is not automatically keyboard-operable; W3C's keyboard-interface guidance says custom widgets need keyboard behavior implemented. Test the observed name and announcement, not merely the presence of aria attributes in code.

- Verify each important button and form field has the intended accessible name.
- Trigger both empty-required and malformed-value errors and inspect how each is exposed.
- Check the confirmation message and return path after successful submission.

## Use automation to catch regressions, then test manually

If the project uses Playwright, role and accessible-name locators can make the user's control names part of an interaction test. Playwright documents axe-based scans for detectable issues, including some missing labels and contrast problems, and recommends manual assessment because automated checks cannot find every accessibility failure. Run a scan after revealing the relevant dialog or error state, not only on the initial page. Keep the keyboard and screen-reader observation as separate evidence. A zero-violation scan cannot prove the modal is useful, the error message makes sense, or the task can be completed.

- Do not add a passing accessibility test by excluding the broken component from the scan.
- A role locator finding a button is useful evidence, but still verify keyboard activation and its resulting behavior.
- Retest the state after the final agent fix, not the earlier preview.

## Give the agent a reproducible fix and close the review

Report the exact branch, URL, viewport, control, keyboard steps, expected behavior, observed behavior, and any screen-reader announcement. For example: after submitting an empty email, focus remains on Submit and only a red border appears; expected: a named error is presented and the user can identify and correct the field. Let the agent make a bounded change, then repeat the keyboard journey, targeted automated check, and final diff review. If a specialist accessibility review is required for this product, assign it explicitly; this short trial is a gate for obvious failures and a precise handoff, not a substitute for a complete audit or user testing.

- Inspect changed event handlers, focus management, and form semantics in the PR.
- Confirm the fix did not break pointer or mobile interaction.
- Record untested assistive technologies and who owns follow-up review.

## Copyable resources

### Agent-built UI keyboard review

Use a test account. Record observations; do not claim conformance from a single scan or assistive-technology trial.

````text
Page, PR head commit, branch, preview URL, viewport: [ ]
Main journey and failure state: [ ]
Keyboard sequence: [control by control, Tab/Shift+Tab/activation]
Visible and unobscured focus at each step: [ ]
Form names, roles, and field-label association: [ ]
Empty/malformed submission and announced error: [ ]
Dialog open, focus inside, close, focus return: [ ]
Screen reader/platform and short observed announcement: [ ]
Automated scan scope, tool, state, and result: [ ]
Exact failure reproduction sent to agent: [ ]
Retest after final edit and latest diff: [ ]
Specialist or user-testing follow-up owner: [ ]
````

## Frequently asked questions

### Does a clean axe or Lighthouse score mean my AI-built page is accessible?

No. Automated tools catch some detectable problems. Manually test the keyboard path, meaning of labels and errors, dialog behavior, and relevant assistive technologies.

### Should Tab move out of a modal dialog?

While a modal is open, the W3C dialog pattern keeps Tab within the dialog. Users need a keyboard way to close it, and focus should return to a sensible place after closing.

### Can the coding agent run this whole review for me?

An agent can run checks and report browser evidence, but a person should verify the actual journey and decide whether specialist review or user testing is needed.

### What should I send the agent when a control fails?

Send the current commit and preview, exact keyboard steps, expected and observed focus or announcement, a screenshot or short recording if useful, and the smallest acceptance check for the fix.

## Sources and further reading

- [W3C WAI: easy accessibility checks](https://www.w3.org/WAI/test-evaluate/preliminary/)
- [W3C WAI: modal dialog keyboard pattern](https://www.w3.org/WAI/ARIA/apg/patterns/dialog-modal/)
- [W3C WAI: form labels and validation](https://www.w3.org/WAI/tutorials/forms/validation/)
- [W3C WAI: keyboard interface guidance](https://www.w3.org/WAI/ARIA/apg/practices/keyboard-interface/)
- [Playwright: accessibility testing and limits](https://playwright.dev/docs/accessibility-testing)
- [Canopy README: Preview and diff review](https://github.com/FluidWorksApp/canopy-ide/blob/main/README.md)

## Related Canopy pages

- [How do I test an AI-built UI before merging it?](https://canopyide.dev/guides/test-agent-built-ui-before-merge.md)
- [How do I turn a Figma design into a running page with a coding agent?](https://canopyide.dev/guides/figma-design-to-running-page-with-coding-agent-canopy.md)
- [How to give a coding agent useful visual feedback](https://canopyide.dev/guides/give-visual-feedback-to-coding-agent.md)
- [Can I launch my AI-built app? A founder's decision sheet](https://canopyide.dev/guides/ai-built-app-launch-checklist-for-founders.md)
- [Did your coding agent weaken a test to make CI pass?](https://canopyide.dev/guides/did-coding-agent-weaken-test-to-make-ci-pass.md)

Canopy runs installed coding CLIs; CLI accounts, model selection, and provider billing remain separate. Check the installed release before relying on version-specific behavior.
