cypress: Change event is not fired on number input

  • 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: https://github.com/cypress-io/cypress/issues/816 test results: image

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 5
  • Comments: 19 (5 by maintainers)

Commits related to this issue

Most upvoted comments

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

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

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

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

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