'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 |
