For a Java/kotlin geek, I'm finding Cypress a bit hard to work with, since I'm used to the way Java/Kotlin and Selenium works.
In this example, I'm having some trouble getting a table with several rows of data, and creating an elegant method of getting a specific td in a specific row.
Consider this simplified markup:
<table>
<tr data-e2e-selector="case-row">
<td data-e2e-selector="date">3. sep</td>
<td data-e2e-selecto=""name">Frank</td>
</tr>
<tr data-e2e-selector="case-row">
<td data-e2e-selector="date">12. sep</td>
<td data-e2e-selecto=""name">Ola</td>
....
....
<tr data-e2e-selector="case-row">
<td data-e2e-selector="date">23. sep</td>
<td data-e2e-selecto=""name">Morgan</td>
</table>
I can get the whole set of rows like this:
cy.get('[data-e2e-selector="case-row]')
That gives me a list/array of the correct number of rows.
However, if I want to get for instance the data-e2e-selector="date"
field from the first, last or other specific row, I'm running into problems.
I would think that this line would verify the "date" field of the FIRST row:
cy.get('[data-e2e-selector=case-row]').first().get('[data-e2e-selector=innsendtDato]').should('contain.text', "3. sep")
But it doesn't, apparently. Because if the cypress runner reports this ("successful") check:
-assert- expected '[ <td#sakInnsendtDato_0.ng-star-inserted>, 20 more... ]' to contain text '23. sep'
which seems to indicate that it's been looking through all 21 rows to find a with the expected value. Whereas I want to know if it's in the FIRST.
To verify this, if I change "first()" to "last()", it will also verify successfully.
So, how does this work?
I've also tried using index to indicate the first row, instead of first() or last(), but that gives a compile error.
Any ideas?
The Cypress command you want to use is cy.find()
. This will search a descendant DOM element, where cy.get()
starts from the top of the DOM for searching. From the cy.get()
documentation:
The
cy.get
command always starts its search from the cy.root element. In most cases, it is the document element, unless used inside the .within() command. The .find command starts its search from the current subject.
cy.get('[data-e2e-selector=case-row]')
.first()
.find('[data-e2e-selector=innsendtDato]')
.should('contain.text', "3. sep");
Alternatively, you could use .within()
to yield the first element and then use cy.get()
within that callback.
cy.get('[data-e2e-selector=case-row]')
.first()
.within(($el) => {
cy.get('[data-e2e-selector=innsendtDato]')
.should('contain.text', "3. sep");
});
When chaining a cy.get()
off of the your .first()
command, you're not actually using the yield of the .first()
command to perform your search. The test is marked as passed because the result of the second cy.get()
(innsendtDato) yields 21 elements (all elements found by cy.get('[data-e2e-selector=innsendtDato]')
) and at least one of those elements does contain the text 3. sep
.