Skip to content

feat(frontend): automated accessibility testing with jest-axe (closes #132)#195

Open
Moonwalker-rgb wants to merge 1 commit into
ChainForgee:mainfrom
Moonwalker-rgb:feat/132-frontend-accessibility
Open

feat(frontend): automated accessibility testing with jest-axe (closes #132)#195
Moonwalker-rgb wants to merge 1 commit into
ChainForgee:mainfrom
Moonwalker-rgb:feat/132-frontend-accessibility

Conversation

@Moonwalker-rgb

Copy link
Copy Markdown
Contributor

What

Closes #132 — adds automated accessibility testing for the frontend using jest-axe, so axe-core violations surface in CI rather than at the aid recipient's keyboard.

Changes

Testing infrastructure

  • jest-axe@^10 and axe-core@^4.12 added as devDeps
  • New jest.setup.a11y.ts registers toHaveNoViolations globally via setupFilesAfterEnv
  • New jest-axe.d.ts (ambient types) so strict tsc --noEmit stays clean
  • New a11yTestUtils.tsx (renderAndCheckA11y helper returning a structured report) and a11y-mocks.tsx (shared mocks for next/link, next-intl, next/navigation, @stellar/freighter-api, and project hooks)
  • New a11y.test.tsx@jest-environment jsdom suite covering ErrorInline (banner + card), ActivityCenter, Navbar, ErrorBoundary, EvidenceArtifactViewer. 6 tests passing, 0 critical violations.

Component fixes (the axe violations the suite uncovered)

  • Icon-only close/remove buttons in ErrorInline and ActivityCenter now carry aria-label and the inner SVG aria-hidden="true" focusable="false"
  • The notification count badge in ActivityCenter is decorative (aria-hidden) with a new sr-only text node for screen readers
  • EvidenceArtifactViewer filename heading promoted from <h3> to <h2> to satisfy heading-order against pages that provide an <h1>

CI

  • New .github/workflows/frontend-ci.yml runs pnpm type-check, pnpm lint, and pnpm jest --ci on every PR touching app/frontend/**, using the official pnpm/action-setup and the pnpm store cache.

Lighthouse CI (documented, not gated)

  • app/frontend/lighthouserc.json asserts categories:accessibility ≥ 0.9
  • app/frontend/LIGHTHOUSE_CI.md explains why Lighthouse isn't part of the CI workflow yet — jest-axe already catches the same class of violations faster and with zero infrastructure overhead; Lighthouse is opt-in via pnpm dlx @lhci/cli autorun or a future scheduled workflow.

Tests

  • 89 unit tests pass on the existing baseline
  • 6 jest-axe tests pass with 0 critical violations
  • Frontend tsc --noEmit passes
  • Backend / mobile untouched by this PR

Notes

  • The shared axeContext prop on renderAndCheckA11y accepts an axe RunOptions object (or undefined). Use it to scope a scan to a single element when adding page-level tests.
  • Tests that depend on the <main> landmark wrap their fixture there to satisfy landmark-one-main and page-has-heading-one.
  • The EvidenceArtifactViewer heading change is a deliberate conformance trade-off — if the component is later embedded under a page that already uses an <h2>, swap it for a titleHeadingLevel prop or an aria-level heading role.

…hainForgee#132)

Introduces jest-axe as a first-class test dependency and wires it into
the unit-test runner via a shared @jest-environment jsdom suite, so any
new a11y regression surfaces in CI rather than in production.

Adds:
  - jest-axe + axe-core devDeps, jest-axe ambient types
  - jest.setup.a11y.ts registering toHaveNoViolations as a matcher
  - jest.config.ts setupFilesAfterEnv wiring
  - a11yTestUtils + a11y-mocks helper modules
  - a11y.test.tsx covering ErrorInline (banner + card), ActivityCenter,
    Navbar, ErrorBoundary, EvidenceArtifactViewer
  - frontend-ci.yml running type-check, lint, jest on app/frontend/**
  - lighthouserc.json + LIGHTHOUSE_CI.md (manual opt-in audit config,
    not gating CI per issue scope)

Fixes uncovered violations:
  - icon-only close/remove buttons get aria-label + aria-hidden=true
    on the inner SVG (ErrorInline, ActivityCenter)
  - notification-count badge gains sr-only text in ActivityCenter
  - EvidenceArtifactViewer filename heading promoted from <h3> to <h2>
    to satisfy heading-order axe rule against pages that provide <h1>

Copy link
Copy Markdown
Contributor Author

cc @Lansa-18 @maramina — recent frontend contributors. Specifically asking for review on (1) the jest-axe setup wiring in jest.config.ts, (2) the heading-order fix in EvidenceArtifactViewer.tsx since it couples the component to a specific page h1 contract, and (3) whether the lighthouserc.json should be wired up now or stay defer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] Frontend has no automated accessibility testing

1 participant