简体   繁体   中英

Cypress: How can I select elements of a list that have a certain condition?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM