tva
← Insights

在自动化浏览器测试中处理 Shadow DOM

封装问题

Shadow DOM 防止外部 CSS 和 JavaScript 影响组件内部结构——这对于设计系统来说是一个有价值的特性。但这种相同的封装使标准的测试选择器失效。document.querySelector('.my-button') 无法找到 Shadow root 中的 .my-button

Playwright 的 Shadow DOM 支持

Playwright 对 Shadow DOM 有内置支持,但它需要了解正在使用哪种 Shadow DOM 实现。

对于开放的 Shadow DOM(mode: "open"),Playwright 的选择器引擎可以自动穿透 Shadow 边界:

await page.locator('my-component >> .inner-button').click()

>> 语法表示"穿透 Shadow DOM 边界"。这适用于整个选择器链。

封闭 Shadow DOM 的挑战

封闭的 Shadow DOM(mode: "closed")是真正的障碍。Shadow root 无法从外部访问,即使是 Playwright 的选择器引擎也无法穿透它。

在实践中,封闭的 Shadow DOM 在最终用户库中很少见,在你自己构建的组件中几乎不应该使用——测试能力是使用封闭模式的充分理由。但如果你必须与封闭的 Shadow DOM 交互,注入脚本是唯一可靠的方法。

实际策略

最可靠的方法是使用数据属性而不是 CSS 类进行测试选择器:

await page.locator('[data-testid="submit-button"]').click()

数据属性在 Shadow DOM 边界上的工作方式与在常规 DOM 中相同,并且它们清楚地表明其存在是为了测试目的,而不是样式。

组件库注意事项

如果你使用带有 Shadow DOM 的第三方组件库,检查它们是否公开推荐的测试钩子。许多现代组件库包含专门设计用于自动化测试的 data-testid 属性或aria-label 约定。

相关洞见

相关文章