一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

前端架构内HTML组件可访问性的单元测试

时间:2026-07-13 12:02:51 编辑:袖梨 来源:一聚教程网

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

为什么不能只测 HTML 结构而要测可访问性行为

HTML 标签本身不带交互逻辑,<button><div 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-expandedexpect(button).toHaveAttribute('aria-expanded', 'true') 是必要断言,否则屏幕阅读器无法感知状态变化

测试时禁用 CSS 后还能否维持语义结构

Chrome DevTools 中执行 Command Menu → "Disable styles" 后,页面只剩语义骨架。这时如果 <h2> 看起来像普通段落、<nav> 无法被键盘 Tab 到、<button> 没有焦点环,说明结构依赖样式而非语义——这种组件在无障碍场景下就是不可用的。

  • 标题层级必须连续且有意义:<h1><h2><h3>,不能跳级或用 <div class="h2"> 冒充
  • 所有交互元素必须有明确 role 和 name,哪怕只是空的 aria-label=""(用于装饰性图标)
  • Elements → Inspect Accessibility Properties 直接查看可访问性树,比肉眼判断更可靠

jsdom 为什么不能替代真实浏览器做可访问性测试

jsdom 不解析 CSS、不触发 layout、不模拟焦点样式、不支持 IntersectionObserver,更不会构建可访问性树。它返回的 offsetHeight 恒为 0,focus() 不触发 :focus-visiblearia-expanded 属性变了但屏幕阅读器根本读不到。

立即学习“前端免费学习笔记(深入)”;

  • 适合场景:纯函数生成 HTML 字符串,如 generateCardHtml(data),断言输出是否含 <h3>aria-label
  • 不适合场景:任何涉及键盘导航、焦点管理、状态同步、动态渲染的组件,必须进 Playwright / Puppeteer
  • Shadow DOM 组件需显式穿透:host.shadowRoot().locator('button'),jsdom 根本不支持 shadowRoot API
真实可访问性测试最难的不是写断言,而是让组件从第一行 HTML 就带上可测锚点:role、name、state 缺一不可,且不能靠 class 或内联样式驱动行为。

热门栏目