How To Select And Invalid Option
Imagine your application responds to the user selection an option from a <select>
element. You handle the valid options, but how would you test handling of the invalid option by the default
switch case?
📺 Watch this recipe explained in Select Invalid Option.
<span>Sort items</span>
<select id="sort">
<option value="a to z">A to Z (name)</option>
<option value="z to a">Z to A (name)</option>
<option value="low to high">Low to high (price)</option>
<option value="high to low">High to low (price)</option>
</select>
<script>
document
.getElementById('sort')
.addEventListener('change', (e) => {
console.log('selected "%s"', e.target.value)
switch (e.target.value) {
case 'a to z':
console.log('sorting by name A to Z')
break
case 'z to a':
console.log('sorting by name Z to A')
break
case 'low to high':
console.log('sorting by price from lowest')
break
case 'high to low':
console.log('sorting by price from highest')
break
default:
console.error(`Unknown sort order ${e.target.value}`)
}
})
</script>
Let's confirm we can pick a valid option using the cy.select command.
cy.get('#sort').select('z to a').should('have.value', 'z to a')
How would you reach the default
select case statement?
cy.window()
.its('console')
.then((console) => {
cy.spy(console, 'error').as('error')
})
cy.get('#sort').invoke(
'append',
'<option value="nope">Nope</option>',
)
cy.get('#sort').select('nope')
Let's confirm the default
case statement called the console.error
method:
cy.get('@error').should('have.been.calledOnce')
// we can also check to confirm the select has the option Nope selected
cy.get('#sort').should('have.value', 'nope')
Tip: We need to re-query the element to select the newly added option because Cypress v12 made cy.invoke
a retry-able query, causing multiple <option value="nope">Nope</option>
elements to be appended. You can use cy.invokeOnce
from my cypress-map plugin instead:
cy.get('#sort')
.invokeOnce('append', '<option value="wrong">Wrong</option>')
.select('wrong')