browser.fill is not compatible with React 15.6 controlled input components
React 15.6 introduces some changes to input event handling, and browser.fill in zombie.js is incompatible with all React controlled inputs. The problem is that browser.fill sets the value directly using the DOM API:
// Switch focus to field, change value and emit the input event (HTML5)
field.focus();
field.value = value; // <--------- Danger! Might not be the raw DOM property
this.fire(field, 'input', false);
// Switch focus out of field, if value changed, this will emit change event
field.blur();
React 15.6 wraps the .value property in input fields using Object.defineProperty, and zombie.js ends up calling the setter defined by React, not the original DOM setter defined by jsdom. Here's the relevant closed React bug: https://github.com/facebook/react/issues/10003
While React could maybe do things differently, zombie.js is wrong here because a real browser doesn't call a custom .value property setter when you input text into a field. Zombie could use jsdom_patches.js to install some custom mechanism for private use to directly set the underlying property without invoking any possible custom property wrappers.
If we generalize a bit, Zombie.js shouldn't even use .value to read the property. With React it doesn't cause any issues, but some other framework or library could have a getter with side-effects. But to fix this main incompatibility it would be enough to handle the .value setter case.
As a quick and dirty patch example, we can replace this:
field.value = value;
with this:
var descriptor = Object.getOwnPropertyDescriptor(field.constructor.prototype, 'value');
descriptor.set.call(field, value);
It works because we use the original constructor's property setter, ignoring any special stuff in the instance's property. In a proper patch this method would need to be used for all .value and .checked accesses and descriptors should probably be cached. And yes, it's unfortunately complicated and makes the code uglier :man_shrugging:
Guys, this issue is fixed, we should close this.