Files
novalon-website/scripts/utils/axe-runner.js
T

74 lines
2.1 KiB
JavaScript

const { chromium } = require('playwright');
const AxeBuilder = require('@axe-core/playwright').default;
const fs = require('fs');
const path = require('path');
async function runAxeTest(url, pageName) {
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
const results = [];
try {
await page.goto(url, { waitUntil: 'networkidle' });
const accessibilityScanResults = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
.analyze();
const violations = accessibilityScanResults.violations.map(v => ({
id: v.id,
impact: v.impact,
description: v.description,
help: v.help,
helpUrl: v.helpUrl,
nodes: v.nodes.length
}));
const passes = accessibilityScanResults.passes.length;
const incomplete = accessibilityScanResults.incomplete.length;
results.push({
page: pageName,
url,
violations,
passes,
incomplete,
score: calculateScore(violations, passes, incomplete)
});
console.log(` ✅ 扫描完成: ${violations.length} 个违规, ${passes} 个通过, ${incomplete} 个未完成`);
await context.close();
await browser.close();
return results[0];
} catch (error) {
await context.close();
await browser.close();
throw new Error(`可访问性测试失败: ${error.message}`);
}
}
function calculateScore(violations, passes, incomplete) {
const total = violations.length + passes + incomplete;
if (total === 0) return 100;
return ((passes / total) * 100).toFixed(1);
}
function generateReport(results, outputPath) {
const report = {
timestamp: new Date().toISOString(),
summary: {
totalPages: results.length,
totalViolations: results.reduce((sum, r) => sum + r.violations.length, 0),
averageScore: (results.reduce((sum, r) => sum + parseFloat(r.score), 0) / results.length).toFixed(1)
},
pages: results
};
fs.writeFileSync(outputPath, JSON.stringify(report, null, 2));
return outputPath;
}
module.exports = { runAxeTest, generateReport };