diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e686ad6999..46a5ec927a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -91,7 +91,7 @@ jobs: - name: 🏗️ Build project run: pnpm build - - name: ♿ Accessibility audit (Lighthouse) - run: pnpx @lhci/cli autorun + - name: ♿ Accessibility audit (Lighthouse - dark & light mode) + run: ./scripts/lighthouse-a11y.sh env: LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }} diff --git a/.lighthouserc.cjs b/.lighthouserc.cjs new file mode 100644 index 0000000000..5c4ba55894 --- /dev/null +++ b/.lighthouserc.cjs @@ -0,0 +1,51 @@ +const fs = require('fs') + +// Auto-detect Chrome executable path +function findChrome() { + const paths = [ + // Linux + '/usr/bin/google-chrome-stable', + '/usr/bin/google-chrome', + '/usr/bin/chromium-browser', + // macOS + '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome', + // Windows + 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe', + 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe', + ] + + for (const p of paths) { + if (fs.existsSync(p)) return p + } + + return undefined +} + +module.exports = { + ci: { + collect: { + startServerCommand: 'pnpm preview', + startServerReadyPattern: 'Listening', + url: [ + 'http://localhost:3000/', + 'http://localhost:3000/search?q=nuxt', + 'http://localhost:3000/nuxt', + ], + numberOfRuns: 1, + chromePath: findChrome(), + puppeteerScript: './lighthouse-setup.cjs', + settings: { + onlyCategories: ['accessibility'], + skipAudits: ['valid-source-maps'], + }, + }, + assert: { + assertions: { + 'categories:accessibility': ['error', { minScore: 1 }], + }, + }, + upload: { + target: 'temporary-public-storage', + }, + }, +} diff --git a/.lighthouserc.json b/.lighthouserc.json deleted file mode 100644 index 9ad5381fe5..0000000000 --- a/.lighthouserc.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "ci": { - "collect": { - "startServerCommand": "pnpm preview", - "startServerReadyPattern": "Listening", - "url": [ - "http://localhost:3000/", - "http://localhost:3000/search?q=nuxt", - "http://localhost:3000/nuxt" - ], - "numberOfRuns": 1, - "settings": { - "onlyCategories": ["accessibility"], - "skipAudits": ["valid-source-maps"] - } - }, - "assert": { - "assertions": { - "categories:accessibility": ["warn", { "minScore": 1 }] - } - }, - "upload": { - "target": "temporary-public-storage" - } - } -} diff --git a/lighthouse-setup.cjs b/lighthouse-setup.cjs new file mode 100644 index 0000000000..5576d96606 --- /dev/null +++ b/lighthouse-setup.cjs @@ -0,0 +1,24 @@ +/** + * Lighthouse CI puppeteer setup script. + * Sets the color mode (light/dark) before running accessibility audits. + * + * The color mode is determined by the LIGHTHOUSE_COLOR_MODE environment variable. + * If not set, defaults to 'dark'. + */ + +/** @param {import('puppeteer').Browser} browser */ +module.exports = async function setup(browser, { url }) { + const colorMode = process.env.LIGHTHOUSE_COLOR_MODE || 'dark' + const page = await browser.newPage() + + // Set localStorage before navigating so @nuxtjs/color-mode picks it up + await page.evaluateOnNewDocument(mode => { + localStorage.setItem('npmx-color-mode', mode) + }, colorMode) + + // Navigate and wait for DOM only - Lighthouse will do its own full load + await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 }) + + // Close the page - Lighthouse will open its own with localStorage already set + await page.close() +} diff --git a/scripts/lighthouse-a11y.sh b/scripts/lighthouse-a11y.sh new file mode 100755 index 0000000000..2ab4dd1039 --- /dev/null +++ b/scripts/lighthouse-a11y.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Run Lighthouse accessibility tests in both light and dark mode +# +# This script runs lhci autorun twice, once for each color mode. +# The LIGHTHOUSE_COLOR_MODE env var is read by lighthouse-setup.cjs +# to set the appropriate theme before each audit. + +set -e + +echo "🌙 Running Lighthouse accessibility audit (dark mode)..." +LIGHTHOUSE_COLOR_MODE=dark pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/dark" + +echo "" +echo "☀️ Running Lighthouse accessibility audit (light mode)..." +LIGHTHOUSE_COLOR_MODE=light pnpx @lhci/cli autorun --upload.githubStatusContextSuffix="/light" + +echo "" +echo "✅ Accessibility audits completed for both color modes"