不能只测HTML结构而要测可访问性行为,因为<button>和<p role=”button”>在DOM中可能相同,但可访问性树中是否被识别为按钮、是否有name、是否支持键盘聚焦,必须依赖语义属性和真实浏览器环境判断;仅用querySelector检查标签或class等于测字符串而非用户真实操作。

为什么不能只测 HTML 结构而要测可访问性行为
HTML 标签本身不带交互逻辑,<button> 和 <p role="button"> 在 DOM 树里可能长得一样,但可访问性树里是否被识别为按钮、是否有 name、是否支持键盘聚焦,全靠语义属性和真实浏览器环境判断。只用 querySelector 检查标签或 class,等于在测字符串,不是测用户能怎么用。
如何用 getByRole 定位并验证真实可访问性状态
getByRole 是目前最贴近用户操作的定位方式,它会自动查找可访问性树中匹配 role + name 的元素,同时触发隐式等待(比如组件异步渲染后才出现)。
- 必须显式提供
name:比如screen.getByRole('checkbox', { name: '接收邮件通知' }),否则即使 DOM 存在也会报错——这不是 API 问题,是组件缺aria-label或可见文本 - 禁用态不能只看
disabled属性:await expect(checkbox).toBeDisabled()才真正检查浏览器是否阻止了焦点和点击,因为有些组件用aria-disabled="true"或 class 模拟禁用 - 展开/收起控件必须同步
aria-expanded:expect(button).toHaveAttribute('aria-expanded', 'true')是必要断言,否则屏幕阅读器无法感知状态变化
测试时禁用 CSS 后还能否维持语义结构
Chrome DevTools 中执行 Command Menu → "Disable styles" 后,页面只剩语义骨架。这时如果 <h2> 看起来像普通段落、<nav> 无法被键盘 Tab 到、<button> 没有焦点环,说明结构依赖样式而非语义——这种组件在无障碍场景下就是不可用的。
- 标题层级必须连续且有意义:
<h1>→<h2>→<h3>,不能跳级或用<p class="h2">冒充 - 所有交互元素必须有明确 role 和 name,哪怕只是空的
aria-label=""(用于装饰性图标) - 用
Elements → Inspect Accessibility Properties直接查看可访问性树,比肉眼判断更可靠
jsdom 为什么不能替代真实浏览器做可访问性测试
jsdom 不解析 CSS、不触发 layout、不模拟焦点样式、不支持 IntersectionObserver,更不会构建可访问性树。它返回的 offsetHeight 恒为 0,focus() 不触发 :focus-visible,aria-expanded 属性变了但屏幕阅读器根本读不到。
立即学习“前端免费学习笔记(深入)”;
- 适合场景:纯函数生成 HTML 字符串,如
generateCardHtml(data),断言输出是否含<h3>和aria-label - 不适合场景:任何涉及键盘导航、焦点管理、状态同步、动态渲染的组件,必须进 Playwright / Puppeteer
- Shadow DOM 组件需显式穿透:
host.shadowRoot().locator('button'),jsdom 根本不支持 shadowRoot API
真实可访问性测试最难的不是写断言,而是让组件从第一行 HTML 就带上可测锚点:role、name、state 缺一不可,且不能靠 class 或内联样式驱动行为。
文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/xitongjiaocheng/125660.html