Select elements in HTML via cypress.get()

10,384

Let's clarify a few things:

1) If you are just wanting to ASSERT that the div's contain the given text then this is the best possible and most precise way to do this:

cy.get('tr[data-recordid="theId"]').should(($tr) => {
  const $divs = $tr.find('div') // find all the divs

  expect($divs.eq(0)).to.contain('Text 1')
  expect($divs.eq(1)).to.contain('Text 2')
  expect($divs.eq(2)).to.contain('Text 2')
})

I can't tell if things need to be this specific. If you only want to ensure that the $tr contains text you could simplify it down to be:

cy.get('tr[data-recordid="theId"]').should(($tr) => {
  expect($tr).to.contain('Text 1')
  expect($tr).to.contain('Text 2')
  expect($tr).to.contain('Text 2')
})

Why do it this way?

  • Using a .should() function will not change the subject. Your $tr will continue to be the subject going forward.
  • Cypress will wait until all of the assertions in the .should() callback pass, and continually retry until they do. That guarantees you the state of multiple elements is correct before proceeding.

2) However if you just care that Cypress finds the text and you don't mind the subject being changed you could do this:

cy.get('tr[data-recordid="theId"]').within(() => {
  cy.contains('Text 1') // changes the subject to the <div>
  cy.contains('Text 2') // changes the subject to the <div>
  cy.contains('Text 3') // changes the subject to the <div>
})

This is different than the first example because instead of an explicit assertion you are simply changing the subject to whatever element the text is found in. Cypress's default assertion on cy.contains() is to retry so ultimately the behavior is the same, except you are additionally changing the subject.

If even this is too complicated you could also just do this:

cy.get('tr[data-recordid="theId"] div').contains('Text 1')
cy.get('tr[data-recordid="theId"] div').contains('Text 2')
cy.get('tr[data-recordid="theId"] div').contains('Text 3')

Your original question was also using chained cy.get() which does not drill into subjects. For that to happen use .find()

cy.get('a').get('span') // each cy.get() queries from the root
cy.get('a').find('span') // the .find() queries from the <a>

One final note: you suggested solution does not work. cy.get() does not accept a callback function, and if you look at your Command Log you will not see those 3 cy.contains from ever being invoked. In other words, they are not running. That's why its passing.

Share:
10,384
khmarbaise
Author by

khmarbaise

Xing Profile https://soebes.io https://blog.soebes.de Twitter: @khmarbaise linkedin Apache Maven Chairman Apache Maven PMC Member Apache Software Foundation Member MojoHaus Committer

Updated on September 07, 2022

Comments

  • khmarbaise
    khmarbaise over 1 year

    I'm using cypress to write some tests against an html site..

    The following selects me correctly a single tr elements from a table on my HTML site. The site contents looks like this:

    <tr data-recordid="theId">
      <td...><div ..>Text 1</div></td>
      <td...><div ..>Text 2</div></td>
      <td...><div ..>Text 3</div></td>
    </tr>
    

    The following test script snippet selects me correctly the single <tr..> part.

    cy.get('tr[data-recordid="theId"]').contains('Text')
    

    Now I want to select the text within the <div>..</div> tags..The first thing I have tried to chain a single call for the first <div>..</div> tag like this:

    cy.get('tr[data-recordid="theId"]').get('div').contains('Text')
    

    which does not work as I expected. The get() calls a chained jQuery calls (Based on the Docs of cypress). So it looks like I misunderstand how things work in JQuery.

    What I'm expecting is how I can check all div elements like this (Not working):

    cy.get('tr[data-recordid="theId"]')..SomeHowMagic
      .get('td[alt="xyz"]".get('div').contains('Text 1')
      .get('td...').get('div').contains('Text 2')
      .get('td...').get('div').contains('Text 3')
    

    Any idea how to get forward a step? Missing any information just make a comment.

  • khmarbaise
    khmarbaise over 6 years
    This solution does not work as Brian Mann has explained.
  • khmarbaise
    khmarbaise over 6 years
    Thank you very much for your detailed explanation and answering my question.. Appreciate to accept that. Brought me many things to think of and a better understanding...