7
votes

I'm trying to count the number of options in a select element, and the number of elements of a certain class in the DOM.

I need to compare the two totals for a Cypress assertion.

I can select the options I need, and iterate over them with each(), and increment a counter that way. However, it's asynchronous, and it's also a clumsy solution. I'm certain that the object yielded by my cy.get() has a length property, I just can't seem to get at it.

Here is one of the things I expected to work. It logs undefined to the console.

cy.get('div[data-cy-type="group-component"]:first').as('firstGroup');
cy.get('@firstGroup').find('[name=group_id]').as('groupSelect');
console.log(cy.get('@groupSelect').children('option').length);

I know my alias is good and my cy.get() is yielding the correct select element.

If I do something like this:

cy.get('@groupSelect').children('option').each(function(){
    console.log(i++);
});

then it will iterate over each option. But it's asynchronous so not very helpful in this flow.

3
I don't understand your problem exactly, but this may help - cy.get('@groupSelect').children('option').then(options => expect(options.length).to.eq(otherTotal)). I'm not sure how the other total (count of class in DOM) is derived, perhaps if you post more code we can help further. - Richard Matsen

3 Answers

5
votes

Maybe you can leverage Cypress.$. Please note however that the documentation doesn't precisely advertise it as a testing tool:

This is a great way to synchronously query for elements when debugging from Developer Tools.

Anyhow, I believe something along this line will yield the value you expect:

selector = 'div[data-cy-type="group-component"]:first select[name=group_id] option'
count = Cypress.$(selector).length
3
votes

You can simple access the length property of a cypress selector.

cy.get('.elements')
        .its('length')
        .then(lengthOfClassElements => cy
           .get('select > option')
           .its('length')
           .then(lengthOfOptions => {
               expect(lengthOfClassElements).to.be.moreThan(lengthOfOptions)
           });
1
votes

I've found that, for whatever reason, I need to chain get twice. The first get should select a parent element and then the second should select all the elements, which live under that parent, that you which to count.

const expectedCount = 5; // whatever count you expect
cy.get('.parentClass').get('.childClass').should('have.length', expectedCount);