LovelyAndy
LovelyAndy

Reputation: 891

How to capture the value of options in a select dropdown for comparison?

I have a dropdown on my dashboard that will redirect the user to a new page based on the value of the option they chose. All the IDs in the dropdown are also the route in the URL, so I figured I could just select whatever option in the list and just assert that the URL route contains that value.

I'm just having trouble figuring out how to get the value of the selected option saved to a variable in the test itself.

The test I have so far. Right now I have a variable that I would like to store the value (selectedIssueID), but getting a Cannot read properties of undefined (reading 'apply') error.

I'm a bit lost here, so if anyone has any ideas, I would really appreciate it!

 it.only('Issue Analysis dropdown functionality check', () => {
   // Assert there are options in the dropdown
    cy.get('[data-cy=issue-analysis-select-issue-dropdown]').should(
      'have.length.gt',
      0
    )
   // grab the last option and store the value 
    let selectedIssueID = ''
    cy.get('[data-cy=issue-analysis-select-issue-dropdown] option')
      .last()
      .then(($lastOption) => {
        cy.get('[data-cy=issue-analysis-select-issue-dropdown]')
          .select($lastOption.text())
          .then((selectedIssueID = $lastOption.text()))
          .log(selectedIssueID)
      })
    // Assert it routes properly
    cy.url().should('include', `/analysis/${selectedIssueID}`)
  })

HTML (The CInput component itself is a all-encompassing input just with styles and some vuejs helpers)

<select
  data-cy="issue-analysis-select-issue-dropdown"
  id="0.2137294948228743"
  class="
    appearance-none
    border-0
    text-secondary-text text-sm
    bg-transparent
    min-w-min
    py-2
    pl-1
    leading-tight
    focus:outline-none
  "
  style="box-shadow: none"
>
  <option disabled="" value="" style="display: none;">Select an Issue You Want to Analyze</option>
  <option class="text-secondary-text" value="1">1</option>
  <option class="text-secondary-text" value="2">2</option>
  <option class="text-secondary-text" value="3">3</option>
  <option class="text-secondary-text" value="4">4</option>
  <option class="text-secondary-text" value="5">5</option>
  <option class="text-secondary-text" value="6">6</option>
  <option class="text-secondary-text" value="7">7</option>
  <option class="text-secondary-text" value="8">8</option>
  <option class="text-secondary-text" value="9">9</option>
</select>

Upvotes: 1

Views: 2299

Answers (2)

Fody
Fody

Reputation: 32044

It's just a bit of a syntax error in .then((selectedIssueID = $lastOption.text())).

But I would also perform saving the text first and then select the option, since that will cause a URL change and the page changes (you might lose the elements previously queried because of the page change)

Update adding an alias to allow selectedIssueID to be used in .select() command.
Ref: backflips

// grab the last option and store the value 
cy.get('[data-cy=issue-analysis-select-issue-dropdown] option').last()
  .then(($lastOption) => selectedIssueID = $lastOption.text())
  .as('selectedIssueID')

cy.get('@selectedIssueID').then(selectedIssueID => {
  cy.get('[data-cy=issue-analysis-select-issue-dropdown]')
    .select(selectedIssueID)
})

// Assert it routes properly
cy.url().should('include', `/analysis/${selectedIssueID}`)

Upvotes: 3

jjhelguero
jjhelguero

Reputation: 2555

You can use get the last option text and save it as an alias, then later get the alias and use it as an assertion on the url.

cy.get('[data-cy=issue-analysis-select-issue-dropdown] option')
  .last()
  .invoke('text')
  .as('lastOptionText')

cy.get('@lastOptionText')
  .then(lot => {
    cy.get('[data-cy=issue-analysis-select-issue-dropdown] option')
      .select(lot)
    cy.url().should('include', `/analysis/${lot}`)
  })

If you want to continue with your approach, you'd have to do some shifting around of your code to do the same.

let selectedIssueID

beforeEach(() => {
  // grab the last option and store the value 
  cy.get('[data-cy=issue-analysis-select-issue-dropdown] option')
    .last()
    .then(($lastOption) => {
      selectedIssueID = $lastOption.text()
    })
})

it.only('Issue Analysis dropdown functionality check', () => {
  // Assert there are options in the dropdown
  cy.get('[data-cy=issue-analysis-select-issue-dropdown]').should(
    'have.length.gt',
    0
  )
  cy.get('[data-cy=issue-analysis-select-issue-dropdown]')
    .select(selectedIssueID)

  // Assert it routes properly
  cy.url().should('include', `/analysis/${selectedIssueID}`)
})

Upvotes: 1

Related Questions