Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is React's onChange event not fired on Selenium WebDriver's SendKeys in IE 11?

We have a relatively simple React component with an input element in it:

export class MyInput extends Component {
  componentDidMount() {
    function log(e) {
      console.log(`Event: ${e.type}, isTrusted: ${e.isTrusted}, input value: ${e.target.value}`, e);
    }

    this.rawInput.addEventListener("change", log);
    this.rawInput.addEventListener("input", log);
  }

  onChanged(e) {
    console.log("raw-input.onChanged: e.target.value", e.target.value);

    this.props.onChanged(e.target.value);
  }

  render() {
    return (
      <div className="my-class">
        <input
          value={this.props.value}
          onChange={this.onChanged.bind(this)}
          ref={(input) => { this.rawInput = input; }}
          />
      </div>
    );
  }
}

Basically, this is just a slightly wrapped input element, while the logging added on top is for debug purposes.

It handles typing just fine in regular usage, it also handles SendKeys under Selenium WebDriver in Chrome, Firefox and IE 11 (provided that WebDriver's EnableNativeEvents is true).

However, when run in Internet Explorer 11 by WebDriver and with EnableNativeEvents = false, the onChanged event is not fired when SendKeys is executed. What's most weird is that the HTML input event is fired. Below is the console output: Missing onChange under WebDriver

Notice that the input's value is changing while "test" is being typed, but there's no onChange.

Below is an expanded input event in case of WebDriver: Detailed input event from WebDriver

If a user then types via keyboard in the same input, the onChange event is there: onChange is successfully fired on real typing

Below is an expanded input event in case of user typing: Detailed input event when user is typing

Close analysis shows that the only difference in the input events is that under WebDriver isTrusted: false, while on real typing isTrusted: true.

The question is why in the first case onChange events are not fired by React?

I assume this is because React skips events with isTrusted: false because this means they are simulated, not real user events. However, I was not able to find any proof for this. If it's the case, would you mind providing a link to a post or a line in React sources that handles it?

  • React: 16.7.0
  • Selenium.WebDriver.IEDriver: 3.14.0
like image 740
Pavel Gatilov Avatar asked Apr 12 '19 14:04

Pavel Gatilov


1 Answers

When setting the nativeEvents capability to false (which is what you’re setting with the EnableNativeEvents property), you’re telling the IE driver to use JavaScript to simulate the events. Events simulated via JavaScript cannot have the isTrusted property set to true. That property is designed to detect exactly the scenario you’re experiencing. The driver implementations for Firefox and Chrome are produced and maintained by the vendors for those browsers (Mozilla and Google, respectively), and as such, those drivers have access to internals of the browser in ways that the IE driver does not (and likely never will) have. If React is indeed keying off that property to fire the onChanged event, then the proper thing to do here is set EnableNativeEvents = true.

like image 199
JimEvans Avatar answered Oct 03 '22 21:10

JimEvans