Cypress中如何筛选包含指定嵌套选择器的列表元素?
问题:Cypress遍历列表项时,无法正确跳过不含指定子元素的项
HTML结构
页面中有两类<li>元素:
包含目标子元素的项:
<li class="comp-data-text"> </li> <span class="imstuck" data-bind="text"> Something </span>
不包含目标子元素的项:
<li class="comp-data-text"> </li>
尝试的代码及问题
我需要判断每个列表项是否包含.imstuck子元素,仅对包含的项执行断言。尝试了以下代码:
cy.get('li.comp-data-text').each(($item) => { if ($item.has('span.imstuck')) { cy.wrap($item).find('.imstuck').should('contain', 'Something') } })
但即使列表项不含.imstuck,代码仍会进入if分支执行find操作,导致报错:
AssertionError Timed out retrying after 10000ms: Expected to find element: .imstuck, but never found it. Queried from element: <li.comp-data-text>
也试过另一种写法,结果相同:
cy.get('li.comp-data-text').each(($item) => { if ($item.hasClass('.imstuck')) { cy.wrap($item).find('.imstuck').should('contain', 'Something') } })
预期与实际
- 预期:不含
.imstuck的列表项跳过if分支,不执行断言代码 - 实际:所有项都会进入分支,无目标元素时触发查找失败错误
解决方案
1. 正确判断子元素是否存在
问题出在if条件的判断逻辑:
- jQuery的
.has()返回的是jQuery对象,而非布尔值,空对象仍为真值,导致条件始终成立 .hasClass()针对的是当前元素(<li>)的类,而非子元素,且参数不需要加.
修改为通过length属性判断子元素是否存在:
cy.get('li.comp-data-text').each(($item) => { // 检查子元素是否存在,length>0表示存在 if ($item.find('span.imstuck').length > 0) { cy.wrap($item).find('.imstuck').should('contain', 'Something') } })
2. 另一种写法:使用jQuery的.has()结合length
cy.get('li.comp-data-text').each(($item) => { if ($item.has('span.imstuck').length > 0) { cy.wrap($item).find('.imstuck').should('contain', 'Something') } })
3. 更简洁的Cypress风格写法(可选)
如果不需要遍历每个项,也可以直接筛选出包含目标子元素的项,再统一断言:
// 直接获取所有包含.imstuck的li,然后断言文本 cy.get('li.comp-data-text:has(span.imstuck)') .find('.imstuck') .should('contain', 'Something') // 同时验证不含.imstuck的li数量(可选) cy.get('li.comp-data-text:not(:has(span.imstuck))').should('have.length', 1) // 根据实际数量调整
内容的提问来源于stack exchange,提问作者Mag
相关产品推荐
相关产品推荐

