It is interesting, that such standard behaviour in such a standard component is so hard to test.
Given an IonRange element in my Ionic React component:
<IonRange
min={0}
max={30}
onIonInput={()=> console.log("changed")}
/>
When I manually test the IonRange, I get the console output as expected.
However, when I have my cypress test like this (pretty much copied over from the docs):
cy.get("ion-range")
.as('range')
.invoke('val', 10)
.trigger('change')
I expect to see the log statement in the output.
Actual behaviour: the range knob jumps to the expected position but the onIonInout
callback is never invoked.
I also tried other triggers, such as
.trigger('ion-change')
.trigger('input')
.trigger('ion-input')
.trigger('range-change')
.trigger('ionChange')
.trigger('ionInput')
all leading to the same behaviour.
I also tried to workaround using arrow keys.
That would be a very unsatisfying solution, because it does not generalise for cases with ranges of, say, 0 to 10,000. I tried it anyway:
cy.get("ion-range").type('{rightArrow}') // trows "this is a non-typable element"
The range knob jumps to the centre (weirdly).
The workaround that I ended up with is:
cy.get("ion-range").click() // clicks in the centre
(also mentioned by @SuchAnIgnorantThingToDo-UKR)
and then I expect the value 15. But due to differences in rendering resolutions (even with a set viewport), the result flakes between 15 and 16. Also, this solution is very unsatisfying given we might want to assert for specific values)
I reviewed the following:
- This article is not helpful since I’m already using a plain number
- And this is kinda related but a different special case
Please let me know if you have any idea for this very trivial every-day problem.
2
Answers
The
.click()
command will alter the value and trigger the event handler, however it’s not as precise as setting the value directly.from
The IonRange seems to have a different internal mechanism to the two linked examples you cited.
Those have an
<input>
underlying, but IonRange does not have one. Instead, it’s a stencil based web component which responds the events in it’s own particular way.The range knob jumps to the centre (weirdly)
I got the same with
.click()
but not specifying the coordinates to click at. I think that’s because the.type()
has a.click()
built in.The default click position, if not specified, is the center of the element.
@SuchAnIgnorantThingToDo-UKR already answered in great detail.
I just want to add how to test the dragging. You can do this: