a11yanalyze
Version:
A command-line tool for developers and QA engineers to test web pages and websites for WCAG 2.2 AA accessibility compliance
152 lines • 7.17 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HtmlBatchRunner = void 0;
const fs_1 = require("fs");
const path_1 = require("path");
const js_yaml_1 = __importDefault(require("js-yaml"));
const page_scanner_1 = require("../scanner/page-scanner");
const vpat_reporter_1 = require("../output/vpat-reporter");
class HtmlBatchRunner {
async run(options) {
let targets = [];
if (options.inputDir) {
targets = this.findHtmlFiles(options.inputDir).map(f => ({ name: (0, path_1.basename)(f, '.html'), path: f, isUrl: false }));
}
if (options.inputList) {
const urls = (0, fs_1.readFileSync)(options.inputList, 'utf8').split(/\r?\n/).filter(Boolean);
targets = targets.concat(urls.map(url => ({ name: this.sanitizeName(url), path: url, isUrl: true })));
}
if (options.inputConfig) {
const config = this.loadConfigFile(options.inputConfig);
if (Array.isArray(config)) {
targets = targets.concat(config.map((entry) => ({
name: entry.name || this.sanitizeName(entry.url || entry.file),
path: entry.url || entry.file,
isUrl: !!entry.url,
meta: entry
})));
}
}
if (!targets.length)
throw new Error('No HTML files, URLs, or config entries found.');
if (!(0, fs_1.existsSync)(options.outputDir))
(0, fs_1.mkdirSync)(options.outputDir, { recursive: true });
let customTemplate;
if (options.template) {
customTemplate = (0, fs_1.readFileSync)(options.template, 'utf8');
}
const summary = [];
const errors = [];
for (const target of targets) {
try {
const pageScanner = new page_scanner_1.PageScanner({
headless: true,
viewport: { width: 1280, height: 720 },
timeout: options.timeout || 30000,
}, {
wcagLevel: options.wcagLevel || 'AA',
includeAAA: false,
includeARIA: true,
customRules: [],
disabledRules: [],
});
await pageScanner.initialize();
const scanOptions = {
wcagLevel: options.wcagLevel || 'AA',
includeAAA: false,
includeARIA: true,
customRules: [],
disabledRules: [],
};
// Run the scan and get results
const scanResult = await pageScanner.scan(target.path, scanOptions);
// Use keyboardNavigation and screenReaderSimulation from scanResult
// (No need to call simulateKeyboardNavigation or simulateScreenReader here)
const vpatReport = vpat_reporter_1.VpatReporter.generateJsonReport(target.name, scanResult);
const baseName = this.sanitizeName(target.name);
if (options.format === 'json' || options.format === 'both') {
const jsonPath = (0, path_1.join)(options.outputDir, `${baseName}.vpat.json`);
if (customTemplate && options.template?.endsWith('.json')) {
(0, fs_1.writeFileSync)(jsonPath, vpat_reporter_1.VpatReporter.generateCustomReport(vpatReport, customTemplate), 'utf8');
}
else {
(0, fs_1.writeFileSync)(jsonPath, JSON.stringify(vpatReport, null, 2), 'utf8');
}
}
if (options.format === 'markdown' || options.format === 'both') {
const mdPath = (0, path_1.join)(options.outputDir, `${baseName}.vpat.md`);
if (customTemplate && options.template?.endsWith('.md')) {
(0, fs_1.writeFileSync)(mdPath, vpat_reporter_1.VpatReporter.generateCustomReport(vpatReport, customTemplate), 'utf8');
}
else {
const md = vpat_reporter_1.VpatReporter.generateMarkdownReport(vpatReport);
(0, fs_1.writeFileSync)(mdPath, md, 'utf8');
}
}
summary.push({
name: target.name,
path: target.path,
meta: target.meta,
status: 'success',
supports: vpatReport.summary.supports,
partiallySupports: vpatReport.summary.partiallySupports,
doesNotSupport: vpatReport.summary.doesNotSupport,
notApplicable: vpatReport.summary.notApplicable,
notEvaluated: vpatReport.summary.notEvaluated,
});
}
catch (error) {
errors.push({
name: target.name,
path: target.path,
meta: target.meta,
error: error instanceof Error ? error.message : String(error),
});
summary.push({
name: target.name,
path: target.path,
meta: target.meta,
status: 'error',
error: error instanceof Error ? error.message : String(error),
});
console.warn(`Failed to scan ${target.name}: ${error instanceof Error ? error.message : String(error)}`);
}
}
(0, fs_1.writeFileSync)((0, path_1.join)(options.outputDir, 'vpat-index.json'), JSON.stringify(summary, null, 2), 'utf8');
if (errors.length > 0) {
(0, fs_1.writeFileSync)((0, path_1.join)(options.outputDir, 'vpat-errors.json'), JSON.stringify(errors, null, 2), 'utf8');
}
}
loadConfigFile(path) {
const content = (0, fs_1.readFileSync)(path, 'utf8');
if (path.endsWith('.json')) {
return JSON.parse(content);
}
else if (path.endsWith('.yaml') || path.endsWith('.yml')) {
return js_yaml_1.default.load(content);
}
throw new Error('Unsupported config file format: ' + path);
}
findHtmlFiles(dir) {
let results = [];
for (const entry of (0, fs_1.readdirSync)(dir)) {
const fullPath = (0, path_1.join)(dir, entry);
const stat = (0, fs_1.statSync)(fullPath);
if (stat.isDirectory()) {
results = results.concat(this.findHtmlFiles(fullPath));
}
else if (stat.isFile() && (0, path_1.extname)(fullPath).toLowerCase() === '.html') {
results.push(fullPath);
}
}
return results;
}
sanitizeName(name) {
return name.replace(/[^a-zA-Z0-9_-]/g, '_');
}
}
exports.HtmlBatchRunner = HtmlBatchRunner;
//# sourceMappingURL=html-batch.js.map