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

React 15.6 input value tracking is incompatible with zombie.js #10003

Closed
Gekkio opened this issue Jun 19, 2017 · 2 comments
Closed

React 15.6 input value tracking is incompatible with zombie.js #10003

Gekkio opened this issue Jun 19, 2017 · 2 comments

Comments

@Gekkio
Copy link

Gekkio commented Jun 19, 2017

React 15.6 backports some input value handling fixes, but the new input value tracking doesn't work in zombie.js. The problem is that React wraps the .value property, and zombie.js assigns to that property in some functions (e.g. browser.fill(selector, value)) and this confuses the value tracking because it loses track of the value before the change.

It's definitely debatable whether this is a React bug or a zombie.js bug, but I find the behaviour of React a bit strange here.

Let's assume we have a controlled <input id="my-input" type="text" value={...} onChange={...} /> in React and we have a zombie.js test that fills the initially empty text field with the value "some-value".

Zombie implements browser.fill using these internal steps:

field.focus();
field.value = value;
this.fire(field, 'input', false); // fire input event
field.blur(); // blur fires change event if the value has changed since focus

Now, here's what happens if we try running our example test:

  1. The test calls browser.fill('#my-input', 'some-value');
  2. Field is focused
  3. field.value = value triggers the .value setter in react-dom inputValueTracking.js:
set: function (value) {
   currentValue = '' + value;
   descriptor.set.call(this, value);
}
  1. Tracker currentValue no longer has the original value "" and now has the new value "some-value"
  2. Input event is fired
  3. Eventually we end up in react-dom inputValueTracking.js function updateValueIfChanged
  4. The tracker compares currentValue (containing "some-value") to the raw value in the DOM node (containing "some-value") -> no change -> no event is sent -> whatever is controlling the props/state thinks the value is "" while React and the DOM node agree it's "some-value"

So, with React 15.6 we lose change events in zombie.js, but React 15.5 works fine.

@aweary
Copy link
Contributor

aweary commented Jun 19, 2017

@Gekkio thanks for taking the time to file this issue! When you have a controlled input React assumes that the only source of truth for the input value is the value prop. That is essentially what "controlled" means, controlled by React and that prop.

Settings the value property of the node on a controlled component will put the input into an inconsistent state in React, so it's not recommended. If possible, zombie.js should provide a way to update the input's value by dispatching actual events instead of setting the value property. ReactTestUtils as a simulate method that might be useful for reference.

Sorry about the breaking behavior, we try to avoid that when possible, but I think it's safe to say this pattern is unsupported. Hope that helps!

@aweary aweary closed this as completed Jun 19, 2017
@Gekkio
Copy link
Author

Gekkio commented Jun 19, 2017

Thanks for the quick response! I'll open a bug in zombie.js, and we might consider a workaround in our test code if zombie.js doesn't change their current approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants