Accessibility and testing

Testing integrations

Test patterns for adapters, runtime behavior, browser delivery, and hands-on screen-reader checks.

Test each layer separately

A runtime transcript shows what core prepared. A DOM test shows how the page changed. Test with a real screen reader to confirm what it speaks.

LayerCheckDoes not confirm
AdapterEvents and stable IDsAnnouncements
CorePrepared updates, timing, suppression, cancellationBrowser behavior
DOMBrowser results and page updatesScreen-reader speech
BrowserKeyboard, landmarks, focus, live regionsEvery screen reader and browser combination
Hands-on screen-reader testOne user workflowBehavior in every environment

Test every supported browser engine

Browser fixtures run in Chromium, Firefox, and WebKit. They check keyboard use, stable focus, page landmarks, live regions, and page announcements.

shell
pnpm test:browser:install
pnpm test:browser

How this code works

  1. 01
    Install engines

    Repository scripts install the Chromium, Firefox, and WebKit versions used by tests.

  2. 02
    Run browser tests

    This command runs cross-browser accessibility fixtures and documentation checks.

  3. 03
    Interpret the result

    A passing browser test confirms browser behavior, not screen-reader speech.

Test a realistic app workflow

Fixtures cover streaming text, tool updates, stopping, retrying, and browser announcements. Each assertion names the behavior it checks.

  • Run the same scenarios in all three browser engines.
  • Check that streaming and status updates do not move focus.
  • Connect each app event to the runtime update and the resulting page change.
  • Keep controls and visible status usable without the library.

Record hands-on screen-reader tests

For each release, record the date, browser, operating system, screen reader and version, workflow, expected result, actual result, and outcome. Repository validation checks every required field.

Use ManualClock for time-dependent behavior

Advance the test clock instead of waiting for real timers. Check diagnostics when the runtime intentionally skips an update.

typescript
const recorder = createAnnouncementRecorder({ preset: "balanced" });
const runtime = recorder.runtime;
const clock = recorder.clock;

runtime.dispatch(started);
runtime.dispatch(delta);
clock.advanceBy(2_000);

expect(recorder.transcript()).toHaveLength(1);

How this code works

  1. 01
    Create the harness

    createAnnouncementRecorder supplies a runtime and ManualClock.

  2. 02
    Send app events

    Use the same events your integration sends in the application.

  3. 03
    Advance the clock

    Tests stay fast and repeatable while checking delayed updates.