Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change event is not fired on number input #1171

Closed
szerintedmi opened this issue Jan 9, 2018 · 19 comments · Fixed by #2016
Closed

Change event is not fired on number input #1171

szerintedmi opened this issue Jan 9, 2018 · 19 comments · Fixed by #2016
Assignees
Labels
pkg/driver This is due to an issue in the packages/driver directory type: bug
Milestone

Comments

@szerintedmi
Copy link

szerintedmi commented Jan 9, 2018

  • Operating System: MacOs
  • Cypress Version: 1.4.1
  • Browser Version: Chrome 63 & Electron 53
  • React: 16.2.0

Is this a Feature or Bug?

Bug

Current behavior:

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

Desired behavior:

Change event should fire with number input just like with text input type

How to reproduce:

https://stackblitz.com/edit/react-byhe3e?file=index.js

App code:

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");
    });
});

Additional Info (images, stack traces, etc):

related issue: #816
test results:
image

@brian-mann
Copy link
Member

Appreciate you putting together a detailed bug report. We'll look at this.

@jennifer-shehane jennifer-shehane added the stage: needs investigating Someone from Cypress needs to look at this label Jan 9, 2018
@szerintedmi
Copy link
Author

szerintedmi commented Jan 12, 2018

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

@GavinThompson
Copy link

GavinThompson commented Jan 12, 2018

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.

@mjfaga
Copy link

mjfaga commented Jan 26, 2018

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".

@jbmusso
Copy link

jbmusso commented Feb 7, 2018

@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.

@mjfaga
Copy link

mjfaga commented Feb 7, 2018

@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.

@jbmusso
Copy link

jbmusso commented Feb 8, 2018

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

@vagusX
Copy link

vagusX commented Jun 23, 2018

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

@kuceb
Copy link
Contributor

kuceb commented Jul 16, 2018

This issue will be fixed in PR #2016 along with many other cy.type() improvements

@kuceb kuceb added this to the 3.0.3 milestone Jul 16, 2018
@kuceb kuceb added pkg/driver This is due to an issue in the packages/driver directory type: bug and removed stage: needs investigating Someone from Cypress needs to look at this labels Jul 16, 2018
brian-mann pushed a commit that referenced this issue Jul 23, 2018
this grew to a large PR fixing many cy.type issues.

fix #365
fix #420
fix #586 
fix #593 
fix #596 
fix #610 
fix #651
fix #940
fix #1002 
fix #1108
fix #1171
fix #1209 
fix #1234 
fix #1366
fix #1381 
fix #1684 
fix #1686
fix #1926 
fix #2056
fix #2096 
fix #2110 
fix #2173
fix #2187
@jennifer-shehane jennifer-shehane added stage: pending release and removed stage: needs review The PR code is done & tested, needs review stage: needs investigating Someone from Cypress needs to look at this stage: in progress labels Jul 23, 2018
@ervicsangel
Copy link

It seems that the issue still occurs on the current version

type: "number"
pattern: "^([0-9]{6})$"

Removing both accepts the values.

@kuceb
Copy link
Contributor

kuceb commented Jan 7, 2019

@ervicsangel are you saying using the pattern attribute will not lead to desired behavior? or any number input?

@ervicsangel
Copy link

ervicsangel commented Jan 8, 2019

@ervicsangel are you saying using the pattern attribute will not lead to desired behavior? or any number input?

The scenarios are:

  • Using the pattern I mentioned earlier: No input was accepted in the UI but it was logged in the commands panel
  • Assigning the type as number: Ditto
  • Using pattern and assigning the type as number: Ditto
  • Removing both: Input was typed

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

@kuceb
Copy link
Contributor

kuceb commented Jan 8, 2019

@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

@ervicsangel
Copy link

ervicsangel commented Jan 9, 2019

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

@maccurt
Copy link

maccurt commented Jan 21, 2019

Thank you. I was getting frustrated with my decimals not typing in and just by upgrading I got past it..

@SergeiTsarikTR
Copy link

SergeiTsarikTR commented Sep 13, 2019

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?

@sgronblo
Copy link

sgronblo commented Nov 1, 2019

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.

@sgronblo
Copy link

sgronblo commented Nov 1, 2019

Worked around by manually triggering by calling .trigger('change')

@jennifer-shehane
Copy link
Member

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.

@cypress-io cypress-io locked as resolved and limited conversation to collaborators Dec 24, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
pkg/driver This is due to an issue in the packages/driver directory type: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.