在前端自动化测试中,Cypress默认无法访问封装在阴影DOM内部的节点,导致很多自定义组件里的按钮、输入框不能被普通选择器定位。要解决这个问题,需要理解Cypress对阴影DOM的支持方式并做相应配置。

什么是Shadow DOM
Shadow DOM是Web组件规范的一部分,它允许将元素的内部结构封装起来,避免外部文档的样式和脚本干扰。一个宿主元素可以通过attachShadow方法创建影子根,其内部节点对外不可见。
<div id="host"></div>
<script>
const host = document.getElementById('host');
const shadow = host.attachShadow({ mode: 'open' });
shadow.innerHTML = '<button class="inner-btn">点击</button>';
</script>
Cypress默认行为的限制
在未开启阴影DOM支持时,Cypress的cy.get()只在常规DOM树中查找,遇到mode: 'open'的影子根也不会自动进入,因此像.inner-btn这样的选择器会返回空。
开启includeShadowDom配置
从Cypress 6开始,可以在配置文件中设置includeShadowDom为true,让所有命令默认穿透阴影边界。
// cypress.config.js
module.exports = {
e2e: {
includeShadowDom: true,
setupNodeEvents() {}
}
};
使用.shadow()命令精确选取
如果不想全局开启,也可以使用.shadow()命令进入指定宿主的影子根。下面示例演示如何点击阴影里的按钮。
// 测试代码示例
describe('Shadow DOM测试', () => {
it('点击阴影内的按钮', () => {
cy.visit('https://ipipp.com/shadow-demo');
cy.get('#host')
.shadow()
.find('.inner-btn')
.should('contain', '点击')
.click();
});
});
处理嵌套阴影DOM
有些组件存在多层阴影嵌套,可以连续调用.shadow()。
cy.get('outer-host')
.shadow()
.find('inner-host')
.shadow()
.find('.deep-element')
.click();
注意事项
- 如果影子根以
mode: 'closed'创建,Cypress也无法访问其内部,需要改造组件。 - 全局开启
includeShadowDom可能略微影响选择器性能,按需使用更好。 - 使用
.shadow()时,确保宿主元素已渲染完成,可加.should('exist')。
掌握上述方法后,隐藏在阴影DOM中的元素就能被Cypress稳定选取,自动化测试覆盖率也随之提升。
CypressShadow_DOM元素选取修改时间:2026-07-26 17:30:23