In Cypress how to count a selection of items and get the length?

Automated TestsCypress

Automated Tests Problem Overview


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.

Automated Tests Solutions


Solution 1 - Automated Tests

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

Solution 2 - Automated Tests

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.

Solution 3 - Automated Tests

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);
  });

Solution 4 - Automated Tests

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)
})

Solution 5 - Automated Tests

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.

Solution 6 - Automated Tests

  • .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

Solution 7 - Automated Tests

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

Solution 8 - Automated Tests

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

Solution 9 - Automated Tests

to get the length you need to use cypress commands:

    cy.get('[ng-repeat="item in catalog"]').then(($el) => { 
        const itemCount = Cypress.$($el).length;
        cy.log(itemCount)
    })

Solution 10 - Automated Tests

 - In the element locator "aria-setsize" property to find the "number of items in the current set of listitems or treeitems" can be used.
 - Within ".then" function, for the previously yielded element. Use ".length" jquery as below.
 - To find the list of: Best Sellers in Computers & Accessories, in "Amazon.in" home screen.

it('test', () => {
        cy.visit('https://www.amazon.in/ref=nav_logo')
        cy.wait(3000)
        cy.get('#desktop-5 li[aria-setsize]')
        .then(($el) => {
         const count= $el.length
         cy.log(count)
        })

    })

Solution 11 - Automated Tests

Body variable is already resolved as you're in .then() part of the promise:

cy.get("body").then($body => {
    cy.log($body.find(".datatable tr").length);
});`

Solution 12 - Automated Tests

It will try until we find 4 matching .datatable > tr

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKatharine OsborneView Question on Stackoverflow
Solution 1 - Automated TestsKatharine OsborneView Answer on Stackoverflow
Solution 2 - Automated TestsYuciView Answer on Stackoverflow
Solution 3 - Automated TestsJohn Benedict Pal-lingayanView Answer on Stackoverflow
Solution 4 - Automated Tests0x4a6f4672View Answer on Stackoverflow
Solution 5 - Automated Testslauri108View Answer on Stackoverflow
Solution 6 - Automated TestskhizerView Answer on Stackoverflow
Solution 7 - Automated TestsSajid AliView Answer on Stackoverflow
Solution 8 - Automated TestsRahul SinghView Answer on Stackoverflow
Solution 9 - Automated TestsWariView Answer on Stackoverflow
Solution 10 - Automated TestsBalajiKView Answer on Stackoverflow
Solution 11 - Automated TestsIvan ValadaresView Answer on Stackoverflow
Solution 12 - Automated TestsGHULAM NABIView Answer on Stackoverflow