Cypress - how to get child of a specific parent element

Viewed 2632

I am stuck by finding a specific button within my list of items... The button exists 3 times with exact same data-testid, but the parent is different. And I end with

error: cy.click() can only be called on a single element. Your subject contained 3 elements. Pass { multiple: true } if you want to serially click each element.

HTML:

        <div data-testid="list-item">
          <div>
            <div>
              <span data-testid="status1">
          <button data-testid="details_button">click</button>
            </div>
          </div>
       </div>
       <div data-testid="list-item">
          <div>
            <div>
              <span data-testid="status2">
          <button data-testid="details_button">click</button>
            </div>
          </div>
      </div>

How can I select the details_button of either status1 or status2?

My attempt was:

  1. cy.get('[data-testid=status1]')
      .get('[data-testid="details_button"]').click()
    
  2. cy.get('[data-testid=status1]')
      .parent().parent()
      .get('[data-testid="details_button"]').click()
    
2 Answers

Your first attempt is almost correct, but use .find() for the second step

cy.get('[data-testid=status1]')
  .find('[data-testid="details_button"]')  // find works here (same as .within())
  .click()

Works for this HTML

<div data-testid="list-item">
  <div>
    <div>
      <span data-testid="status1">
        <button data-testid="details_button">click</button>
      <!-- span closing tag is missing -->
    </div>
  </div>
</div>

The reason that works is because the HTML posted is slightly invalid - the <span> has no closing tag.

Cypress thinks that the button is inside the span, so using .find() works.


However if that's a typo, you should change to your 2nd command using .parent() and also change .get() to .find()

cy.get('[data-testid=status1]')
  .parent()
  .find('[data-testid="details_button"]')
  .click()

Works for this HTML

<div data-testid="list-item">
  <div>
    <div>
      <span data-testid="status1"></span>   
      <!-- span is closed, button is outside span so use .parent() command -->
      <button data-testid="details_button">click</button>
    </div>
  </div>
</div>

You can use the siblings() method is cypress.

cy.get('[data-testid=status1]').siblings('[data-testid="details_button]').click()
cy.get('[data-testid=status2]').siblings('[data-testid="details_button]').click()

You can also use a combination of parent() and within(), something like:

cy.get('span[data-testid=status1]')
  .parent('div')
  .within(() => {
    cy.get('button[data-testid="details_button]').click()
  })
cy.get('span[data-testid=status2]')
  .parent('div')
  .within(() => {
    cy.get('button[data-testid="details_button]').click()
  })
Related