Home > Back-end >  Is there any alternative to check if the text displayed of all the children are different?
Is there any alternative to check if the text displayed of all the children are different?

Time:01-03

it('features', () => {
      home.featuresMainTitle("What you'll learn")
      cy.get('.grid').children().each(($el, index, $list) =>{
        const currentText = $el.find('h3').text()
        const nextText = $el.next().find('h3').text()
        expect(currentText).to.not.equal(nextText)
      })

I'm capturing a grid from the DOM and trying to verify that the text in each children of the grid must be different of the others.

The code works but the impression that it gives to me is that's naive and that there's to be a better way to achieve the same result with a more polished code avoiding the use of that javascript variables (currentText and nextText) . Maybe is there a cypress characteristic that i'm unaware to makes the lines more cleaner at first glance.

CodePudding user response:

On the same idea of counting unique values, use Lodash uniqBy() method

cy.get('.grid')
  .children()
  .should($els => {
    const unique = Cypress._.uniqBy($els, (el) => el.innerText)
    expect(unique.length).to.eq($els.length)
  })

This will pass is all texts in the grid are unique.


Factoring in the <h3>

Since you're doing a .find() within the .each(), this should do the same unless you have some <h3> in the grid that need to be excluded.

cy.get('.grid')
  .find('h3')
  .should($els => {
    const unique = Cypress._.uniqBy($els, (el) => el.innerText)
    expect(unique.length).to.eq($els.length)
  })

CodePudding user response:

Not really less code, but gives you a stronger test:

If you use a Set you can verify the lengths of .children() and the length of the set.

The Set object lets you store unique values of any type

This does not limit you to comparing next and current, it compares across all children.

cy.get(".grid").children()
  .then($els => {
    const setOfTexts = new Set();
    [...$els].forEach(el => setOfTexts.add(el.innerText)); // only stores unique values
    return setOfTexts;
  })
  .then(setOfTexts => {
     cy.get(".grid").children().its('length')
       .should('eq', setOfTexts.size)
  })

or with a reducer,

cy.get(".grid").children()
  .then($els => [...$els].reduce((acc, el) => {
    acc.add(el.innerText)
  }, new Set()))
  .then(setOfTexts => {
     cy.get(".grid").children().its('length')
       .should('eq', setOfTexts.size)
  })

CodePudding user response:

Another way, get all the children, extract their text, create an array from a new set and then check it equals with the original array.

cy.get(".grid")
  .children()
  // get innerText of all children
  .then(($el) => Cypress._.map($el, (el) => el.innerText))
  .then((childrenText) => {
    // create new array of unique values
    const uniqueText = Array.from(new Set(childrenText));
    expect(childrenText).to.deep.equal(uniqueText);
  })

Here is a working example.

  • Related