72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import { Page } from '@playwright/test';
|
|
import AxeBuilder from '@axe-core/playwright';
|
|
import { AccessibilityResult, Violation } from '../../types';
|
|
|
|
export class AccessibilityTester {
|
|
constructor(private page: Page) {}
|
|
|
|
async runAxeScan(pageName: string, url: string): Promise<AccessibilityResult> {
|
|
const accessibilityScanResults = await new AxeBuilder({ page: this.page })
|
|
.withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa'])
|
|
.analyze();
|
|
|
|
const violations: Violation[] = accessibilityScanResults.violations.map(v => ({
|
|
id: v.id,
|
|
impact: v.impact || 'unknown',
|
|
description: v.description,
|
|
help: v.help,
|
|
helpUrl: v.helpUrl,
|
|
nodes: v.nodes.length
|
|
}));
|
|
|
|
const passes = accessibilityScanResults.passes.length;
|
|
const incomplete = accessibilityScanResults.incomplete.length;
|
|
const score = this.calculateScore(violations, passes, incomplete);
|
|
|
|
return {
|
|
score,
|
|
violations,
|
|
passes,
|
|
incomplete,
|
|
page: pageName,
|
|
url
|
|
};
|
|
}
|
|
|
|
private calculateScore(violations: Violation[], passes: number, incomplete: number): number {
|
|
const total = violations.length + passes + incomplete;
|
|
if (total === 0) return 100;
|
|
return parseFloat(((passes / total) * 100).toFixed(1));
|
|
}
|
|
|
|
async checkColorContrast(): Promise<boolean> {
|
|
const results = await new AxeBuilder({ page: this.page })
|
|
.withTags(['wcag2aa'])
|
|
.include('#content')
|
|
.analyze();
|
|
|
|
return results.violations.filter(v => v.id === 'color-contrast').length === 0;
|
|
}
|
|
|
|
async checkAltText(): Promise<{ total: number; withAlt: number; withoutAlt: number }> {
|
|
const images = await this.page.locator('img').all();
|
|
let withAlt = 0;
|
|
let withoutAlt = 0;
|
|
|
|
for (const image of images) {
|
|
const alt = await image.getAttribute('alt');
|
|
if (alt && alt.trim() !== '') {
|
|
withAlt++;
|
|
} else {
|
|
withoutAlt++;
|
|
}
|
|
}
|
|
|
|
return {
|
|
total: images.length,
|
|
withAlt,
|
|
withoutAlt
|
|
};
|
|
}
|
|
}
|