Bug
Change event is not fired on "number" type inputs after .type() nor .click() or .focus() to other element.
It works fine with "text" input types
Change event should fire with number input just like with text input type
https://stackblitz.com/edit/react-byhe3e?file=index.js
import React, { Component } from 'react';
import { render } from 'react-dom';
class App extends Component {
state = {
inputTextValue: '',
inputNumberValue: ''
};
handleTextChange = (event) => {
this.setState({
inputTextValue: event.currentTarget.value,
});
}
handleNumberChange = (event) => {
this.setState({
inputNumberValue: event.currentTarget.value,
});
}
render() {
return (
<div>
<div>
Input text: {this.state.inputTextValue} <br/>
<input id="textInput" onChange={this.handleTextChange } value={this.state.inputTextValue} type="text" /> <br/><br/>
</div>
<div>
Input number: {this.state.inputNumberValue} <br/>
<input id="numberInput" onChange={this.handleNumberChange } value={this.state.inputNumberValue} type="number" />
</div>
</div>
);
}
}
render(<App />, document.getElementById('root'));
Test code:
describe("Change event bug repro", function() {
it("Should fire change on textInput", function() {
cy.visit("https://react-byhe3e.stackblitz.io");
cy
.get("#textInput")
.type("hello")
.should("have.value", "hello");
cy.get("#inputTextValue").contains("hello");
});
it("Should fire change on numberInput entering integers", function() {
cy
.get("#numberInput")
.type("1234.56")
.should("have.value", "1234");
cy.get("#inputNumberValue").contains("1234.56");
});
it("Should fire change on numberInput entering decimals", function() {
cy
.get("#numberInput")
.type("1234.56")
.should("have.value", "1234.56");
cy.get("#inputNumberValue").contains("1234.56");
});
});
related issue: https://github.com/cypress-io/cypress/issues/816
test results:
Appreciate you putting together a detailed bug report. We'll look at this.
I accidentally found what's going on.
The event isn't triggered when I pass string to type(), if I pass number then events are firing.
Although the behaviour is weird and works different than browser when passing string even if it contains only numbers
UPDATE: @GavinThompson is right, events are not triggered when the value contains a decimal point. I've updated the test case to demonstrate the issue
Just to piggyback on this really detailed bug, I'm actually encountering the same bug with number fields and change events not firing. Specifically however I believe it's only happening when the input contains a decimal (at least in our case).
If I use the following command cy.get('#price').type('9122')
and log the changes I can watch the following logs scroll by in Cypress:
Price change output on number field: 9
Price change output on number field: 91
Price change output on number field: 912
Price change output on number field: 9122
When I change the command to include a decimal -- cy.get('#price').type('9122.99')
I get the following:
Price change output on number field: undefined
Price change output on number field: undefined
Price change output on number field: ....etc
This works with or without single quotes around the number in question.
I'd like to add that we are having this same issue, but for <input type="date" />
fields, even when typing the date with the Date Input format noted in the cypress docs: "YYYY-MM-DD".
@mjfaga I think I'm experimenting the same issue with <input type="date" />
. Have you been able to find a workaround by chance?
Date input value is being cleared in the DOM despite a should('have.value')
assertion is successful. I can only reproduce this issue when filling form in cypress - I'm still trying to figure out if this is a cypress bug, or somewhere down in my app. Will reply if I find a workaround/fix.
@jbmusso I can reproduce this by running the following in my console...
const datePicker = document.querySelector('input[type="date"]');
datePicker.value = "2015-01-01";
...and then clicking the submit button on my form manually.
From the research I've done, it comes down to that fact that doing what I note above doesn't trigger the react life cycle events, so the react change event is never fired, and therefore, the field doesn't technically have a value as a result.
I can get things working when using ReactTestUtils.Simulate.change(datePicker);
in a debug session, but I haven't found a way to hook that up properly in cypress to get things to execute properly.
That is as far as I've gotten thus far. No work around yet.
Thanks for sharing. Our app is a single page app (React).
As a quick-n-dirty workaround, I fixed my Cypress test suite by casting the input to a type="text"
:
cy
.get('input[name="birthDate"]')
.type('1970-06-15')
.should('have.value', '1970-06-15') // Failed assertion
// Workaround, cast to "type"
cy
.get('input[name="birthDate"]')
.invoke('attr', 'type', 'text')
.should('have.value', '1970-06-15') // Successful assertion
It looks like that the change event now fires, which triggers form validation (use case: form validation using mobx-react-form
).
Also, wrapped up:
cy
.get('input[name="birthDate"]')
.invoke('attr', 'type', 'text') // Cast
.type('1970-06-15')
.should('have.value', '1970-06-15') // Successful assertion
In my situaion,
cy.get('input').type('10.0001').trigger('blur');
I set something for input#onBlur, but seems input#onChange didn't work when with decimals
This issue will be fixed in PR #2016 along with many other cy.type()
improvements
It seems that the issue still occurs on the current version
type: "number"
pattern: "^([0-9]{6})$"
Removing both accepts the values.
@ervicsangel are you saying using the pattern
attribute will not lead to desired behavior? or any number
input?
@ervicsangel are you saying using the
pattern
attribute will not lead to desired behavior? or anynumber
input?
The scenarios are:
The test data provided is merely '222222'
UPDATE: I just found out that it does not work when using mat-form-field. I tried rerunning it against a simple input box and it worked; changing it back to mat-form-field (textbox), the issue recurred.
Cheers
@ervicsangel can you provide a reproducible example using the mat-form-field
element? What library is that component from? Possibly just link us to the demo of the component if it's in documentation somewhere
I think it was because the maxLength
was not explicitly set. As I did so, it worked not just using Cypress but also in IE. I think that's enough for now, thanks.
Cheers
Thank you. I was getting frustrated with my decimals not typing in and just by upgrading I got past it..
I'd like to add that we are having this same issue, but for
<input type="date" />
fields, even when typing the date with the Date Input format noted in the cypress docs: "YYYY-MM-DD".
I have the issue that in browser the input field is
<input type="date">
but when Cypress is running browser the input field is
<input type="text">
Why is it?
I'm using Cypress with the following versions (installed yesterday):
Cypress package version: 3.5.0
Cypress binary version: 3.5.0
Using .type('yyyy-mm-dd')
on an input type=date does not fire React's onChange event.
Worked around by manually triggering by calling .trigger('change')
This issue will be closed to further comment as the exact issue here was resolved and tested.
If you're experiencing a bug similar to this in Cypress, please open a new issue with a fully reproducible example that we can run. There may be a specific edge case with the issue that we need more detail to fix.
Most helpful comment
Thanks for sharing. Our app is a single page app (React).
As a quick-n-dirty workaround, I fixed my Cypress test suite by casting the input to a
type="text"
:It looks like that the change event now fires, which triggers form validation (use case: form validation using
mobx-react-form
).Also, wrapped up: