Skip to content

Commit a31db56

Browse files
authored
ci: run lighthouse a11y tests in both light + dark mode (#194)
1 parent f200b39 commit a31db56

5 files changed

Lines changed: 95 additions & 28 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ jobs:
9191
- name: 🏗️ Build project
9292
run: pnpm build
9393

94-
- name: ♿ Accessibility audit (Lighthouse)
95-
run: pnpx @lhci/cli autorun
94+
- name: ♿ Accessibility audit (Lighthouse - dark & light mode)
95+
run: ./scripts/lighthouse-a11y.sh
9696
env:
9797
LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }}

.lighthouserc.cjs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const fs = require('fs')
2+
3+
// Auto-detect Chrome executable path
4+
function findChrome() {
5+
const paths = [
6+
// Linux
7+
'/usr/bin/google-chrome-stable',
8+
'/usr/bin/google-chrome',
9+
'/usr/bin/chromium-browser',
10+
// macOS
11+
'/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
12+
// Windows
13+
'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
14+
'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
15+
]
16+
17+
for (const p of paths) {
18+
if (fs.existsSync(p)) return p
19+
}
20+
21+
return undefined
22+
}
23+
24+
module.exports = {
25+
ci: {
26+
collect: {
27+
startServerCommand: 'pnpm preview',
28+
startServerReadyPattern: 'Listening',
29+
url: [
30+
'http://localhost:3000/',
31+
'http://localhost:3000/search?q=nuxt',
32+
'http://localhost:3000/nuxt',
33+
],
34+
numberOfRuns: 1,
35+
chromePath: findChrome(),
36+
puppeteerScript: './lighthouse-setup.cjs',
37+
settings: {
38+
onlyCategories: ['accessibility'],
39+
skipAudits: ['valid-source-maps'],
40+
},
41+
},
42+
assert: {
43+
assertions: {
44+
'categories:accessibility': ['error', { minScore: 1 }],
45+
},
46+
},
47+
upload: {
48+
target: 'temporary-public-storage',
49+
},
50+
},
51+
}

.lighthouserc.json

Lines changed: 0 additions & 26 deletions
This file was deleted.

lighthouse-setup.cjs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* Lighthouse CI puppeteer setup script.
3+
* Sets the color mode (light/dark) before running accessibility audits.
4+
*
5+
* The color mode is determined by the LIGHTHOUSE_COLOR_MODE environment variable.
6+
* If not set, defaults to 'dark'.
7+
*/
8+
9+
/** @param {import('puppeteer').Browser} browser */
10+
module.exports = async function setup(browser, { url }) {
11+
const colorMode = process.env.LIGHTHOUSE_COLOR_MODE || 'dark'
12+
const page = await browser.newPage()
13+
14+
// Set localStorage before navigating so @nuxtjs/color-mode picks it up
15+
await page.evaluateOnNewDocument(mode => {
16+
localStorage.setItem('npmx-color-mode', mode)
17+
}, colorMode)
18+
19+
// Navigate and wait for DOM only - Lighthouse will do its own full load
20+
await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 })
21+
22+
// Close the page - Lighthouse will open its own with localStorage already set
23+
await page.close()
24+
}

scripts/lighthouse-a11y.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/bash
2+
# Run Lighthouse accessibility tests in both light and dark mode
3+
#
4+
# This script runs lhci autorun twice, once for each color mode.
5+
# The LIGHTHOUSE_COLOR_MODE env var is read by lighthouse-setup.cjs
6+
# to set the appropriate theme before each audit.
7+
8+
set -e
9+
10+
echo "🌙 Running Lighthouse accessibility audit (dark mode)..."
11+
LIGHTHOUSE_COLOR_MODE=dark pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/dark"
12+
13+
echo ""
14+
echo "☀️ Running Lighthouse accessibility audit (light mode)..."
15+
LIGHTHOUSE_COLOR_MODE=light pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/light"
16+
17+
echo ""
18+
echo "✅ Accessibility audits completed for both color modes"

0 commit comments

Comments
 (0)