/**
* Axe scanner configuration and execution utilities
*/
import { Page } from 'playwright';
import AxeBuilder from '@axe-core/playwright';
import { COMPREHENSIVE_WCAG_TAGS } from '../constants/wcag-tags.js';
import type { Violation, ViolationNode } from '../types/scan-result.js';
/**
* Create an AxeBuilder configured with comprehensive WCAG tags
*/
export function createAxeBuilder(page: Page, selector?: string): AxeBuilder {
const axeBuilder = new AxeBuilder({ page });
// Apply comprehensive WCAG tags
axeBuilder.withTags([...COMPREHENSIVE_WCAG_TAGS]);
// Include specific selector if provided
if (selector) {
axeBuilder.include(selector);
}
return axeBuilder;
}
/**
* Run accessibility scan and format violations
*/
export async function runAccessibilityScan(
page: Page,
selector?: string
): Promise<{ violations: Violation[]; passes: number; incomplete: number }> {
const axeBuilder = createAxeBuilder(page, selector);
const results = await axeBuilder.analyze();
const formattedViolations: Violation[] = results.violations.map(violation => ({
id: violation.id,
impact: violation.impact || 'unknown',
description: violation.description,
help: violation.help,
helpUrl: violation.helpUrl,
tags: violation.tags,
nodes: violation.nodes.map(node => ({
html: node.html,
target: node.target,
failureSummary: node.failureSummary
}))
}));
return {
violations: formattedViolations,
passes: results.passes.length,
incomplete: results.incomplete.length
};
}