Complete MIM4U A+ evidence: potrace SVG, SiteHeader, and full-site a11y.
Consolidate header via SiteHeader, regenerate potrace nav lockups, add screenshot matrix and Lighthouse site audit scripts, fix PWA dismiss aria-label, and bump institutional grade to A+ (99/100). Co-authored-by: Cursor <[email protected]>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Full-site Lighthouse accessibility audit (live URL).
|
||||
* Usage: node scripts/a11y/audit-site-lighthouse.mjs [--url=https://mim4u.org]
|
||||
*/
|
||||
import { spawnSync } from 'node:child_process'
|
||||
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
||||
import { dirname, join } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||
const repoRoot = join(__dirname, '../..')
|
||||
const outDir = join(repoRoot, 'reports/status')
|
||||
|
||||
const urlArg = process.argv.find((a) => a.startsWith('--url='))
|
||||
const url = urlArg ? urlArg.split('=')[1] : 'https://mim4u.org'
|
||||
const lhOut = join(outDir, 'lighthouse-site-a11y-latest.json')
|
||||
|
||||
mkdirSync(outDir, { recursive: true })
|
||||
const chromePath = process.env.CHROME_PATH || '/usr/bin/google-chrome'
|
||||
|
||||
const result = spawnSync(
|
||||
'npx',
|
||||
[
|
||||
'--yes',
|
||||
'lighthouse',
|
||||
url,
|
||||
'--only-categories=accessibility,performance,best-practices,seo',
|
||||
'--skip-audits=full-page-screenshot,screenshot-thumbnails',
|
||||
'--output=json',
|
||||
`--output-path=${lhOut}`,
|
||||
'--chrome-flags=--headless --no-sandbox',
|
||||
],
|
||||
{
|
||||
cwd: repoRoot,
|
||||
env: { ...process.env, CHROME_PATH: chromePath },
|
||||
encoding: 'utf8',
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
}
|
||||
)
|
||||
|
||||
if (result.status !== 0 && !readFileSync(lhOut, 'utf8').includes('"categories"')) {
|
||||
console.error((result.stderr || result.stdout || 'Lighthouse failed').trim())
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const raw = JSON.parse(readFileSync(lhOut, 'utf8'))
|
||||
const scores = Object.fromEntries(
|
||||
Object.entries(raw.categories).map(([k, v]) => [k, Math.round(v.score * 100)])
|
||||
)
|
||||
const failing = raw.categories.accessibility.auditRefs
|
||||
.filter((ref) => {
|
||||
const audit = raw.audits[ref.id]
|
||||
return audit && audit.score !== null && audit.score < 1
|
||||
})
|
||||
.map((ref) => ({ id: ref.id, title: raw.audits[ref.id].title }))
|
||||
|
||||
const report = {
|
||||
schemaVersion: '1.0.0',
|
||||
assessmentDate: new Date().toISOString().slice(0, 10),
|
||||
url,
|
||||
scores,
|
||||
accessibilityFailingAudits: failing,
|
||||
reportPath: lhOut,
|
||||
}
|
||||
|
||||
const outPath = join(outDir, 'mim4u-site-lighthouse-latest.json')
|
||||
writeFileSync(outPath, `${JSON.stringify(report, null, 2)}\n`)
|
||||
|
||||
console.log('Lighthouse scores:', scores)
|
||||
if (failing.length) {
|
||||
failing.forEach((f) => console.log(` a11y FAIL: ${f.id} — ${f.title}`))
|
||||
}
|
||||
console.log(`Report: ${outPath}`)
|
||||
process.exit(scores.accessibility >= 95 ? 0 : 1)
|
||||
Reference in New Issue
Block a user