Skip to content

Accessibility Audit (axe-core) #5

Accessibility Audit (axe-core)

Accessibility Audit (axe-core) #5

Workflow file for this run

name: Accessibility Audit (axe-core)
# WCAG 2.1 Level AA conformance check for the three main
# wl_manager dashboards. Uses axe-core via @axe-core/playwright.
#
# Runs weekly (Saturday 04:00 UTC) + on-demand via
# workflow_dispatch. Reports uploaded as artifacts. Exit-code
# semantics: 0 = pass, 1 = a11y failures, 2 = infrastructure
# error.
#
# Cadence rationale: weekly matches the ZAP scan cadence and is
# enough for a11y findings (which only change when the UI
# changes). If we later want PR-gating on UI-touching changes,
# add a `pull_request: paths: ['appserver/static/**']` trigger.
#
# See tests/a11y/README.md for the audit contract, pass/fail
# criterion, and baseline-suppression maintenance rules.
on:
schedule:
# 04:00 UTC Saturday. Off-peak. Separate from the nightly
# E2E (03:00 UTC weekdays) and ZAP (04:00 UTC Sunday) so a
# flaky weekend run doesn't compound with other workflows.
- cron: "0 4 * * 6"
workflow_dispatch:
permissions:
contents: read
jobs:
a11y-audit:
name: Accessibility Audit
runs-on: ubuntu-latest
# 25 minutes: ~1 min container startup + ~30s setup +
# ~5-10 min audit (axe-core is fast, but the Playwright
# navigation + render-wait between pages adds up) + ~30s
# teardown. Generous headroom for slow runners.
timeout-minutes: 25
permissions:
contents: read
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
- name: Set up Node.js
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version: "20"
cache: "npm"
- name: Install npm deps
run: npm ci
- name: Install Playwright browsers
# Pin to the same minor as playwright-core in package.json
# (currently 1.59.1) so the installed chromium revision matches
# what playwright-core resolves at runtime. See e2e-smoke.yml
# for the full explanation.
run: npx playwright@1.59.1 install --with-deps chromium
- name: Start Splunk container
run: docker compose up -d
- name: Fix bind-mount permissions for Splunk user
run: |
docker exec -u 0 wl_manager_test \
chown -R splunk:splunk \
/opt/splunk/etc/apps/wl_manager/bin \
/opt/splunk/etc/apps/wl_manager/default \
/opt/splunk/etc/apps/wl_manager/lookups \
/opt/splunk/etc/apps/wl_manager/appserver \
/opt/splunk/etc/apps/wl_manager/metadata
- name: Wait for Splunk + provision test users
run: bash tests/e2e/setup_test_env.sh wl_manager_test
- name: Run a11y audit
# `npm run test:a11y` → node tests/a11y/test_a11y_dashboards.cjs
# Exits 0/1/2 per the criterion in tests/a11y/README.md.
# We let exit 1 (a11y failures) fail the workflow so the
# weekly report demands attention. Exit 2 (infra error)
# also fails — distinguishable via logs.
run: npm run test:a11y
- name: Upload a11y reports
# Always upload — even on pass — so the weekly artifact
# forms a longitudinal record. Reviewing the trend across
# runs is more useful than just the latest run.
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: a11y-reports-${{ github.run_id }}
path: tests/a11y/reports/
retention-days: 30
- name: Capture Splunk logs on failure
if: failure()
run: |
mkdir -p ci-logs
docker compose logs --tail=500 > ci-logs/compose.log 2>&1 || true
docker exec wl_manager_test \
cat /opt/splunk/var/log/splunk/splunkd.log 2>/dev/null \
| tail -1000 > ci-logs/splunkd.log || true
- name: Upload Splunk logs on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: a11y-splunk-logs-${{ github.run_id }}
path: ci-logs/
retention-days: 14
- name: Teardown
if: always()
run: docker compose down -v