不能只测HTML结构而要测可访问性行为,因为<button>和<div role="button">在DOM中可能相同,但可访问性树中是否被识别为按钮、是否有name、是否支持键盘聚焦,必须依赖语义属性和真实浏览器环境判断;仅用querySelector检查标签或class等于测字符串而非用户真实操作。
HTML 标签本身不带交互逻辑,<button> 和 <div role="button"> 在 DOM 树里可能长得一样,但可访问性树里是否被识别为按钮、是否有 name、是否支持键盘聚焦,全靠语义属性和真实浏览器环境判断。只用 querySelector 检查标签或 class,等于在测字符串,不是测用户能怎么用。
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') 是必要断言,否则屏幕阅读器无法感知状态变化Chrome DevTools 中执行 Command Menu → "Disable styles" 后,页面只剩语义骨架。这时如果 <h2> 看起来像普通段落、<nav> 无法被键盘 Tab 到、<button> 没有焦点环,说明结构依赖样式而非语义——这种组件在无障碍场景下就是不可用的。
<h1> → <h2> → <h3>,不能跳级或用 <div class="h2"> 冒充aria-label=""(用于装饰性图标)Elements → Inspect Accessibility Properties 直接查看可访问性树,比肉眼判断更可靠jsdom 不解析 CSS、不触发 layout、不模拟焦点样式、不支持 IntersectionObserver,更不会构建可访问性树。它返回的 offsetHeight 恒为 0,focus() 不触发 :focus-visible,aria-expanded 属性变了但屏幕阅读器根本读不到。
立即学习“前端免费学习笔记(深入)”;
generateCardHtml(data),断言输出是否含 <h3> 和 aria-label
host.shadowRoot().locator('button'),jsdom 根本不支持 shadowRoot API