Open cliren opened 8 years ago
Any update on this or has any suggested alternatives?
Checking for an update, is this going to fixed or any suggestion for alternative solution?
You can properly simulate this in shallow
renders because it does not have a DOM. But mount
ed renders actually use the dom, which then the event system kicks out the real event with real nodes.
I'm not sure if there would be a way to over-ride the values in enzyme or not. If you could take a look into it and submit a working PR that would be great.
Otherwise, I am seeing for myself that if I do this test, the currentTarget.value === input.value
e.g.,
wrapper = mount(<input value="foo" onChange={e => console.log(e.currentTarget.value)} />);
wrapper.simulate('change');
// logs `"foo"`
It's been over a year, any updates on this? I'm having the same problem.
// MyInput.js
<input onChange={(event) => {
console.log(event.currentTarget.value)} // undefined
console.log(event.target.value)} // 'foo'
}/>
In my test:
const eventObject = value => ({ currentTarget: { value }, target: { value } });
const wrapper = mount(<MyInput />);
wrapper.find('input').simulate('change', eventObject('foo'));
My current solution is to use:
wrapper.find('input').props().onChange(eventObject('foo')));
Through my limited research, this seems to be an issue related to mount
and jsdom
.
(Sorry for reviving an old thread, but this is what came up in a Google search, and I see this issue is still open.)
Edit: Relevant conversation here as well: https://github.com/airbnb/enzyme/issues/76
discovered this issue just now. was refactoring event handling code for flow type, and it wants to use current target. so now my tests that simulate change don't work anymore ☹️
This seemed to work for me:
const wrapper = mount(/*Omitted*/).find('form');
wrapper.simulate('submit', { currentTarget: wrapper.getDOMNode() });
I think this should be natively supported though.
I understand this is an old topic but just ran into this issue and I can't seem to find any clarity on it.
As I understand Enzyme uses TestUtils, so unless I'm missing something testUtils never adds the currentTarget on the 'fake event"
TestUtils ( so this 'manually' builds the SyntheticEvent )
Enzyme Adapter - this uses the above
Now went and looked at SyntheticEvent and the currentTarget isn't added there, it's added when it's 'dispatched' - I don't really understand this part that well
... Actually, I don't get it, if I do an .simulate('click', { currentTarget: { value: ''} })
this should reach my handler passed to an input element ( based on the code above ), but somehow it doesn't, value is null
I too am finding this issue. I was using event.target.value
in my <input />
change handler before, but after getting some Typescript type errors for using it and reading this post about how event.currentTarget
instead of event.target
is the actual correct value to use, I found my enzyme tests broke.
Now, when I try setting event.currentTarget
in my simulated change event, it currentTarget
doesn't get set. Like so:
const enzymeWrapper = mount(<MyComponent />);
const input = enzymeWrapper.find('.myInput');
input.simulate("change", { target: { value: "new_value" } }); // event.target is properly set in the change handler
input.simulate("change", { currentTarget: { value: "another_new_value" } }); // event.currentTarget is not set in the change handler
Don't think this is how this is supposed to behave. It does seem to work if I use shallow()
though.
I solved this by doing:
input.getDOMNode().value = "another_new_value";
input.simulate("change");
Yeah this really broke all of my tests that simulated doubleClick. The only workaround I used was to do the following (the custom method shown updates the state and is used as an event handler):
wrapper.instance().someMethodForChangingState({currentTarget:{value:"value"}});
wrapper.update();
This really needs to get fixed, it feels hackish to call the instance object.
Two years later and still no update?
A PR with a failing test case would be helpful.
In general though, I suggest never using simulate
, as it does not faithfully simulate anything. If you want to invoke a prop callback like onClick
, invoke it directly with .prop('onClick')()
.
The underlying culprit has been closed! https://github.com/facebook/react/issues/4950. Methinks the Enzyme folks should weigh-in. currentTarget
is a no-brainer MUST HAVE for simulate()
to be useful.
I don't think simulate
can ever be useful as it's currently implemented. See the immediately preceding comment.
@ljharb isn't getting into props an implementation detail though? I don't particularly want to know a lot about the component/React API, I just want to know something fired correctly when I update a value in an input element.
@antgonzales as is simulate
, as currently implemented. If enzyme had a proper "simulate event" API, then that'd be ideal - but nobody actually has that, because it would require an independent implementation of the DOM event system.
do you mean something kind of like what dom-testing-library has, but for enzyme?
@antgonzales no, because that library doesn't implement that - it just leverages the DOM. enzyme needs to work for server rendering, too, so we can't just be a thin wrapper around React and the browser.
Please suggest how to fix this scenario to simulate currentTarget object :
target.value is available in the event object as expected
currentTarget.value is NOT available in the event object as expected, currentTarget is a real dom object. Looks like jsdom is overwriting it?