React TestUtils, how can I simulate a mouseMove document?
I want to use TestUtils.Simulate.mouseMove
in document
. I have a component Dragger
that adds an event listener mouseMove
to a document
. Here's an incomplete version:
// Dragger.js
'use strict';
var React = require('react');
export default React.createClass({
propTypes: {
handleDrag: React.PropTypes.func // callback set by parent
},
getInitialState: function() {
return {dragging: false}
},
componentDidUpdate: function(props, state) {
//
if (this.state.dragging && !state.dragging) {
document.addEventListener('mousemove', this.onMouseMove)
} else if (!this.state.dragging && state.dragging) {
document.removeEventListener('mousemove', this.onMouseMove)
}
},
onMouseDown: function(e) {
this.setState({dragging: true})
},
onMouseMove: function(e) {
// Calls back to the parent with the drag
this.props.handleDrag(e);
},
render: function() {
return <div onMouseDown={this.onMouseDown} ></div>
}
});
I am using jasmine and I want my callback to be handleDrag
called after mouseDown
followed by a mouseMove
.
// Dragger.spec.js
var React = require('react/addons');
import Dragger from './Dragger';
var TestUtils = React.addons.TestUtils;
describe('Dragger', function() {
it('should call the callback after drag interaction', function() {
// make callback to spy on
var f = {callback: function(e){return}};
// render Dragger
var dragger = TestUtils.renderIntoDocument(<Dragger handleDrag={f.callback} />);
// spy on callback
spyOn(f, 'callback');
// simulate a mouseDown and mouseMove
TestUtils.Simulate.mouseDown(dragger.getDOMNode(), {button: 0});
TestUtils.Simulate.mouseMove(document);
expect(f.callback).toHaveBeenCalled(); // FAILS!
}
}
But the event mouseMove
will not be modeled correctly. I see 2 problems
- I may need to pass event data to
TestUtils.Simulate.mouseMove
. For example, the challengeTestUtils.Simulate.mouseDown(dragger.getDOMNode())
was working not until I changed it toTestUtils.Simulate.mouseDown(dragger.getDOMNode(), {button: 0})
. What event data should be passed toTestUtils.Simulate.mouseMove
? -
document
not part of the detached DOM that the test component is being passed to. This could be another reason forSimulate.mouseMove
not working. What can I use in the test insteaddocument
?
How can i use TestUtils.Simulate.mouseMove
?
source to share
After trying several different enzyme methods and TestUtils reaction, I finally came across only creating and dispatching events in pure JS that works in my joke tests like
it('calls handler on mouseDown on element, mouseMove on document', () => {
const handler = jest.fn();
const props = {
foo: {
uid: '1',
resizable: true,
},
resizeHandler,
};
const instance = mount(<Header {...props} />);
const resizer = instance.find('.resizer');
const top = window.document.documentElement; // target the documentElement
resizer.simulate('mouseDown', { preventDefault: () => true }); // uses enzyme to simulate this event, adding listener to documentElement on mousemove
const mouseMove = new Event('mousemove'); // creates a new event
top.dispatchEvent(mouseMove); // dispatches it
const mouseUp = new Event('mouseup');
top.dispatchEvent(mouseUp);
expect(resizeHandler).toBeCalled(); // the passed in handler is called on mousemove
});
Basically, you can search document.documentElement
using window.document.documentElement
and dispatch events from it like any otherselement
source to share
This is an old post, but I see that there is no post solution yet, I come across it because I am writing a similar component. I think the problem is that you are focusing on the wrong event, you should be using onDrag
drag and drop, here's an adapted version of your code that works for me:
// Dragger.js
import React from 'react';
export default React.createClass({
propTypes: {
handleDrag: React.PropTypes.func // callback set by parent
},
getInitialState: function() {
return {dragging: false}
},
onDragStart: function(e) {
// Calls back to the parent with the drag
this.setState({ dragging: true });
this.props.handleDrag(e);
},
onDragEnd: function() {
this.setState({ dragging: false });
},
render: function() {
return <div onDragStart={this.onDragStart} onDragEnd={this.onDragEnd}></div>;
}
});
and
// Dragger.spec.js
import React from 'react';
import Dragger from '../src/Dragger';
import {
renderIntoDocument,
scryRenderedDOMComponentsWithTag,
Simulate
} from 'react-addons-test-utils';
import { expect } from 'chai';
describe('Dragger', function() {
it('should call the callback after drag interaction', function() {
// spy on callback
var called = false;
// make callback to spy on
function callback() {
called = true;
};
// render Dragger
var dragger = renderIntoDocument(<Dragger handleDrag={callback} />);
// simulate a dragStart and dragEnd
const element = scryRenderedDOMComponentsWithTag(dragger, 'div')[0];
Simulate.dragStart(element);
Simulate.dragEnd(element);
expect(called).to.equal(true);
});
});
source to share