Skip to content

Simple guide · Overview

Page status: Active

axe Accessibility CI with Playwright

axe Accessibility CI is the automated accessibility safety net for the NutsNews web app.

Visual overview

Primary diagram

System map

axe Accessibility CI is the automated accessibility safety net for the NutsNews web app.

Render the repository-owned system map when you need it.

Diagram is not rendered yet.

View as text
axe Accessibility CI with Playwright

axe Accessibility CI is the automated accessibility safety net for the NutsNews web app.

flowchart TB
  accTitle: axe Accessibility CI with Playwright
  accDescr {
    axe Accessibility CI is the automated accessibility safety net for the NutsNews web app.
  }
  A["axe Accessibility CI with Playwright"] --> B["AXE_PLAYWRIGHT_ACCESSIBILITY_CI.md"]
  B --> C["Auto-generated placeholder diagram"]

axe Accessibility CI with Playwright

Fullscreen diagram view.

axe Accessibility CI is the automated accessibility safety net for the NutsNews web app.

It complements Lighthouse CI by running deeper page-level accessibility checks with Playwright and @axe-core/playwright on every push, pull request, and manual workflow run.

Use this for checking:

  • Missing image alternative text
  • Form label problems
  • Button/link naming problems
  • Landmark and heading issues
  • Color contrast issues detected by axe
  • Serious and critical WCAG violations before public launch or App Store review

This does not replace a manual WAVE browser-extension pass. Use WAVE manually before important releases, and use axe CI to catch regressions automatically.


NutsNews is a multi-folder repository.

The repository root is:

Terminal window
/Users/ramideltoro/WebstormProjects/nutsnews3

The Next.js website is inside:

Terminal window
/Users/ramideltoro/WebstormProjects/nutsnews3/web

That means Playwright and axe dependencies must be installed inside web/, not at the repository root.


FilePurpose
web/playwright.config.tsPlaywright test configuration for the built NutsNews web app
web/tests/accessibility.spec.tsaxe accessibility tests for public NutsNews pages
.github/workflows/accessibility-ci.ymlGitHub Actions workflow that runs the accessibility tests
web/package.jsonAdds the test:accessibility script and dev dependencies
web/package-lock.jsonLocks Playwright and axe dependency versions
web/.gitignoreIgnores generated local Playwright and Lighthouse reports

The first automated axe pass checks these public reader/support pages:

/
/about
/privacy
/contact

These are safe because they are public pages and do not trigger ingestion, AI review, translation, refresh work, database writes, OAuth flows, or admin-only workflows.

Do not add Worker refresh URLs, controller trigger URLs, admin pages, OAuth callback routes, or API routes that perform writes.


The first setup fails CI only for axe violations with these impacts:

critical
serious

Moderate and minor findings are still useful during manual review, but starting with serious and critical issues keeps the CI signal practical while NutsNews is still evolving.

Later, the threshold can be tightened to fail on moderate issues too.


Step 1 — Install Dependencies in the Web App

Section titled “Step 1 — Install Dependencies in the Web App”
Terminal window
cd /Users/ramideltoro/WebstormProjects/nutsnews3/web
npm install --save-dev @playwright/test @axe-core/playwright

Expected changed files:

web/package.json
web/package-lock.json

web/package.json should include:

{
"scripts": {
"test:accessibility": "playwright test --config=playwright.config.ts"
}
}

Keep the existing dev, build, start, and lint scripts.


The config starts the already-built Next.js app on a local CI port and runs Chromium-only accessibility tests.

import { defineConfig, devices } from '@playwright/test';
const PORT = Number(process.env.PLAYWRIGHT_PORT ?? 3100);
const baseURL = process.env.PLAYWRIGHT_BASE_URL ?? `http://127.0.0.1:${PORT}`;
export default defineConfig({
testDir: './tests',
timeout: 60_000,
expect: {
timeout: 10_000,
},
fullyParallel: false,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 1 : 0,
workers: 1,
reporter: process.env.CI ? [['line'], ['html', { open: 'never' }]] : [['list'], ['html', { open: 'never' }]],
use: {
baseURL,
trace: 'retain-on-failure',
screenshot: 'only-on-failure',
},
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
webServer: {
command: `npm run start -- -p ${PORT}`,
url: baseURL,
reuseExistingServer: !process.env.CI,
timeout: 120_000,
},
});

Step 4 — Add web/tests/accessibility.spec.ts

Section titled “Step 4 — Add web/tests/accessibility.spec.ts”

The test opens each public NutsNews page and scans it with axe.

The test currently uses these axe tags:

wcag2a
wcag2aa
wcag21a
wcag21aa

The test fails when serious or critical violations are found.


The workflow file belongs at the repository root:

.github/workflows/accessibility-ci.yml

The workflow commands run from web/ using:

defaults:
run:
working-directory: web

The workflow:

  1. Checks out the repository.
  2. Sets up Node.js 22.
  3. Installs web dependencies with npm ci.
  4. Installs Playwright Chromium and Linux browser dependencies.
  5. Builds NutsNews.
  6. Runs the axe accessibility tests.
  7. Uploads the Playwright HTML report and failure traces as a GitHub Actions artifact.

The CI workflow uses the same public Supabase values as Lighthouse CI:

NEXT_PUBLIC_SUPABASE_URL
NEXT_PUBLIC_SUPABASE_ANON_KEY

Add or confirm them here:

GitHub repo → Settings → Secrets and variables → Actions → Repository secrets

Use the values from:

Terminal window
cd /Users/ramideltoro/WebstormProjects/nutsnews3
grep -E '^NEXT_PUBLIC_SUPABASE_(URL|ANON_KEY)=' web/.env.local | sed 's/NEXT_PUBLIC_SUPABASE_ANON_KEY=.*/NEXT_PUBLIC_SUPABASE_ANON_KEY=<hidden>/'

From the web app folder:

Terminal window
cd /Users/ramideltoro/WebstormProjects/nutsnews3/web
npm run build
npx playwright install chromium
npm run test:accessibility

Expected result:

4 passed

If there is a failure, open the local report:

Terminal window
npx playwright show-report

From the repository root:

Terminal window
cd /Users/ramideltoro/WebstormProjects/nutsnews3
git status
git add \
web/package.json \
web/package-lock.json \
web/playwright.config.ts \
web/tests/accessibility.spec.ts \
web/.gitignore \
.github/workflows/accessibility-ci.yml \
README.md \
docs/README.md \
docs/OBSERVABILITY.md \
docs/AXE_PLAYWRIGHT_ACCESSIBILITY_CI.md \
docs/updates/README_AXE_PLAYWRIGHT_ACCESSIBILITY_CI_UPDATE.md
git commit -m "Add axe Playwright accessibility CI"
git push

After pushing, open:

GitHub → Actions → Accessibility CI

A good run shows:

Install dependencies ✅
Install Playwright Chromium ✅
Build NutsNews ✅
Run axe accessibility checks ✅
Upload Playwright accessibility report ✅

If it fails, open the failed step. The test output lists:

  • axe rule ID
  • impact level
  • help text
  • affected DOM selectors
  • axe help URL

The uploaded accessibility-playwright-report artifact can be downloaded from the workflow run.


Automated axe checks are useful, but they do not catch every accessibility issue. Before App Store review and public launch, still run the WAVE browser extension manually on:

https://www.nutsnews.com/
https://www.nutsnews.com/about
https://www.nutsnews.com/privacy
https://www.nutsnews.com/contact

Use WAVE for visual review of:

  • Contrast warnings
  • Heading structure
  • Visible labels
  • Button readability
  • Link text quality
  • Layout and reading order

For NutsNews, the best setup is:

Lighthouse CI = broad web quality score
axe Playwright CI = automated accessibility regression checks
WAVE extension = final manual accessibility polish