# Selected value

# Option's value

<select>
  <option value="456">apples</option>
  <option value="457">oranges</option>
  <option value="458">bananas</option>
</select>

Let's select the option "oranges" and see what value it has. We can use cy.select (opens new window) It yields the jQuery for the original <select> element.

cy.get('select')
  .select('oranges')
  .should(($el) => {
    expect(Cypress.dom.isElement($el), 'yields DOM element').to
      .be.true
    expect(Cypress.dom.isJquery($el), 'wrapped in jQuery').to.be
      .true
    // note: the yielded element is the <select>
    expect($el.prop('nodeName'), 'element type').to.equal(
      'SELECT',
    )
    expect($el.val(), 'option value').to.equal('457')
  })
// shorter assertion using chaining
cy.get('select')
  .select('oranges')
  .invoke('val')
  .should('equal', '457')
// you can yield the value without retrying
cy.get('select')
  .select('oranges')
  .invoke('val')
  .then((value) => {
    expect(value).to.equal('457')
  })

You can select multiple options, yielding list of elements

<select multiple>
  <option value="456">apples</option>
  <option value="457">oranges</option>
  <option value="458">bananas</option>
</select>
cy.get('select')
  .select(['apples', 'bananas']) // yields <select> element
  .invoke('val') // calls $(<select>).val() which returns list of selected values
  .should('deep.equal', ['456', '458'])

# Selecting option by index

Imagine we have a <select> element and want to select an option by index. Let's say we want to select the option at index 1 and confirm it has text "oranges" and value "457".

<select>
  <option value="456">apples</option>
  <option value="457">oranges</option>
  <option value="458">bananas</option>
</select>
// every child of <select> is an <option> element
cy.get('select')
  .children()
  .eq(1)
  .then(($option) => {
    expect(
      $option.prop('label'),
      'cannot compare 🍎 to 🍊',
    ).to.equal('oranges')

    const value = $option.attr('value')
    expect(value).to.equal('457')
    // if we want to select the oranges,
    // let's use the value we got
    cy.get('select').select(value)
  })
// let's confirm the selected option
cy.get('select').invoke('val').should('equal', '457')

# Selecting the random option

Imagine we have a <select> element and want to select one of its options randomly.

<select>
  <option value="456">apples</option>
  <option value="457">oranges</option>
  <option value="458">bananas</option>
</select>
// get the number of options available
cy.get('select option')
  .its('length')
  // pick a random number between 0 and n-1
  // using the Lodash _.random function
  .then((n) => Cypress._.random(0, n - 1))
  // print the picked random number
  .should('be.a', 'number')
  // and then use the cy.select command
  // to select it from the element
  .then((index) => {
    cy.get('select').select(index)
  })
// confirm the selected value
cy.get('select')
  .invoke('val')
  .should('be.oneOf', ['456', '457', '458'])

# Select the last option

Similarly, we can select the last option in two steps: first, find the value of the last <option> element, then select it in the <select> element.

<select>
  <option value="apl">apples</option>
  <option value="ora">oranges</option>
  <option value="ban">bananas</option>
</select>
cy.get('select option')
  .last()
  .invoke('val')
  .then((value) => {
    cy.get('select').select(value)
  })
// verify the last option was selected
cy.get('select').should('have.value', 'ban')

# Verify options text

Let's say we want to verify all available options and confirm their text. The options below should include only "BMW", "Mercedes", and "Audi".

<select id="cars_list">
  <option value="-1">--Select Car--</option>
  <option value="B">BMW</option>
  <option value="M">Mercedes</option>
  <option value="A">Audi</option>
</select>

The test is verbose on purpose, converting and confirming everything step by step.

cy.get('#cars_list option')
  .then(($options) => {
    // get the text of each option
    return Cypress._.map(
      $options,
      ($option) => $option.innerText,
    )
  })
  .should('deep.equal', [
    '--Select Car--',
    'BMW',
    'Mercedes',
    'Audi',
  ])
  // let's skip the "--Select Car--" default option
  .then((list) =>
    Cypress._.filter(list, (s) => s !== '--Select Car--'),
  )
  // and check now
  .should('deep.equal', ['BMW', 'Mercedes', 'Audi'])
  // TIP: sort the array for consistency
  .invoke('sort')
  .should('deep.equal', ['Audi', 'BMW', 'Mercedes'])

# Get selected option

You can get the currently selected option using the jQuery's :selected selector (opens new window).

<select id="name">
  <option>Joe</option>
  <option>Mary</option>
  <option selected="selected">Peter</option>
</select>
cy.get('select#name option:selected').should(
  'have.text',
  'Peter',
)