accessibility-testing

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
<objective> Make an application usable by people who rely on keyboards and assistive technology, and prove it with tests that run in CI. A button that passes `toBeVisible()` can still be unreachable by keyboard; a page with zero axe violations can still be impossible to operate with a screen reader. Automated tools catch 30-40% of accessibility issues — this skill covers the automated scan plus the keyboard, screen reader, and ARIA-state testing that catch the other 60-70%. </objective>
<objective> 让依赖键盘和辅助技术的用户能够使用应用程序,并通过在CI中运行的测试来验证这一点。通过`toBeVisible()`测试的按钮仍可能无法通过键盘访问;没有axe违规的页面仍可能无法通过屏幕阅读器操作。自动化工具只能发现30-40%的无障碍问题——本技能涵盖自动化扫描以及键盘、屏幕阅读器和ARIA状态测试,可发现剩下的60-70%问题。 </objective>

Discovery Questions

探索问题

Check
.agents/qa-project-context.md
first — if it exists, use it as the foundation and skip anything already answered.
Requirements and compliance (sets the target level and audit obligations)
  • What WCAG conformance level is required — A, AA, or AAA? AA is the practical legal default.
  • What laws apply — ADA, EAA/EN 301 549, Section 508, AODA? Each maps to a WCAG level.
  • Is there a VPAT or accessibility statement to maintain, or contractual a11y clauses from enterprise/government customers?
Current state (tells you whether you're auditing or preventing regressions)
  • Has an audit run before? What were the findings, and what's already in the backlog?
  • Does the design system carry accessibility guidance and accessible components?
Testing infrastructure (determines what you can automate vs. must do by hand)
  • Is automated a11y testing already in CI?
  • Which screen readers does the team test with — VoiceOver, NVDA, JAWS, TalkBack?
首先查看
.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?

Core Principles

核心原则

  1. Automated testing catches 30-40% of issues — no more. axe-core finds missing alt text, low contrast, missing labels, and invalid ARIA. It cannot tell you whether alt text is meaningful, whether tab order is logical, or whether a custom widget is operable. Passing axe is necessary, not sufficient. Crucially, axe ships no automated rule for several WCAG 2.2 success criteria (2.4.11 focus-not-obscured, 2.5.7 dragging movements, and 2.5.8 target-size only partially) — a green axe run does not equal 2.2 AA conformance.
  2. Semantic HTML first, ARIA as last resort. Native elements (
    <button>
    ,
    <nav>
    ,
    <input>
    ,
    <dialog>
    ) carry built-in semantics, keyboard behavior, and screen reader support. A
    <div role="button">
    also needs
    tabindex
    , Enter/Space handlers, focus styles, and ARIA state — all of which a
    <button>
    gives you free. Reach for ARIA only when no native element fits.
  3. Test in impact order: keyboard, screen reader, automated. Keyboard issues physically block users from features (highest impact). Screen reader issues confuse with wrong announcements. Automated checks catch the mechanical remainder. Start where the damage is worst, not where the tooling is easiest.
  4. Accessibility is a quality attribute, not a feature. Test it continuously like performance or security — every new component, every PR. Retrofitting accessibility onto a finished product costs 10-100x more because inaccessible patterns get baked into the component library.
  5. Test with real assistive technology. Browser DevTools and axe extensions are dev aids, not substitutes for VoiceOver (macOS/iOS), NVDA (Windows), and TalkBack (Android), which each behave differently. Reserve manual AT passes for complex custom widgets.
  1. 自动化测试仅能发现30-40%的问题——仅此而已。axe-core可发现缺失的替代文本、低对比度、缺失标签和无效ARIA,但无法判断替代文本是否有意义、Tab顺序是否合理,或自定义组件是否可操作。通过axe测试是必要条件,但并非充分条件。关键是,axe并未针对WCAG 2.2的多项成功准则(2.4.11焦点不被遮挡、2.5.7拖拽操作、2.5.8目标尺寸仅部分覆盖)提供自动化规则——axe测试通过并不等同于符合2.2 AA标准。
  2. 优先使用语义化HTML,ARIA仅作为最后手段。原生元素(
    <button>
    <nav>
    <input>
    <dialog>
    )自带语义、键盘行为和屏幕阅读器支持。
    <div role="button">
    还需要
    tabindex
    、Enter/Space事件处理程序、焦点样式和ARIA状态——而这些
    <button>
    都能免费提供。仅当没有合适的原生元素时才使用ARIA。
  3. 按影响优先级测试:键盘、屏幕阅读器、自动化。键盘问题会从物理层面阻碍用户使用功能(影响最高)。屏幕阅读器问题会因错误播报造成混淆。自动化检查处理剩余的机械性问题。从影响最严重的环节开始,而非工具最易用的环节。
  4. 无障碍是质量属性,而非功能。像性能或安全一样持续测试——每个新组件、每个PR都要测试。在成品上 retrofit(改造)无障碍功能的成本是10-100倍,因为无障碍模式会被嵌入组件库中。
  5. 使用真实辅助技术测试。浏览器DevTools和axe扩展是开发辅助工具,无法替代VoiceOver(macOS/iOS)、NVDA(Windows)和TalkBack(Android),这些工具的行为各不相同。仅对复杂自定义组件进行手动辅助技术测试。

Automated Scanning with axe-core + Playwright

使用axe-core + Playwright进行自动化扫描

Install
@axe-core/playwright
(the 4.11.x line; it tracks axe-core's major.minor). Wrap it in a reusable
checkAccessibility(page, testInfo, options)
helper that filters to the WCAG tags
['wcag2a', 'wcag2aa', 'wcag22aa']
, attaches the full results JSON to the test for the audit trail, and asserts
violations.toHaveLength(0)
. Loop it over every key page and over interactive states (modal open, menu expanded), not just the default load.
Suppress a rule only with a documented justification (a tracking issue or inline comment) and
exclude
third-party widgets you don't own rather than disabling the rule globally.
See
references/recipes.md
for the install command, RGAA tag caveat, the full helper, the page-loop and interactive-state specs, rule suppression, and CI integration.
安装
@axe-core/playwright
(4.11.x版本,与axe-core的主版本号同步)。将其封装为可复用的
checkAccessibility(page, testInfo, options)
辅助函数,过滤WCAG标签
['wcag2a', 'wcag2aa', 'wcag22aa']
,将完整结果JSON附加到测试中作为审计追踪,并断言
violations.toHaveLength(0)
。遍历所有关键页面和交互状态(模态框打开、菜单展开),而非仅默认加载状态。
仅在有文档化理由(跟踪问题或内联注释)的情况下抑制规则,对于不属于你的第三方组件,使用
exclude
排除而非全局禁用规则。
有关安装命令、RGAA标签注意事项、完整辅助函数、页面遍历和交互状态规范、规则抑制以及CI集成,请查看
references/recipes.md

Manual Testing Checklist

手动测试清单

Automated scanning is the floor. These checks need a human (or a keyboard-driven Playwright spec — see
references/recipes.md
for the keyboard specs).
自动化扫描是基础。以下检查需要人工完成(或通过键盘驱动的Playwright规范完成——请查看
references/recipes.md
中的键盘规范)。

Keyboard navigation audit

键盘导航审计

  • Tab order is logical — left-to-right, top-to-bottom for LTR. No surprise focus jumps.
  • All interactive elements reachable via Tab / Shift+Tab.
  • Focus indicator visible on every focused element. No
    outline: none
    without a replacement.
  • Skip link works — first Tab reveals "Skip to main content"; Enter moves focus to
    <main>
    .
  • Enter activates buttons/links; Space activates buttons and toggles checkboxes.
  • Escape closes modals, dropdowns, tooltips; focus returns to the trigger.
  • Arrow keys navigate within tabs, menus, radio groups, tree views.
  • No keyboard traps (modal dialogs intentionally trap until dismissed — that's allowed).
  • Custom widgets operable without a mouse (sliders, date pickers, drag-and-drop).
  • Tab顺序合理——从左到右、从上到下(LTR语言)。无意外焦点跳转。
  • 所有交互元素可通过Tab/Shift+Tab访问
  • 每个聚焦元素都有可见的焦点指示器。无
    outline: none
    替代方案时不要使用该属性。
  • 跳转链接可用——首次按Tab键显示“跳转到主要内容”;按Enter键将焦点移至
    <main>
  • Enter键激活按钮/链接;空格键激活按钮并切换复选框。
  • Esc键关闭模态框、下拉菜单、提示框;焦点返回触发元素。
  • 方向键在标签页、菜单、单选组、树视图内导航。
  • 无键盘陷阱(模态框在关闭前故意捕获焦点——这是允许的)。
  • 自定义组件无需鼠标即可操作(滑块、日期选择器、拖放)。

Screen reader testing

屏幕阅读器测试

Screen ReaderOSBrowserFree?
VoiceOvermacOS/iOSSafariYes (Cmd+F5)
NVDAWindowsFirefox/ChromeYes
JAWSWindowsChrome/EdgeNo
TalkBackAndroidChromeYes
  • Page title announced on navigation.
  • Headings form a navigable outline (h1 → h2 → h3, no skipped levels).
  • Images have descriptive alt text (or
    alt=""
    for decorative).
  • Form inputs announce their labels when focused.
  • Required fields announced as required; errors associated with their input.
  • Live regions announce dynamic content (toasts, loading states).
  • Buttons/links announce their purpose (no "click here").
屏幕阅读器操作系统浏览器免费?
VoiceOvermacOS/iOSSafari是(Cmd+F5)
NVDAWindowsFirefox/Chrome
JAWSWindowsChrome/Edge
TalkBackAndroidChrome
  • 导航时播报页面标题。
  • 标题形成可导航的大纲(h1 → h2 → h3,无层级跳跃)。
  • 图片有描述性替代文本(装饰性图片使用
    alt=""
    )。
  • 表单输入框在聚焦时播报其标签。
  • 必填字段被播报为必填;错误信息与其输入框关联。
  • 实时区域播报动态内容(提示框、加载状态)。
  • 按钮/链接播报其用途(无“点击此处”)。

Color contrast and visual

颜色对比度与视觉检查

  • Normal text: 4.5:1 minimum (WCAG AA). Large text (18pt+ / 14pt+ bold): 3:1.
  • UI components and graphical objects: 3:1 against adjacent colors.
  • Information never conveyed by color alone — add icons, patterns, or text.
  • 普通文本:最小对比度4.5:1(WCAG AA标准)。大文本(18pt+ / 14pt+加粗):3:1
  • UI组件和图形对象:与相邻颜色的对比度3:1
  • 信息永远不单独通过颜色传达——添加图标、图案或文本。

Form and error accessibility

表单与错误无障碍

  • Every input has a visible
    <label>
    tied via
    for
    /
    id
    (placeholder is not a label).
  • Required fields indicated visually and programmatically (
    required
    /
    aria-required
    ).
  • Errors use
    aria-describedby
    to link to the input and
    role="alert"
    to announce.
  • Focus moves to the first error on submission failure.
  • Related fields grouped with
    <fieldset>
    and
    <legend>
    .
  • 每个输入框都有可见的
    <label>
    ,并通过
    for
    /
    id
    关联(占位符不能作为标签)。
  • 必填字段通过视觉程序方式(
    required
    /
    aria-required
    )标记。
  • 错误信息使用
    aria-describedby
    链接到输入框,并使用
    role="alert"
    进行播报。
  • 提交失败时焦点移至第一个错误。
  • 相关字段使用
    <fieldset>
    <legend>
    分组。

WCAG 2.2 Quick Reference

WCAG 2.2速查

Level A (must fix)

A级(必须修复)

CriterionWhat it meansCommon failure
1.1.1 Non-text ContentImages have alt text
<img>
without
alt
1.3.1 Info and RelationshipsStructure via HTML semantics
<div>
styled as a heading
2.1.1 KeyboardAll functionality via keyboardCustom widget responds only to mouse
2.4.1 Bypass BlocksSkip navigation linkNo skip link
3.1.1 Language of Page
<html lang="en">
set
Missing
lang
3.3.1 Error IdentificationErrors described in textError shown only by red border
4.1.2 Name, Role, ValueCustom controls expose name/role
<div onclick>
with no role
准则含义常见错误
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>
无角色属性

Level AA (most common legal requirement)

AA级(最常见的法律要求)

CriterionWhat it meansCommon failure
1.4.3 Contrast (Minimum)4.5:1 normal, 3:1 largeLight gray on white
1.4.4 Resize TextScales to 200% without lossFixed-height containers clip text
1.4.11 Non-text ContrastUI components 3:1Low-contrast input borders
2.4.7 Focus VisibleKeyboard focus visible
outline: none
with no replacement
2.5.8 Target SizeTouch targets 24×24px minTiny icon buttons
3.3.2 Labels or InstructionsInputs have labelsPlaceholder as the only label
3.3.8 Accessible AuthNo cognitive function testCAPTCHA with no alternative
准则含义常见错误
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无替代方案

Level AAA (nice to have)

AAA级(可选增强)

CriterionWhat it means
1.4.6 Contrast (Enhanced)7:1 normal text, 4.5:1 large
2.4.9 Link Purpose (Link Only)Link text alone describes destination
3.1.5 Reading LevelLower-secondary education level
准则含义
1.4.6 对比度(增强)普通文本7:1,大文本4.5:1
2.4.9 链接用途(仅链接)仅链接文本即可描述目标
3.1.5 阅读水平低于中等教育水平

Accessible Patterns

无障碍模式

Test on the accessible tree (roles, names, ARIA state), not on CSS. The patterns you need runnable tests for:
  • Forms — error linked via
    aria-describedby
    ,
    aria-invalid='true'
    , focus on first error.
  • Modal/dialog
    aria-modal='true'
    ,
    aria-labelledby
    , focus trapped, Escape returns focus.
  • Interactive states — opened dropdown (
    role="menu"
    or
    role="listbox"
    ,
    aria-expanded
    ), loading skeleton (
    aria-busy='true'
    during fetch), toast (
    aria-live='polite'
    ). These carry different ARIA per state, so click to trigger the state change and assert the open-state ARIA — the default page snapshot never exercises them.
  • Data tables
    columnheader
    roles,
    aria-sort
    reflects the active sort.
  • Landmarks — exactly one
    main
    ;
    banner
    ,
    navigation
    ,
    contentinfo
    present.
See
references/patterns.md
for the full runnable tests for every pattern above.
针对无障碍树(角色、名称、ARIA状态)进行测试,而非CSS。需要可运行测试的模式:
  • 表单——错误信息通过
    aria-describedby
    链接,
    aria-invalid='true'
    ,焦点移至第一个错误。
  • 模态框/对话框——
    aria-modal='true'
    aria-labelledby
    ,焦点捕获,Esc键返回焦点。
  • 交互状态——展开的下拉菜单(
    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 Snapshots

ARIA快照

Playwright's
toMatchAriaSnapshot()
captures the accessible tree as YAML and asserts against it — the fastest way to catch a regression where a visual change silently breaks semantics (a
<div>
restyled to look like a button, a heading demoted to plain text). It checks structure and accessible names, not pixels, so it's complementary to
visual-testing
, not a replacement. Scope snapshots to a stable container; whole-page snapshots over async content go flaky. See
references/patterns.md
for navigation and form snapshot examples.
Playwright的
toMatchAriaSnapshot()
将无障碍树捕获为YAML并进行断言——这是捕获视觉变化导致语义静默破坏(如
<div>
被重新样式为按钮、标题降级为普通文本)的最快方式。它检查结构和无障碍名称,而非像素,因此是
visual-testing
的补充,而非替代方案。将快照范围限定在稳定容器内;包含异步内容的整页快照会不稳定。有关导航和表单快照示例,请查看
references/patterns.md

Legal Compliance Mapping

法律合规映射

Law / StandardRegionWCAG level requiredEnforcement
ADAUSAAA (court precedent)Lawsuits (private right of action)
Section 508USA (federal)WCAG 2.0 AAFederal procurement requirement
EAAEUEN 301 549 (WCAG 2.1 AA)In force since 28 June 2025. Member states actively enforcing; private cause of action varies (DE, FR, IE most active). EN 301 549 expected to align with WCAG 2.2 next revision.
AODAOntario, CanadaWCAG 2.0 AAFines up to $100K/day
EN 301 549EUWCAG 2.1 AAPublic procurement requirement
Equality Act 2010UKWCAG 2.1 AA (guidance)Lawsuits
ISO/IEC 40500:2025InternationalEquivalent to WCAG 2.2 (Oct 2023)Useful for procurement/RFP language; freely available from ISO
Practical target: if you serve US or EU users, WCAG 2.2 AA is the target for new development — the EAA is in force, EN 301 549 is expected to update to 2.2, and ISO/IEC 40500:2025 (published Sept 2025) codifies WCAG 2.2 internationally. WCAG 2.1 AA is the legacy minimum where 2.2 can't be reached immediately.
WCAG 3 status: W3C published an updated WCAG 3 working draft in March 2026 that renamed "Outcomes" to "Requirements" and moved away from binary pass/fail grading; it lists ~174 requirements. It remains a working draft — Candidate Recommendation is targeted for Q4 2027 and a Recommendation not before 2028. Plan for WCAG 2.2 today; track WCAG 3 but do not test against it yet.
Audit evidence to collect: automated scan results per page, manual checklists with tester/date, screen reader results with AT versions, accessibility statement, VPAT for enterprise sales, and a remediation plan for known issues. For the full legal/VPAT/consent mapping, see
compliance-testing
.
法律/标准地区要求的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公共采购要求
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国际化。WCAG 2.1 AA是暂时无法达到2.2时的遗留最低标准。
WCAG 3状态:W3C于2026年3月发布了WCAG 3的更新工作草案,将“成果”更名为“要求”,并放弃了二元通过/失败评级;列出了约174项要求。目前仍为工作草案——候选推荐目标为2027年第四季度,正式推荐不会早于2028年。当前计划基于WCAG 2.2;跟踪WCAG 3但暂不针对其进行测试。
需收集的审计证据:每页的自动化扫描结果、带有测试人员/日期的手动检查清单、包含辅助技术版本的屏幕阅读器测试结果、无障碍声明、面向企业销售的VPAT,以及已知问题的整改计划。有关完整的法律/VPAT/同意映射,请查看
compliance-testing

Anti-Patterns

反模式

Only automated testing

仅依赖自动化测试

Running axe, finding zero violations, and declaring the product accessible. Automated tools miss 60-70% of real issues and skip several WCAG 2.2 criteria entirely. Fix: pair every axe run with the keyboard and screen reader checklist; gate releases on both, not just the scan.
仅运行axe测试,发现无违规后就宣称产品无障碍。自动化工具会遗漏60-70%的实际问题,并且完全跳过WCAG 2.2的多项准则。修复方案:将每次axe测试与键盘和屏幕阅读器清单相结合;发布需同时通过两者,而非仅扫描。

ARIA overuse

过度使用ARIA

Adding
role
,
aria-label
, and
aria-describedby
to elements that already have native semantics, creating double announcements. Fix: delete the redundant ARIA and use the native element — a
<button>
never needs
role="button"
.
为已有原生语义的元素添加
role
aria-label
aria-describedby
,导致重复播报。修复方案:删除冗余的ARIA,使用原生元素——
<button>
永远不需要
role="button"

Ignoring keyboard users

忽略键盘用户

Features that work by mouse and touch but not keyboard — click-only dropdowns, drag-and-drop with no keyboard path, hover-only tooltips. Fix: give every mouse interaction a keyboard equivalent and cover it with a
keyboard.spec.ts
test (see
references/recipes.md
).
功能仅支持鼠标和触摸,不支持键盘——仅点击的下拉菜单、无键盘路径的拖放、仅悬停的提示框。修复方案:为每个鼠标交互提供键盘等效操作,并通过
keyboard.spec.ts
测试覆盖(请查看
references/recipes.md
)。

Retrofitting accessibility

后期改造无障碍

Waiting until the product is "finished," by which point inaccessible patterns are baked into the component library at 10-100x the fix cost. Fix: add an axe check to the Definition of Done so every new component is gated on accessibility before merge.
等到产品“完成”后再处理,此时无障碍模式已嵌入组件库,修复成本是10-100倍。修复方案:将axe检查添加到“完成定义”中,确保每个新组件在合并前都通过无障碍测试。

Treating accessibility as optional

将无障碍视为可选功能

Deprioritizing a11y tickets because "nobody complained" — users with disabilities can't complain through a product they can't use, so they leave silently, and US web-accessibility lawsuits have climbed year over year since 2018. Fix: track a11y as a release blocker with the same severity rules as functional bugs, and report open a11y issues in the release readiness check.
因“无人投诉”而优先处理无障碍工单——有障碍的用户无法通过无法使用的产品投诉,因此会默默离开,且自2018年以来美国网页无障碍诉讼逐年增加。修复方案:将无障碍问题作为发布阻塞项,与功能缺陷使用相同的严重性规则,并在发布就绪检查中报告未解决的无障碍问题。

Testing only the happy path

仅测试正常路径

Scanning only the default page state, missing the modals, expanded dropdowns, error messages, and loading skeletons that carry different ARIA. Fix: drive each interactive state in the test (click to open the menu, trigger the fetch) and re-run the scan against the changed DOM.
仅扫描默认页面状态,遗漏模态框、展开的下拉菜单、错误信息和加载骨架等带有不同ARIA属性的状态。修复方案:在测试中触发每个交互状态(点击打开菜单、触发数据获取),并针对变化后的DOM重新运行扫描。

Failure Modes

故障模式

SymptomLikely causeFix or check
axe finds 0 violations but the page is unusable by keyboardAutomated scans don't test operability or focus orderRun the keyboard audit; add a
keyboard.spec.ts
toMatchAriaSnapshot
is flaky
Dynamic content or list reordering inside the snapshot scopeScope to a stable container; use a partial snapshot
Contrast rule passes but text over a gradient/overlay/image is unreadableaxe can't compute contrast against non-solid backgroundsCheck those cases manually or with a contrast picker
Passing axe but failing a WCAG 2.2 AA auditaxe ships no rule for 2.4.11 / 2.5.7 and only partial 2.5.8Manually verify focus-not-obscured, dragging alternatives, and target size
症状可能原因修复或检查方法
axe测试无违规,但页面无法通过键盘使用自动化扫描不测试可操作性或焦点顺序运行键盘审计;添加
keyboard.spec.ts
toMatchAriaSnapshot
不稳定
快照范围内有动态内容或列表重新排序将范围限定在稳定容器;使用部分快照
对比度规则通过,但渐变/覆盖层/图片上的文本不可读axe无法计算非纯色背景的对比度手动检查这些情况或使用对比度选择器
axe测试通过,但未通过WCAG 2.2 AA审计axe未针对2.4.11/2.5.7提供规则,仅部分覆盖2.5.8手动验证焦点不被遮挡、拖拽替代方案和目标尺寸

Verification

验证

Prove the suite actually exercises the page — an a11y test that passes vacuously (wrong URL, axe scanning an error page, snapshot never reached) is worse than none.
  1. Confirm axe is scanning real content. Point the helper at a page you know has a violation (e.g. temporarily remove a
    <label>
    ) and run it — the test must FAIL and name the rule:
    bash
    npx playwright test e2e/tests/a11y/pages.spec.ts
    If a page with a planted defect still passes, AxeBuilder is scanning the wrong DOM (redirect, blank page, or wrong selector) — fix that before trusting any green run.
  2. Confirm the keyboard specs reach the app, not a 404. Run
    npx playwright test e2e/tests/a11y/keyboard.spec.ts
    and open the trace for the skip-link test — the first Tab should land on the skip link, not nowhere. A test that "passes" because the page never loaded is a false green.
  3. Confirm the CI gate blocks. Introduce one serious violation on a branch and push — the
    a11y
    job must exit non-zero and fail the PR check. Revert after.
  4. Spot-check an ARIA snapshot. Run
    toMatchAriaSnapshot
    once with
    --update-snapshots
    , then again without — the second run must pass. If it flakes, the snapshot scope includes async/reordering content; narrow it to a stable container.
证明测试套件确实覆盖了页面——空通过的无障碍测试(错误URL、axe扫描错误页面、快照未加载)比没有测试更糟。
  1. 确认axe扫描真实内容。将辅助函数指向已知存在违规的页面(例如临时移除
    <label>
    )并运行——测试必须失败并指出规则:
    bash
    npx playwright test e2e/tests/a11y/pages.spec.ts
    如果植入缺陷的页面仍通过测试,说明AxeBuilder扫描了错误的DOM(重定向、空白页或错误选择器)——在信任任何通过结果前修复该问题。
  2. 确认键盘规范覆盖应用,而非404页面。运行
    npx playwright test e2e/tests/a11y/keyboard.spec.ts
    并打开跳转链接测试的跟踪记录——首次按Tab键应定位到跳转链接,而非无焦点。因页面未加载而“通过”的测试是虚假通过。
  3. 确认CI网关阻止违规。在分支中引入一个严重违规并推送——
    a11y
    任务必须返回非零状态并使PR检查失败。之后恢复。
  4. 抽查ARIA快照。使用
    --update-snapshots
    运行一次
    toMatchAriaSnapshot
    ,然后再次运行——第二次必须通过。如果不稳定,说明快照范围包含异步/重排序内容;将其缩小到稳定容器。

Done When

完成标准

  • axe-core integrated into the E2E suite and run automatically on all key user-facing pages identified in the test strategy.
  • CI reports zero critical or serious axe violations and blocks merge when any are introduced (see
    references/recipes.md
    for the workflow).
  • Keyboard navigation tested end-to-end for all interactive flows (forms, modals, dropdowns, navigation menus).
  • Interactive-state ARIA verified for at least one dropdown/menu (
    aria-expanded
    +
    role
    ), one loading region (
    aria-busy
    ), and one live region (
    aria-live
    ).
  • Color contrast validated for the full brand palette against WCAG AA thresholds (4.5:1 normal text, 3:1 large text and UI components).
  • Screen reader test notes documented for complex custom widgets (date pickers, data tables, drag-and-drop), including which screen reader and version was used.
  • axe-core集成到E2E套件中,并自动在测试策略中确定的所有关键用户页面上运行。
  • CI报告零严重或高危axe违规,且在引入任何违规时阻止合并(有关工作流,请查看
    references/recipes.md
    )。
  • 所有交互流程(表单、模态框、下拉菜单、导航菜单)都经过端到端键盘导航测试。
  • 至少验证一个下拉菜单/菜单(
    aria-expanded
    +
    role
    )、一个加载区域(
    aria-busy
    )和一个实时区域(
    aria-live
    )的交互状态ARIA。
  • 针对WCAG AA阈值(普通文本4.5:1,大文本和UI组件3:1)验证完整品牌调色板的颜色对比度。
  • 记录复杂自定义组件(日期选择器、数据表、拖放)的屏幕阅读器测试笔记,包括使用的屏幕阅读器和版本。

Related Skills

相关技能

  • playwright-automation — the test runner for both axe scans and keyboard/ARIA snapshot tests; this skill adds the accessibility-specific patterns on top.
  • compliance-testing — legal/regulatory testing including cookie consent (GDPR/CMP), VPAT generation, and EAA/Section 508 reporting. Go there for consent banners and formal compliance documentation; stay here for WCAG conformance testing.
  • visual-testing — pixel-diff screenshot regression. Use it for visual rendering changes; use this skill's ARIA snapshots for semantic-tree regressions and contrast for the a11y-specific color thresholds.
  • ci-cd-integration — running a11y tests in CI and blocking merges on violations.
  • risk-based-testing — prioritizes which pages and components to audit first.
  • playwright-automation——axe扫描和键盘/ARIA快照测试的测试运行器;本技能在此基础上添加了无障碍特定模式。
  • compliance-testing——法律/法规测试,包括Cookie同意(GDPR/CMP)、VPAT生成和EAA/Section 508报告。Cookie横幅和正式合规文档请使用该技能;WCAG合规测试请使用本技能。
  • visual-testing——像素差异截图回归测试。用于视觉渲染变化;本技能的ARIA快照用于语义树回归,对比度检查用于无障碍特定颜色阈值。
  • ci-cd-integration——在CI中运行无障碍测试,并在出现违规时阻止合并。
  • risk-based-testing——优先确定要审计的页面和组件。