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.
Best Answer
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
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)
I tested with Cypress version 3.1.0 and 3.2.0.
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);});
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 elementsexpect($table.find('td').length).to.equal(4)})
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.
cy.get('ul[data-qa="qa-navbar"] li') // selector .should('have.length', 5) // Assertion
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
.children (selector(byId, class, custom attribute) yields DOMelements 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
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)})
- 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.lengthcy.log(count)})})
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);});`