for the following 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". there are more than one tr
and some have another name then "automated test title" and some have the same name. 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. the first <tr>
is indexed first. If you delete it, it skips the next <tr>
element and you continue with the third element. 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. https://imgur.com/a/VRHw1dR
$ele.find('.orderTemplate-name').contains('automated test title')
gives an error
$ele.find(...).contains is not a function
because there is no .contains()
in jQuery.
You can use the pseudo-selector :contains , but you must test the .length
of the result
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.
If the delete action is slow to remove the row, it might still find the previous delete button because .each()
will run quite fast.
Add .within()
to fix that
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
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.
This function might get better results
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)
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.