[英]Cypress: How can I select elements of a list that have a certain condition?
for the following html:对于以下 html:
<tr xpath="1">
<td>
<a class="orderTemplate-name" href="/my-account/saved-carts/0000443027"> td </a>
<div class="orderTemplate-created">
<span> blabla </span><!----><span> blabla </span>
</div>
</td>
<td>
<div class="orderTemplateOrderImage">
<!----><!---->
</div>
</td>
<td>
<div class="orderTemplateActions">
<button class="btn btn-commerce" id="addBtn" type="button">
<cx-icon class="">
<!----><!---->
<svg viewBox="0 0 20 20">
<path fill="currentColor" fill-rule="evenodd" d="blabla"></path>
</svg>
</cx-icon>
</button>
<a class="btn-icon" href="/my-account/saved-carts/0000443027">
<cx-icon class="">
<!----><!---->
<svg viewBox="0 0 20 20">
<path fill="currentColor" fill-rule="evenodd" d="blabla"></path>
</svg>
</cx-icon>
</a>
<button class="btn-icon" id="deleteBtn" type="button">
<cx-icon class="">
<!----><!---->
<svg viewBox="0 0 20 20">
<path fill="currentColor" fill-rule="evenodd" d="blabla"></path>
</svg>
</cx-icon>
</button>
</div>
</td>
</tr>
i want to click on the deleteBtn
if orderTemplate-name
contains "automated test title".如果
orderTemplate-name
包含“自动测试标题”,我想单击deleteBtn
。 there are more than one tr
and some have another name then "automated test title" and some have the same name.有不止一个
tr
,有些有另一个名字,然后是“自动测试标题”,有些有相同的名字。 I only wanna delete all with this name.我只想删除所有具有此名称的内容。 How can I do this?
我怎样才能做到这一点?
i've tried it with:我试过:
cy.get('tbody tr').each(($ele) => {
if ($ele.find('.orderTemplate-name').contains('automated test title')) {
cy.get('#deleteBtn').click()
}
})
EDIT:编辑:
Fody's method works very well, but there is a problem with the indexing of the <tr>
elements. Fody 的方法效果很好,但是
<tr>
元素的索引有问题。 the first <tr>
is indexed first.第一个
<tr>
首先被索引。 If you delete it, it skips the next <tr>
element and you continue with the third element.如果你删除它,它会跳过下一个
<tr>
元素,你继续第三个元素。 I have attached a screenshot to make this clearer.我附上了屏幕截图以使这一点更清楚。 this is after the first element has been deleted.
这是在第一个元素被删除之后。 you can see that the next
<tr>
element is skipped.你可以看到下一个
<tr>
元素被跳过了。 https://imgur.com/a/VRHw1dR https://imgur.com/a/VRHw1dR
$ele.find('.orderTemplate-name').contains('automated test title')
gives an error $ele.find('.orderTemplate-name').contains('automated test title')
报错
$ele.find(...).contains is not a function
$ele.find(...).contains 不是 function
because there is no .contains()
in jQuery.因为jQuery中没有
.contains()
。
You can use the pseudo-selector :contains , but you must test the .length
of the result您可以使用伪选择器:contains ,但您必须测试结果的
.length
if ($ele.find('.orderTemplate-name:contains("automated test title")').length) {
cy.get('#deleteBtn').click()
is a bit dodgy because it always searches from the top of the document, not within the row. cy.get('#deleteBtn').click()
有点狡猾,因为它总是从文档的顶部而不是行内搜索。
If the delete action is slow to remove the row, it might still find the previous delete button because .each()
will run quite fast.如果删除行的删除操作很慢,它可能仍会找到上一个删除按钮,因为
.each()
运行得非常快。
Add .within()
to fix that添加
.within()
来解决这个问题
cy.get('tbody tr').each(($row) => {
if ($row.find('.orderTemplate-name:contains("automated test title")').length) {
cy.wrap($row).within(() => {
cy.get('#deleteBtn').click()
})
}
})
Simpler to add :contains()
condition inside the row selector在行选择器中添加
:contains()
条件更简单
cy.get('tbody tr:contains("automated test title")').each(($row) => {
cy.wrap($row).find('#deleteBtn').click()
})
I agree with your comment, detached-from-DOM error is most likely due to re-render after a delete.我同意您的意见,从 DOM 分离错误很可能是由于删除后重新呈现造成的。
This function might get better results这个 function 可能会得到更好的结果
const deleteRow = (selector, rowsToDelete) => {
if (rowsToDelete === 0) return
// Fresh query each iteration
cy.get('tbody tr:contains("automated test title")').eq(0)
.as('rowDeleted')
.find('#deleteBtn').click()
// Need some way to make sure delete action has finished
cy.get('@rowDeleted')
.should('not.exist')
// Do the next one
deleteRow(selector, --rowsToDelete)
}
const selector = 'tbody tr:contains("automated test title")'
cy.get(selector).then($rows => {
const rowsToDelete = $rows.length // obtain the count
deleteRow(selector, rowsToDelete)
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.