3746bc55a9
- 为Logo链接添加aria-label - 增强可访问性测试的详细输出 - 扩大测试范围至前20个链接 任务 2/4
97 lines
3.0 KiB
TypeScript
97 lines
3.0 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
|
|
test.describe('无障碍测试 @feature @frontend', () => {
|
|
test('首页无障碍检查', async ({ page }) => {
|
|
await page.goto('/');
|
|
|
|
const violations = await page.evaluate(() => {
|
|
return (window as unknown as { axe?: { run: () => unknown[] } }).axe?.run() || [];
|
|
});
|
|
|
|
expect(violations.length).toBe(0);
|
|
});
|
|
|
|
test('导航键盘可访问', async ({ page }) => {
|
|
await page.goto('/');
|
|
|
|
await page.keyboard.press('Tab');
|
|
const focusedElement = page.locator(':focus');
|
|
await expect(focusedElement).toBeVisible();
|
|
});
|
|
|
|
test('图片有alt属性', async ({ page }) => {
|
|
await page.goto('/');
|
|
|
|
const images = page.locator('img');
|
|
const count = await images.count();
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
const img = images.nth(i);
|
|
const alt = await img.getAttribute('alt');
|
|
expect(alt).not.toBeNull();
|
|
}
|
|
});
|
|
|
|
test('表单标签关联正确', async ({ page }) => {
|
|
await page.goto('/contact');
|
|
|
|
const inputs = page.locator('input[type="text"], input[type="email"], textarea');
|
|
const count = await inputs.count();
|
|
|
|
for (let i = 0; i < count; i++) {
|
|
const input = inputs.nth(i);
|
|
const id = await input.getAttribute('id');
|
|
|
|
if (id) {
|
|
const label = page.locator(`label[for="${id}"]`);
|
|
const hasLabel = await label.count() > 0;
|
|
const hasAriaLabel = await input.getAttribute('aria-label');
|
|
|
|
expect(hasLabel || hasAriaLabel).toBeTruthy();
|
|
}
|
|
}
|
|
});
|
|
|
|
test('标题层级正确', async ({ page }) => {
|
|
await page.goto('/');
|
|
|
|
const h1 = page.locator('h1');
|
|
const h1Count = await h1.count();
|
|
expect(h1Count).toBeGreaterThanOrEqual(1);
|
|
expect(h1Count).toBeLessThanOrEqual(1);
|
|
});
|
|
|
|
test('链接有明确的文本', async ({ page }) => {
|
|
await page.goto('/');
|
|
await page.waitForLoadState('domcontentloaded');
|
|
|
|
const links = page.locator('a');
|
|
const count = await links.count();
|
|
const problematicLinks: string[] = [];
|
|
|
|
for (let i = 0; i < Math.min(count, 20); i++) {
|
|
const link = links.nth(i);
|
|
const text = await link.textContent();
|
|
const ariaLabel = await link.getAttribute('aria-label');
|
|
const title = await link.getAttribute('title');
|
|
const href = await link.getAttribute('href');
|
|
|
|
const hasAccessibleName = text?.trim() || ariaLabel || title;
|
|
const isSpecialLink = !href || href === '#' || href.startsWith('javascript:') || href.startsWith('mailto:');
|
|
|
|
if (!hasAccessibleName && !isSpecialLink) {
|
|
const linkHtml = await link.innerHTML();
|
|
problematicLinks.push(`链接 ${i + 1}: href="${href}", innerHTML="${linkHtml}"`);
|
|
console.log(`链接 ${i + 1} 缺少可访问名称: href="${href}", innerHTML="${linkHtml}"`);
|
|
}
|
|
}
|
|
|
|
if (problematicLinks.length > 0) {
|
|
console.log('\n缺少可访问名称的链接列表:');
|
|
problematicLinks.forEach(link => console.log(link));
|
|
}
|
|
|
|
expect(problematicLinks.length).toBe(0);
|
|
});
|
|
});
|