如何编写Cypress测试校验Shadow DOM元素可见性与支付方法一致性?
问题描述
在线商店的支付方式下拉列表包含信用卡、现金、免费、租赁四个选项,用户选择支付方式后进入购物车,要求购物车中的支付方式下拉列表与之前选择的一致。编写测试用例随机选择支付方式并对比两处文本时,因涉及Shadow DOM元素在Cypress中报错:
Timed out retrying after 30000ms: Expected the subject to host a shadow root, but never found it.
当前测试代码
cy.xpath("//div[@class='simple-caption-input form-group--width-fix d--block']//select").shadow().filter(':visible').invoke('text').then((First) => { cy.xpath('cart').click() cy.xpath("//div[@class='simple-caption-input form-group--width-fix d--block']//select").shadow().filter(':visible').invoke('text').then((Second) => { expect(First).to.include(Second) }) })
DevTools截图

问题分析与解决方案
错误根源:你给普通
<select>元素调用了.shadow()方法,但从截图看这个下拉框是原生HTML组件,并不包含Shadow DOM,这才导致超时报错。修正后的测试逻辑:
- 随机选择支付方式并记录选中的文本值
- 点击进入购物车
- 验证购物车中支付方式的选中值与之前记录的一致
修正代码:
// 随机选择支付方式并记录选中文本 cy.xpath("//div[@class='simple-caption-input form-group--width-fix d--block']//select") .filter(':visible') .then($select => { // 获取可用选项并随机选中一个 const availableOptions = $select.find('option').not('[disabled]') const randomIndex = Math.floor(Math.random() * availableOptions.length) const selectedText = availableOptions.eq(randomIndex).text() cy.wrap($select).select(selectedText) // 修正购物车按钮定位(原代码的cy.xpath('cart')定位错误) cy.xpath("//*[contains(text(),'购物车')]").click() // 验证购物车中的支付方式与选中的一致 cy.xpath("//div[@class='simple-caption-input form-group--width-fix d--block']//select") .filter(':visible') .invoke('val') .then(cartSelectedValue => { cy.xpath(`//div[@class='simple-caption-input form-group--width-fix d--block']//select/option[@value="${cartSelectedValue}"]`) .invoke('text') .should('eq', selectedText) }) })
- 额外注意事项:
- 若页面确实存在Shadow DOM,需确认Shadow DOM的宿主元素是自定义组件(如
<custom-payment-select>),而非<select>本身。此时要先定位宿主元素,调用.shadow()后再查找内部的<select>元素。 - 原代码中
cy.xpath('cart')定位逻辑错误,需根据页面实际结构替换为正确的购物车按钮定位表达式。
- 若页面确实存在Shadow DOM,需确认Shadow DOM的宿主元素是自定义组件(如
内容的提问来源于stack exchange,提问作者Alex77
相关产品推荐
相关产品推荐

