Reputation: 12966
I have a lot of components in my application that respond to different key presses, and so far, none of my tests that use TestUtils.Simulate.keyDown
work at all. It seems like keyDown
just plain and simple does not work.
Here's the component I'm trying to test:
var React = require('react/addons');
var Description = React.createClass({
render : function () {
return (
<div className="description">
<input type="text" ref="input"/>
</div>
)
}
});
module.exports = Description;
And here is a simple test that is failing:
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var expect = require('expect');
var Description = require('../description');
describe('Description', function () {
it('updates input value on key press', function () {
var description = TestUtils.renderIntoDocument(<Description/>);
var input = React.findDOMNode(description.refs.input);
expect(input.value).toEqual(''); //This passes
TestUtils.Simulate.keyDown(input, {key : "a"});
expect(input.value).toEqual('a'); //This fails
});
});
I have multiple tests that rely on TestUtils.Simulate.keyDown
. These tests try a multitude of different keys to press (with Enter being the most prominent), but none of them work. I've tried using keyPress
and keyUp
, not knowing if those functions even exist at all (shoutout to the surprisingly incomplete documentation).
Am I just using the function incorrectly? Or is there something else wrong here?
I'm using karma-cli via npm to run my tests, if that makes a difference.
Upvotes: 9
Views: 8657
Reputation: 150
Just for the record, I had a very similar problem from a SearchInput component that send the text introduced when hitting enter. I had some tests as follows:
describe('SearchInput functionality,', () => {
let mockData, component, input;
beforeAll(() => {
mockData = {
searchCriteria: "something",
emptyString: " ",
submitHandler: function(filter) {
// storing filter param in mockData, it means SearchInput called handler successfully
mockData.filter = filter;
}
};
spyOn(mockData, 'submitHandler').and.callThrough();
component = ReactTestUtils.renderIntoDocument(
<SearchInput placeholder="Search..." onSubmit={mockData.submitHandler}/>
);
input = ReactTestUtils.findRenderedDOMComponentWithTag(component, 'input');
});
it('user writes a search criteria and hits enter', () => {
input.value = mockData.searchCriteria;
ReactTestUtils.Simulate.change(input);
ReactTestUtils.Simulate.keyDown(input, {key: "Enter", keyCode: 13, which: 13});
expect(mockData.filter).toEqual(mockData.searchCriteria);
expect(mockData.submitHandler).toHaveBeenCalled();
expect(mockData.submitHandler).toHaveBeenCalledTimes(1);
});
});
And it didn't work.
But after some research I changed the keyDown by keyPress and everything worked perfectly. The reason, enter key was never actually pressed, then input value was never sent and all the assertions failed.
Upvotes: 0
Reputation: 12966
I ended up figuring out the issue.
TestUtils.Simulate.keyDown(input, {key : "a"});
This line sends an event to the correct DOM node, but the event data doesn't actually contain a keyCode
, which is what the code is looking for. Why the official documentation specifically says you should use key
is beyond me.
For it to function correctly, the following modification needed to be made:
TestUtils.Simulate.keyDown(input, {keyCode : 65});
I hope this helps out someone else with a similar issue.
Upvotes: 10
Reputation: 13200
TestUtils.Simulate
does not actually change values, but rather simulates events on the targeted elements. So if you had an onKeyDown
handler on your input
, simulating keyDown
with TestUtils
would let you see if that handler works correctly.
To change the value of the input
you can try changing it directly with this.refs.input.value = 'a'
, or simulate a change event if you have an onChange
handler that you want to test:
TestUtils.Simulate.change(input, { target: { value: 'a' } })
Upvotes: 3