-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Unable to simulate keyboard events #441
Comments
@DarkJoker are you using |
I've tried both after reading several posts, but i couldn't find a way to make the keydown, keypress or keyup events to work. |
@DarkJoker you can see a working example that I wrote this morning to verify the behavior: class TestComponent extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<input onKeyDown={this.props.onKeyDown} />
</div>
);
}
}
describe('Issue #441', () => {
it('It should simulate keydown events', () => {
const onKeyDown = sinon.spy();
const wrapper = mount(<TestComponent onKeyDown={onKeyDown}/>);
const input = wrapper.find('input');
input.simulate('keyDown', {keyCode: 40});
expect(onKeyDown.called).to.be.true;
}); This passes as I'd expect. If you can share a simplified reproducible case where it's not working that would be great. Feel free to fork that ^ repo to do so, if you'd like. |
Thnaks for the quick response, the component code is in the attachement, the test code is as it follows: describe("ComboBox Component", () => {
let options = [
{ "value": 0, "text": "United States" },
{ "value": 1, "text": "United Kingdom" },
{ "value": 16, "text": "Slovakia" }
];
it("it highlights option selected with keyboard on option on list", () => {
let combo = mount(
<ComboBox comboBoxElements={options}/>
);
// TestUtils.Simulate.keyDown(searchInput, { keyCode: 40 });
combo.find(".fa-chevron-down").simulate("click");
let input = combo.find("input");
input.simulate("keyDown", { keyCode: 40 });
expect(combo.find("li").at(1).prop("className")).toBe(("selectedOption selectedChildren"));
});
}); |
@DarkJoker Did you resolve this? I'm seeing a similar problem. |
No, I have been using TestUtils for this kind of tests |
@DarkJoker for |
I'll post a simplified version of the component asap only maintaining the core functionality I'm trying to test |
+1, waiting for a solution. |
@DarkJoker @springuper try this, worked for me wrapper.find('.myclass').simulate('keyDown', { key: 'ArrowLeft' }); |
For me the problem was I had added event listeners on the DOM elements themselves, and not in JSX (e.g. |
You can refer to |
It did not work for me until I used the
I can remove both |
Is it possible to simulate multiple keys, such as ctrls+s? Sorry for breaking into this discussion though :/ |
@tomitrescak that would require a keypress for |
I am having the same problem with the keyPress event. All other events can be simulated except key events on text input field |
Having the same issue here. None of the solutions above worked for me. |
@danyim @prijuly2000 if you use onChange to simulate input fields, only the last character in the string will be reflected in the keyDown event so you can use that to test keyPress So you can slice the string input and check for each last character to simulate a simulation on keyPress via keyDown events! import React, { Component } from 'react';
import { mount } from 'enzyme';
import { expect } from 'chai';
export class Issue441 extends Component {
constructor() {
super();
this.state = {
change: '',
keyDown: ''
}
this.onChangeInput = this.onChangeInput.bind(this);
this.onKeyDownInput = this.onKeyDownInput.bind(this);
}
onChangeInput(e) {
this.setState({
change: e.target.value
})
}
onKeyDownInput(e) {
this.state({
keyDown: e.keyCode
});
// to check which of the following actually works on your system
if(e.keyCode)
console.log(e.keyCode)
if(e.key)
console.log(e.key)
if(e.which)
console.log(e.which)
}
render() {
return (
<div>
<input
class='myclass'
onChange={this.onChangeInput}
onKeyDown={this.onKeyDownInput}
/>
</div>
);
}
}
describe('<Issue441/>', () => {
const wrapper = mount(<Issue441/>);
it('should simulate change', () => {
wrapper.find('input.myclass').simulate('change', { target: { value: 'xyz' } });
expect(wrapper.state('change')).to.equal.('xyz');
expect(wrapper.state('keyDown')).to.equal.('z');
});
// theoretical testing of keyPress events
const st = 'string';
for(let i in st) {
it('should theoretical simulate keyPress', () => {
wrapper.find('input.myclass').simulate('change', { target: { value: st.slice(0, i += 1) } });
expect(wrapper.state('change')).to.equal.(st.slice(0, i += 1));
expect(wrapper.state('keyDown')).to.equal.(st[i]);
});
}
}) NOTE
|
It's counter intuitive that for testing a |
@EduardoAC the example is to mock testing of |
@aweary I managed to get it working on mount by using
However, the same example using
@pranjalk Honestly I don't know where to start to comment your post even if you example achieve the question asked. Personally, it's over engineer from my point of view because you are storing the event on the Otherwise, you should target examples like "Brandon dail" propose, but replacing |
I believe this is true. The |
Hello guys, thanks for the enzyme! here is some problem what I try to describe. I got battleship game, as side project where I report bugs and try things. if I remove it here: [as it doesn't work to be honest, as we need observer 'document level'] test fails do I'm doing something wrong? or how I could emulate 'document level' events? I presume because react's events are syntetic, it is impossible? |
I was attempting to simulate a ArrowDown keydown event on an @pranjalk your solution worked for me with Enzyme 3. Thanks! |
i found that if the events attached by so my suggested solution is to simulate the event manually by
|
Considering that you can trust the HTML event to raise the OnClick or OnChange even when requested, this is all unnecessary. Just call the OnChange prop of the React element. |
I sure wish you could trigger a This is one of the hairiest accessibility problems I've come across in React testing. I've tried every relevant trick I could come up with, and I'm having to concede and write keyboard compatibility tests in Selenium Webdriver instead. Even Simulant doesn't seem to trigger event callbacks in this scenario, I suspect because of the way SyntheticEvent is delegating events through the DOM tree rather than on a specific button node. |
@marcysutton I think our team is going to have to start using syntax like this to make it clear: function handler(event) {
const evt = event.nativeEvent || event // works for React events
const key = evt.code || evt.which // prefers non deprecated api
...
} It may be worth it to remove |
|
When working with events created by class AwInput extends Component {
inputElement = null;
componentDidMount() {
const node = this.inputElement;
// using some third-party library to manipulate the DOM node.
node.addEventListener("blur", innerEventHandler);
node.addEventListener("keydown", innerEventHandler);
}
render() {
const props = this.props;
return (
<inputWrapper
id={props.id}
value={props.value}
onChange={props.onChange}
innerRef={(el) => (this.inputElement = el)}
/>
);
}
}
function innerEventHandler (event) {
// simulate() never reaches this point
console.log('innerEventHandler:', event);
} And writing the unit test for that component with Enzyme... describe('Testing <AwInput />', () => {
const ctx = { value: 'testing' };
const onChange = jest.fn((e) => (ctx.value = e.target.value));
const Wrapper = mount(
<AwInput
id="awInput"
value={ctx.value}
onChange={onChange}
/>
);
const inputElement = Wrapper.find('#awInput').last();
it('Should render input element without any error', () => {
expect(inputElement.exists()).toBe(true); // success
expect(inputElement).toHaveLength(1); // success
});
it('Should call the mock onChange function', () => {
const value = 'new value';
inputElement.simulate('change', { target: { value } }); // success
expect(onChange).toHaveBeenCalled();
expect(ctx.value).toBe(value);
});
it('Should call the inner keyDown function', () => {
inputElement.simulate('keyDown', { key: 'a', keyCode: 97 }); // fail
// expected: console.log('innerEventHandler:', event);
});
}); So, as mentioned before, it seems the Using ReactTestUtils.Simulate is not working as expected neither :( BTW, it's worth mentioning the Enzyme Future Work. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Is it posible to simulate shift + enter? |
@leon0707 the |
Problem
I'm truing to simulate keyboard events with enzyme but I couldn't find a single line of documentation or code example where keyboard events are implemented. I've tried using
and
I've also tried using other types of casing on the event name and key names but nothing worked.
While there's no error using any of the two examples I've mentioned the output just isn't the expected and using
TestUtils.Simulate.keyDown(searchInput, { keyCode: 40 });
all works as expected.Am I not using the correct syntax?
The text was updated successfully, but these errors were encountered: