feat: add accessibility testing utility
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
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
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user