Compare json file and dropdown values displayed in an inorderly way

Viewed 170

I have my JSON file with the following text[there are around 100 values I have just put 4 here]

{
  label: ['a', 'b', 'c', 'd'],
}

I have my dropdown in my website which has these values but in a different order.

How can I compare that the text from the JSON and dropdown values are equal?

Also, I have a text "ALL" which is displayed in the dropdown by default and is not included in the JSON file. It's like this: enter image description here

In the dropdown, the rest of the values are in the JSON file.

I have done the below but it is not working.

cy.fixture('label.json')
    .then(function (category) {
           this.cat = category
      })
})
cy.get('#labels').each(($ele, i) => {
      expect($ele).to.have.text(this.category.label[i])
      })
})

Any help will be highly appreciated Thank you

2 Answers

You can do something like this:

cy.fixture("labels.json").then((labels) => {
  cy.get("select#labels option").each(($ele, i) => {
    if ($ele.text().trim() == "ALL") {
      expect(labels.label).to.not.include($ele.text().trim())
    } else {
      expect(labels.label).to.include($ele.text().trim())
    }
  })
})

Test runner:

test runner screenshot

One way is to map the option elements to an array of label texts

HTML

<select name="labels" id="labels">
  <option value="" selected="">ALL</option>
  <option value="a">a</option> 
  <option value="c">c</option> 
  <option value="b">b</option> 
  <option value="d">d</option>
</select>

Test

cy.get('option')
  .then($options => Cypress.$.map($options, (option => option.innerText)))
  .then(optionLabels => {  

    // optionLabels is ['ALL', 'a', 'c', 'b', 'd']

    cy.fixture('my-labels.json'),then(fixture => {

      const expected = fixture.label.concat(['ALL'])  // add the ALL
      // expected is ['a', 'c', 'b', 'd', 'ALL']

      expect(optionLabels).to.have.members(expected)  // .to.have.members checks with any order
    })
  })

Result

enter image description here

When missing an option

enter image description here


Truncated option text

When your option text is truncated but you want to match to text in the fixture,

"clarif..." -> "clarification"

you can transform the fixture data before comparing.

Also, since there are 124 entries, it is better to just log any failures rather than the whole list.

<select>
  <option>ALL</option>
  <option>clarif...</option>
  <option>a</option>
  <option>d</option>
  <option>b</option>
</select>


cy.get('option')
  .then($options => Cypress.$.map($options, (option => option.innerText)))
  .then(console.log)
  .then(optionLabels => {

    cy.fixture('my-labels.json').then(fixture => {

      const truncate = (text) => text.length > 6 ? text.slice(0,6) + '...' : text;

      const expected = fixture.label.concat(['ALL'])      // add ALL
        .map(truncate)                 // convert fixture to short strings 

      const notInDropdown = expected.filter(exp => !optionLabels.includes(exp))
      const extraInDropdown = optionLabels.filter(label => !expected.includes(label))

      if (notInDropdown.length) {
        throw `Not in dropdown: ${notInDropdown.join(' ')}`
      }
      if (extraInDropdown.length) {
        throw `Extra in dropdown: ${extraInDropdown.join(' ')}`
      }
      cy.log('Dropdown passes')
    })
  })
})
Related