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