关于 accessibility-testing
accessibility-testing 是面向开发与 QA 团队的无障碍测试技能,指导将自动扫描、键盘操作和屏幕阅读器测试纳入持续验证。它覆盖 WCAG 检查、ARIA 状态及常见交互模式。
主要功能
- 01使用 axe-core 与 Playwright 自动扫描
- 02检查键盘导航与焦点行为
- 03验证屏幕阅读器可访问内容
- 04测试 ARIA 状态与交互模式
- 05使用 ARIA 快照检查语义结构
适用场景
- 01在 CI 中发现无障碍回归
- 02验证表单错误与焦点提示
- 03检查菜单、对话框等交互状态
- 04审核页面是否符合 WCAG 目标
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ petrkindlmann/ qa-skills --skill accessibility-testing安装后在 Claude Code 中输入/accessibility-testing确认已加载。
附带文件references/patterns.mdreferences/recipes.md
详细介绍
调研问题
先检查 .agents/qa-project-context.md——如果该文件存在,就以它为基础,并跳过已回答的问题。
要求与合规性(确定目标级别和审计义务)
- 要求达到哪个 WCAG 一致性级别——A、AA 还是 AAA?AA 是实际应用中常见的法律默认标准。
- 适用哪些法律——ADA、EAA/EN 301 549、Section 508、AODA?每项法律都对应一个 WCAG 级别。
- 是否需要维护 VPAT 或无障碍声明?企业或政府客户是否有合同中的无障碍条款?
当前状态(判断你是在执行审计,还是在防止回归)
- 之前是否进行过审计?发现了哪些问题?哪些已列入待办事项?
- 设计系统是否包含无障碍指南和可访问组件?
测试基础设施(确定哪些测试可以自动化,哪些必须手动完成)
- CI 中是否已包含自动化无障碍测试?
- 团队使用哪些屏幕阅读器进行测试——VoiceOver、NVDA、JAWS、TalkBack?
核心原则
-
自动化测试只能发现 30-40% 的问题,无法发现更多。 axe-core 可以发现缺少替代文本、对比度过低、缺少标签和无效 ARIA 等问题。它无法判断替代文本是否有意义、Tab 顺序是否合理,或自定义组件是否可操作。通过 axe 检查是必要条件,但不是充分条件。尤为重要的是,axe 对若干 WCAG 2.2 成功准则没有自动化规则(2.4.11 焦点未被遮挡、2.5.7 拖动动作,以及仅部分覆盖的 2.5.8 目标尺寸)——axe 检查全绿并不代表符合 2.2 AA。
-
优先使用语义化 HTML,ARIA 作为最后手段。 原生元素(
<button>、<nav>、<input>、<dialog>)自带语义、键盘行为和屏幕阅读器支持。<div role="button">还需要tabindex、Enter/空格键处理程序、焦点样式和 ARIA 状态——而<button>免费提供了这些功能。只有在没有合适的原生元素时才使用 ARIA。 -
按影响顺序测试:键盘、屏幕阅读器、自动化。 键盘问题会直接阻碍用户使用功能(影响最大)。屏幕阅读器问题会导致播报错误。自动化检查负责发现剩余的机械性问题。应从影响最严重的地方开始,而不是从最容易使用工具的地方开始。
-
无障碍性是一项质量属性,而非功能特性。 应像测试性能或安全性一样持续测试无障碍性——涵盖每个新组件和每个 PR。对已完成的产品进行无障碍改造,成本会高出 10-100 倍,因为无法访问的设计模式会固化在组件库中。
-
使用真实的辅助技术进行测试。 浏览器 DevTools 和 axe 扩展是开发辅助工具,不能替代 VoiceOver(macOS/iOS)、NVDA(Windows)和 TalkBack(Android)。这些工具的行为各不相同。复杂的自定义组件应安排人工辅助技术测试。
使用 axe-core + Playwright 自动扫描
通过 npm view @axe-core/playwright version 获取版本,并将 @axe-core/playwright 固定为精确版本(截至 2026-10-21 为 4.14.0;其次版本号与 axe-core 的次版本号同步,因此每次升级都会引入一组新规则,必须经过审核,不要自动更新)。将其封装为可复用的 checkAccessibility(page, testInfo, options) 辅助函数,并筛选 WCAG 标签 ['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa', 'wcag22aa']。扫描前,必须验证预期 URL,并执行由应用负责的就绪断言:空白页、错误页和重定向后的页面都可能通过 axe 扫描。附加完整的结果 JSON,拒绝未评估任何规则的扫描,并断言 violations.toHaveLength(0)。导出的 scanAccessibility 辅助函数会返回违规摘要,用于已知问题基线;checkAccessibility 则要求违规数量为零。针对每个关键页面和各种交互状态(模态框打开、菜单展开、已登录账户)循环扫描,不要只测试默认加载状态。对于无法修复的第三方页面,不要跳过扫描,而是断言已知规则 ID 的精确集合,以便新增违规或已修复的问题都能触发测试变更。
只有在有文档说明的理由(跟踪问题或内联注释)时才抑制规则;对于不归你管理的第三方组件,应使用 exclude 排除,而不是全局禁用规则。
有关安装命令、RGAA 标签注意事项、完整辅助函数、页面循环和交互状态测试、规则抑制及 CI 集成,请参阅 references/recipes.md。
手动测试清单
自动扫描只是最低要求。以下检查需要人工完成(或编写由键盘驱动的 Playwright 测试规范——键盘测试规范请参阅 references/recipes.md)。
键盘导航审查
- Tab 顺序符合逻辑 — 对于 LTR 布局,顺序为从左到右、从上到下。焦点不会意外跳转。
- 所有交互元素均可通过 Tab / Shift+Tab 访问。
- 每个获得焦点的元素都显示焦点指示器。没有用替代样式的
outline: none。 - 跳过链接可正常工作 — 按下第一个 Tab 时显示“跳至主要内容”;按 Enter 后焦点移至
<main>。 - Enter 可激活按钮/链接;Space 可激活按钮并切换复选框。
- Escape 可关闭模态框、下拉菜单和工具提示;焦点返回触发元素。
- 方向键可在选项卡、菜单、单选按钮组和树视图中导航。
- 不存在键盘陷阱(模态对话框会有意锁定焦点,直到将其关闭——这是允许的)。
- 自定义组件无需鼠标即可操作(滑块、日期选择器、拖放)。
屏幕阅读器测试
| 屏幕阅读器 | 操作系统 | 浏览器 | 免费? |
|---|---|---|---|
| VoiceOver | macOS/iOS | Safari | 是(Cmd+F5) |
| NVDA | Windows | Firefox/Chrome | 是 |
| JAWS | Windows | Chrome/Edge | 否 |
| TalkBack | Android | Chrome | 是 |
- 导航时会播报页面标题。
- 标题构成可导航的大纲(h1 → h2 → h3,不跳级)。
- 图片具有描述性替代文本(装饰性图片使用
alt="")。 - 聚焦表单输入框时会播报其标签。
- 会播报必填字段;错误与对应输入框相关联。
- 动态内容(提示消息、加载状态)会通过实时区域播报。
- 按钮/链接会播报其用途(不要使用“点击此处”)。
颜色对比度和视觉呈现
- 正常文本:最低 4.5:1(WCAG AA)。大号文本(18pt 及以上 / 粗体 14pt 及以上):3:1。
- UI 组件和图形对象与相邻颜色的对比度:3:1。
- 不要只通过颜色传达信息——应添加图标、图案或文本。
表单和错误提示的无障碍性
- 每个输入框都有可见的
<label>,并通过for/id关联(占位符不是标签)。 - 通过视觉和程序化方式标示必填字段(
required/aria-required)。 - 错误使用
aria-describedby与输入框关联,并通过role="alert"播报。 - 提交失败时,焦点移至第一个错误。
- 使用
<fieldset>和<legend>对相关字段分组。
WCAG 2.2 快速参考
A 级(必须修复)
| 标准 | 含义 | 常见问题 |
|---|---|---|
| 1.1.1 非文本内容 | 图片具有替代文本 | <img> 缺少 alt |
| 1.3.1 信息和关系 | 通过 HTML 语义表达结构 | 将 <div> 设置样式伪装成标题 |
| 2.1.1 键盘 | 所有功能均可通过键盘使用 | 自定义控件只能响应鼠标操作 |
| 2.4.1 跳过区块 | 提供跳过导航链接 | 没有跳过链接 |
| 3.1.1 页面语言 | 设置 <html lang="en"> | 缺少 lang |
| 3.3.1 错误识别 | 通过文本描述错误 | 仅通过红色边框显示错误 |
| 4.1.2 名称、角色、值 | 自定义控件公开名称和角色 | <div onclick> 没有角色 |
AA 级(最常见的法律要求)
| 标准 | 含义 | 常见问题 |
|---|---|---|
| 1.4.3 对比度(最低) | 普通文本为 4.5:1,大号文本为 3:1 | 白底浅灰色文字 |
| 1.4.4 调整文本大小 | 放大至 200% 时内容不丢失 | 固定高度容器裁切文本 |
| 1.4.11 非文本对比度 | UI 组件为 3:1 | 输入框边框对比度过低 |
| 2.4.7 焦点可见 | 键盘焦点清晰可见 | 使用 outline: none 且没有替代样式 |
| 2.5.8 目标尺寸 | 触控目标至少为 24×24px | 图标按钮太小 |
| 3.3.2 标签或说明 | 输入框具有标签 | 仅使用占位符作为标签 |
| 3.3.8 无障碍身份验证 | 不要求执行认知功能测试 | CAPTCHA 没有替代方案 |
AAA 级(锦上添花)
| 标准 | 含义 |
|---|---|
| 1.4.6 对比度(增强) | 普通文本为 7:1,大号文本为 4.5:1 |
| 2.4.9 链接用途(仅链接) | 链接文本本身能说明目标位置 |
| 3.1.5 阅读水平 | 初中教育水平 |
无障碍模式
针对无障碍树(角色、名称、ARIA 状态)进行测试,而不是 CSS。以下模式需要 编写可运行的测试:
- 表单 — 通过
aria-describedby关联错误信息,设置aria-invalid='true',并将焦点移至第一个错误。 - 模态框/对话框 — 设置
aria-modal='true'、aria-labelledby,限制焦点范围,按下 Escape 后恢复焦点。 - 交互状态 — 已打开的下拉菜单(
role="menu"或role="listbox",aria-expanded)、 加载骨架屏(获取数据期间设置aria-busy='true')、提示消息(aria-live='polite')。这些状态对应不同的 ARIA 属性,因此需要点击触发状态变化,并断言打开状态下的 ARIA 属性 — 默认页面快照不会触发这些状态。 - 数据表格 —
columnheader角色,aria-sort反映当前排序状态。 - 地标 — 恰好有一个
main;包含banner、navigation、contentinfo。
有关上述所有模式的完整可运行测试,请参阅 references/patterns.md。
ARIA 快照
Playwright 的 toMatchAriaSnapshot() 会将无障碍树捕获为 YAML 并对其进行断言 — 这是发现视觉更改悄然破坏语义的最快方法(例如,将 <div> 重新设置样式使其看起来像按钮,或将标题降级为纯文本)。它检查结构和无障碍名称,而不是像素,因此可与 visual-testing 互为补充,而非替代。
将快照限定在稳定的容器范围内;针对异步内容的整页快照容易变得不稳定。导航和表单快照示例请参阅 references/patterns.md。
法律合规映射
| 法律/标准 | 地区 | WCAG 要求级别 | 执行方式 |
|---|---|---|---|
| ADA | 美国 | AA(法院判例) | 诉讼(私人诉权) |
| Section 508 | 美国(联邦) | WCAG 2.0 AA | 联邦采购要求 |
| EAA | 欧盟 | EN 301 549(WCAG 2.1 AA) | 自 2025 年 6 月 28 日起生效。 成员国正在积极执法;私人诉因因地而异(德国、法国、爱尔兰最为积极)。预计 EN 301 549 下一次修订时将与 WCAG 2.2 保持一致。 |
| AODA | 加拿大安大略省 | WCAG 2.0 AA | 罚款最高达每天 10 万美元 |
| EN 301 549 | 欧盟 | WCAG 2.1 AA | 公共采购要求 |
| Equality Act 2010 | 英国 | WCAG 2.1 AA(指南) | 诉讼 |
| ISO/IEC 40500:2025 | 国际 | 等同于 WCAG 2.2(2023 年 10 月) | 可用于采购/RFP 文案;可从 ISO 免费获取 |
**实际目标:**如果你的服务面向美国或欧盟用户,WCAG 2.2 AA 是新开发的目标标准——EAA 已生效,预计 EN 301 549 将更新至 2.2,而 ISO/IEC 40500:2025(2025 年 9 月发布)已将 WCAG 2.2 编入国际标准。无法立即达到 2.2 时,WCAG 2.1 AA 是旧版最低标准。
**WCAG 3 状态:**W3C 于 2026 年 3 月发布了更新版 WCAG 3 工作草案,将“成果”改名为“要求”,并不再采用二元通过/失败评定;该草案列出了约 174 项要求。目前仍是工作草案——目标是在 2027 年第四季度发布候选推荐标准,推荐标准则不会早于 2028 年发布。现阶段应按 WCAG 2.2 规划;关注 WCAG 3,但暂勿据此进行测试。
**需收集的审计证据:**各页面的自动扫描结果、注明测试人员和日期的手动检查清单、附带辅助技术版本信息的屏幕阅读器测试结果、无障碍声明、面向企业销售的 VPAT,以及已知问题的修复计划。如需查看完整的法律/VPAT/同意映射,请参阅 compliance-testing。
反模式
仅进行自动化测试
运行 axe,发现违规项为零,便宣称产品无障碍。自动化工具会漏掉 60–70% 的实际问题,并完全跳过若干 WCAG 2.2 成功标准。**改进方法:**每次运行 axe 时,都配合键盘和屏幕阅读器检查清单;发布门槛应同时涵盖两者,而不只是扫描结果。
过度使用 ARIA
给已有原生语义的元素添加 role、aria-label 和 aria-describedby,导致重复播报。**改进方法:**删除多余的 ARIA,改用原生元素——<button> 无需设置 role="button"。
忽视键盘用户
功能可通过鼠标和触控操作,却无法通过键盘操作——例如只能点击的下拉菜单、没有键盘操作方式的拖放功能、仅悬停时显示的工具提示。**改进方法:**为每种鼠标交互提供对应的键盘操作方式,并通过 keyboard.spec.ts 测试覆盖(参见 references/recipes.md)。
事后补做无障碍支持
等到产品“完成”后才处理无障碍问题,此时不可访问的模式已经固化在组件库中,修复成本会增加 10–100 倍。**改进方法:**将 axe 检查纳入完成定义,确保每个新组件在合并前都通过无障碍检查。
将无障碍支持视为可选项
因为“没人投诉”而降低无障碍工单的优先级——残障用户无法通过自己无法使用的产品提出投诉,因此他们只会悄然离开;而且自 2018 年以来,美国网站无障碍诉讼数量逐年攀升。**改进方法:**将无障碍问题视为发布阻断项,并采用与功能缺陷相同的严重程度规则;在发布就绪检查中报告尚未解决的无障碍问题。
只测试正常流程
只扫描页面的默认状态,遗漏使用了不同 ARIA 属性的模态框、展开的下拉菜单、错误消息和加载骨架屏。**改进方法:**在测试中触发每种交互状态(点击以打开菜单、触发数据获取),并针对变更后的 DOM 重新运行扫描。
故障模式
| 症状 | 可能原因 | 修复或检查 |
|---|---|---|
| axe 检测到 0 个违规,但页面无法通过键盘操作 | 自动扫描不会测试可操作性或焦点顺序 | 执行键盘审计;添加 keyboard.spec.ts |
toMatchAriaSnapshot 不稳定 | 快照范围内的动态内容或列表重排 | 将范围限定为稳定的容器;使用部分快照 |
| 对比度规则通过,但渐变、叠加层或图像上的文本无法阅读 | axe 无法计算非纯色背景上的对比度 | 手动检查这些情况,或使用对比度取色器 |
| axe 检查通过,但 WCAG 2.2 AA 审计未通过 | axe 未提供 2.4.11 / 2.5.7 规则,对 2.5.8 的支持也不完整 | 手动验证焦点未被遮挡、拖动操作的替代方案以及目标尺寸 |
验证
确认测试套件确实覆盖了页面——一个虚假通过的无障碍测试(URL 错误、axe 扫描的是错误页面、快照从未执行)比没有测试更糟。
- 确认 axe 扫描的是实际内容。 将辅助函数指向一个已知存在违规的页面(例如,暂时移除一个
<label>),然后运行测试——测试必须失败并指出规则:
如果植入缺陷的页面仍然通过,说明 AxeBuilder 扫描了错误的 DOM(重定向、空白页面或错误的选择器)——在信任任何绿色运行结果之前先修复。npx playwright test e2e/tests/a11y/pages.spec.ts - 确认键盘测试规范访问的是应用,而不是 404 页面。 运行
npx playwright test e2e/tests/a11y/keyboard.spec.ts,并打开跳过链接测试的跟踪记录——第一次按 Tab 应该聚焦到跳过链接,而不是没有任何结果。测试因页面从未加载而“通过”,属于虚假通过。 - 确认 CI 门禁会阻止合并。 在一个分支上引入一项严重违规并推送——
a11y作业必须以非零状态退出,并使 PR 检查失败。之后还原更改。 - 抽查 ARIA 快照。 使用
--update-snapshots运行一次toMatchAriaSnapshot,然后不带该参数再运行一次——第二次运行必须通过。如果结果不稳定,说明快照范围包含异步变化或重排的内容;将范围缩小到稳定的容器。
完成标准
- 已将 axe-core 集成到 E2E 测试套件,并自动检查测试策略中确定的所有关键用户页面。
- CI 报告的 axe 严重或紧急违规为零;出现任何违规时会阻止合并(工作流见
references/recipes.md)。 - 已对所有交互流程(表单、模态框、下拉菜单、导航菜单)进行端到端键盘导航测试。
- 已验证至少一个下拉菜单/菜单(
aria-expanded+role)、一个加载区域(aria-busy)和一个实时区域(aria-live)的交互状态 ARIA。 - 已根据 WCAG AA 阈值验证完整品牌调色板的颜色对比度(普通文本为 4.5:1,大号文本和 UI 组件为 3:1)。
- 已记录复杂自定义控件(日期选择器、数据表格、拖放)的屏幕阅读器测试说明,包括使用的屏幕阅读器及其版本。
相关技能
- playwright-automation — axe 扫描和键盘/ARIA 快照测试所用的测试运行器;此技能在其基础上补充了无障碍专项模式。
- compliance-testing — 涵盖法律/法规测试,包括 Cookie 同意(GDPR/CMP)、VPAT 生成以及 EAA/Section 508 报告。Cookie 同意横幅和正式合规文档请参阅此技能;WCAG 一致性测试请留在这里。
- visual-testing — 基于像素差异的截图回归测试。视觉渲染变更请使用此技能;语义树回归请使用本技能的 ARIA 快照,a11y 专项颜色阈值请使用对比度检查。
- ci-cd-integration — 在 CI 中运行 a11y 测试,并在出现违规时阻止合并。
- risk-based-testing — 确定优先审计的页面和组件。