Fix a11y violations in nightlies and improve a11y config (#7499)

# Description of Changes
This fixes the a11y violations that are currently failing in the
nightlies in dark mode. Now that we're down to 0 baseline, we can
require the a11y tests to pass in PRs before they merge, so I've changed
that, and I've also made it so that the nightly will report failures in
both light and dark mode instead of just light mode if that fails.

<img width="2560" height="838" alt="image"
src="https://github.com/user-attachments/assets/b0322182-f6ff-4dea-9a1c-5a6c9c9c5439"
/>
This commit is contained in:
James Brunton
2026-08-14 14:02:16 +01:00
committed by GitHub
parent 0be10b2dff
commit 588afb6306
5 changed files with 51 additions and 26 deletions
+6 -3
View File
@@ -134,9 +134,10 @@ jobs:
uses: ./.github/workflows/frontend-validation.yml
secrets: inherit
# Advisory: deliberately NOT in all-checks-passed. It reports on the stories a
# branch touches so a regression is visible in review, but a browser scan is
# too new here to block merges on. Promote it once its pass/fail proves stable.
# Required (in all-checks-passed). Scans the stories a branch touches in both
# light and dark; an axe violation in either theme blocks the merge. The
# whole-suite sweep (nightly.yml) still covers stories a change affects without
# touching them directly.
frontend-a11y:
if: needs.files-changed.outputs.frontend == 'true'
needs: [files-changed]
@@ -290,6 +291,7 @@ jobs:
- db-migration-test
- check-generateOpenApiDocs
- frontend-validation
- frontend-a11y
- playwright-e2e
- playwright-e2e-live
- playwright-e2e-enterprise
@@ -316,6 +318,7 @@ jobs:
db-migration-test=${{ needs.db-migration-test.result }}
check-generateOpenApiDocs=${{ needs.check-generateOpenApiDocs.result }}
frontend-validation=${{ needs.frontend-validation.result }}
frontend-a11y=${{ needs.frontend-a11y.result }}
playwright-e2e=${{ needs.playwright-e2e.result }}
playwright-e2e-live=${{ needs.playwright-e2e-live.result }}
playwright-e2e-enterprise=${{ needs.playwright-e2e-enterprise.result }}
+2 -7
View File
@@ -3,17 +3,12 @@ name: Frontend a11y regression gate
# Reusable workflow called from build.yml when frontend sources change.
#
# Scans the stories this branch touches in real Chromium and runs axe against
# each. Existing violations are grandfathered in .storybook/a11y-baseline.json;
# the check fails on a NEW violation — a story breaking a rule it wasn't already
# breaking — or on a story that fails to render at all.
# each; the check fails on any axe violation, or on a story that fails to render
# at all.
#
# Only changed stories, because a full sweep is ~30 minutes: far too slow to sit
# in front of every merge. The whole suite is scanned nightly instead
# (nightly.yml), which catches anything a branch didn't touch.
#
# Advisory for now: this is not in build.yml's all-checks-passed list, so a
# failure reports without blocking. Promote it once a few weeks of runs show the
# pass/fail is stable.
on:
workflow_call:
+10 -6
View File
@@ -64,10 +64,14 @@ jobs:
# the story itself — a shared component, a theme token — still surfaces within
# a day.
a11y-all-stories:
name: a11y (every story, light + dark)
name: a11y (every story)
strategy:
fail-fast: false
matrix:
theme: [light, dark]
runs-on: ubuntu-latest
# Two full sweeps (one per theme), each ~30 minutes of browser time.
timeout-minutes: 120
# One full sweep (~30 minutes of browser time).
timeout-minutes: 60
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@bf7454d06d71f1098171f2acdf0cd4708d7b5920 # v2.20.0
@@ -87,14 +91,14 @@ jobs:
- name: Install Task
uses: go-task/setup-task@01a4adf9db2d14c1de7a560f09170b6e0df736aa # v2.1.0
- name: a11y gate (every story, light + dark)
run: task frontend:storybook:a11y
- name: a11y gate (every story, ${{ matrix.theme }})
run: task frontend:storybook:a11y:${{ matrix.theme }}
- name: Upload scan reports
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: a11y-scan-nightly-${{ github.run_id }}
name: a11y-scan-nightly-${{ matrix.theme }}-${{ github.run_id }}
path: frontend/.a11y-scan/
retention-days: 14
if-no-files-found: ignore