102
votes

I'm starting to learn Cypress. I have a 4 row table (with a class of datatable). I can verify the number of rows this way:

cy.get('.datatable').find('tr').each(function(row, i){
        expect(i).to.be.lessThan(4)
})

This is fine, but it seems awkward, since I just want to count the length and don't really need to access the stuff in the rows, and I assume it's faster to do one thing than do 4 things.

If I log the selection (not sure what else to call it):

cy.log(cy.get('.datatable').find('tr'))

it comes out as [object Object] and I'm not quite sure how to deconstruct that, which suggests to me that I'm thinking about this all wrong.

If I try:

expect(cy.get('.datatable').find('tr')).to.have.lengthOf(4)

I get AssertionError: expected { Object (chainerId, firstCall) } to have a property 'length'

If I try:

    expect(Cypress.$('.datatable > tr')).to.have.lengthOf(4)

I get AssertionError: expected { Object (length, prevObject, ...) } to have a length of 4 but got 0 so at least it has a length here?

If I log that method of selection I get Object{4}. I'm not sure where to go from here. It seems like this would be a very common thing to deal with.

8
My client uses only Chrome (it's not a public facing app). We have moved away from Cypress as we are converting the app to Angular and are now using Karma and Jasmine (which are inbuilt with the framework). I found Cypress quite easy to work with but I didn't choose it (nor did I choose Angular); however I would have to say that the extensive documentation for Cypress is probably very attractive. When testing is not your ken and more of a chore, having extensive docs with good examples helps you get up and running quicker.Katharine Osborne
Thanks, so much for your feedback Katharinealexrogers

8 Answers

148
votes

Found a solution, This works to check a count of items:

cy.get('.datatable').find('tr').should('have.length', 4)

This does not work with the Cypress.$() method of notation.

Reference: https://docs.cypress.io/guides/references/assertions.html#Length

76
votes

You can also get the length of a selection of items through its property, for example:

cy.get('.datatable').find('tr').its('length').should('eq', 4)
cy.get('.datatable').find('tr').its('length').should('be.gte', 4)

In addition to should('have.length', 4)

enter image description here I tested with Cypress version 3.1.0 and 3.2.0.

31
votes

if you want more flexible and have a dynamic result use this.

cy.get('.listings-grid')
  .find('.listing')
  .then(listing => {
    const listingCount = Cypress.$(listing).length;
    expect(listing).to.have.length(listingCount);
  });
11
votes

One option is to use "have.length" ...

cy.get('.datatable tr').should('have.length', 4)

...another option is to use should

cy.get('.datatable tr').should(($tr) => {
    expect($tr).to.have.length(4)
})

...or then (synchronous queries)

cy.get('.datatable').then(($table) => {
  // synchronously query to find length of elements
  expect($table.find('td').length).to.equal(4)
})
5
votes

From the cypress API docs .should() section, using an arrow function:

cy.get('.datatable').find('tr').should(($listOfElements) => {
   expect($listOfElements).to.have.length(4)
   // any other assertions, for example the below one
   // expect($listOfElements).to.have.any.keys('key1', 'key2')
})

This approach will allow you to use Chai BDD notation and assert more than one thing on your list of elements.

0
votes

cy .get('ul[data-qa="qa-navbar"] li') // selector .should('have.length', 5) // Assertion

0
votes

My use case was to compare that, say no. of "i" icons on the page should match the no. of table rows. So, this solution worked for it i.e. when I wanted to compare the no. of elements of one selector vs the other

cy.get('first element').its('length').then((val)=>{
     cy.get('second element).its('length').should('eq',val)
})

Writing then after its captures the requested property (in this case, length) and within the first then block, we do a compare by getting the length of the second element

-1
votes
  • .children (selector(byId, class, custom attribute) yields DOM elements and retry untill defaultCommandTimeout exceeds.

    cypress config defaultCommandTimeout

  • once DOM elements exists and yielded added length assertion.

<ul data-qa="qa-navbar">
  <li>Home</li>
  <li>About</li>
  <li>Services</li>
  <li>Our Team</li>
  <li>Contact Us</li>
</ul>

    cy
      .get('[data-qa="qa-navbar"]') // selector
      .children() // get direct decendents 
      .should('have.length', 5); // add assertion to have lenght of 5