'can't move a Slider <input type="range"> with Cypress using arrowKeys

I'm trying to implement some tests here and can't apply my logic to the input range of this website: https://the-internet.herokuapp.com/horizontal_slider

here my code

it('and a slider is displayed, the slider is moved to a specific position', () =>{
    cy.visit('/horizontal_slider')

    // to achieve this, we need to know the attributes of the slider component
    // min; max; value and step
    // we need to move the slider using the keyboard (right arrow) to move the slider
    // each type the key is pressed, the slider will move one value equal to the "step" attribute

    const destiny = 1
    const step = 0.5
    const initialValue = 0
    const stepsToReachDestiny = (destiny - initialValue) / step 

    // now we repeat x times (stepsToReachDestiny) 
    // the key press to reach the value
    const keyboardCommandRepeated = '{rightArrow}'.repeat(stepsToReachDestiny)

    // and call the function
    cy.get('.sliderContainer > input').click()

    cy.get('.sliderContainer > input').type(keyboardCommandRepeated)

    // check the value in the slider
    cy.get('.sliderContainer > span')
        .should('have.value', destiny)
})

The slider just does not move. The Cypress Documentation says about using invoke() method but I rather avoid that to see the slider being moved



Solution 1:[1]

There's a few things going on here.

The range input does not respond to Cypress' .type('{rightArrow}') but you can use cypress-real-events .realType('{rightarrow}') instead.

Note rightarrow instead of rightArrow.

Take a look at the source code, there is an onchange event handler to update the span.

<input type="range" min="0.0" max="5.0" step="0.5" value="0" onchange="showValue(this.value)">

To make the span change you need to trigger this change event.

This means you can't repeat the rightarrow, each step will need the change event to be triggered individually.

Finally, the span has text not value.

it('and a slider is displayed, the slider is moved to a specific position', () =>{
  cy.visit('https://the-internet.herokuapp.com/horizontal_slider')

  const destiny = 1
  const step = 0.5
  const initialValue = 0
  const stepsToReachDestiny = (destiny - initialValue) / step 

  cy.get('.sliderContainer > input').focus()    // use focus instead of click
  
  // loop the steps so that we can trigger change event each step
  Cypress._.times(stepsToReachDestiny, (i) => {

    const expectedAtThisStep = (i+1) * step

    cy.get('.sliderContainer > input').realType('{rightarrow}')
    cy.get('.sliderContainer > input').trigger('change')

    // check the internal value
    cy.get('.sliderContainer > input')
      .invoke('val').then(val => +val)  // get value text and convert to number
      .should('eq', expectedAtThisStep)

    // check the external span text
    cy.get('.sliderContainer > span')
      .should('have.text', expectedAtThisStep)
  })

  cy.get('.sliderContainer > span')
    .should('have.text', destiny)
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Fody