Skip to content

[a11y][P0-2] Add PR CI with unit tests and an axe baseline gate #36

Description

@BrianGenisio

Why

There is currently no CI on pull requests. .github/workflows/release.yml triggers only on release: created, so nothing runs npm test when a PR opens, and nothing checks accessibility at all.

Without a gate, the 16 accessibility fixes in the remediation plan will erode. Several of them are the kind of thing a well-meaning refactor silently undoes — a focus call removed, an aria-selected dropped, a token overridden.

Scope

Add .github/workflows/pr.yml triggered on pull_request:

  • Checkout with git submodule update --init (the design system is required to render)
  • Node 20, npm ci, matching the existing release workflow
  • npm test
  • npm run build
  • Start the server, run an axe scan in both color schemes, fail on regression

The axe gate

The audit harness already does this and can be adapted directly. It boots the app, drives it through five states (empty, streaming, populated, settings modal, settings modal with dropdown open), and scans each in light and dark.

Two adaptations needed for CI:

  1. No live agent. The audit run had working Octavus credentials, so it could send a real prompt and scan a populated conversation. CI will not. Either stub the API endpoints, or reduce the CI scan to the states reachable without a backend and keep the full sweep as a manual job.
  2. Baseline, not zero. The app does not pass axe cleanly today. Capture the current violations as a checked-in baseline and fail the build when a new violation appears or a fixed one returns. The baseline should only ever shrink; each fix PR updates it downward.

Known baseline as of the audit

Per state, consistent across both themes:

Rule Impact Nodes
color-contrast serious 3 (4 in dark, settings modal)
nested-interactive serious 2 (3 with the modal open)
aria-allowed-role minor 1
landmark-one-main moderate 1
page-has-heading-one moderate 1
region moderate 1 (6 with the dropdown open)
aria-input-field-name serious 1 (dropdown open only)

Important limitation to document

axe cannot detect A1, the most severe finding in the audit. A live region that re-announces its entire contents is valid HTML; only a screen reader reveals the problem. This gate is a floor, not a ceiling — the plan's manual VoiceOver checks stay mandatory regardless of CI status.

Worth stating in the workflow file itself so nobody mistakes a green badge for conformance.

Acceptance criteria

  • A PR runs unit tests, a build, and an axe scan in both color schemes
  • A new axe violation fails the build
  • The baseline is checked in and documented as shrink-only
  • The workflow notes that axe does not cover live-region behavior

Reference

a11y-audits/8-5-26/resolution-plan.md → Wave 0 → P0-2

Metadata

Metadata

Assignees

No one assigned

    Labels

    a11yAccessibilityseverity:seriousMajor barrier for some users

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions