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 challenge TestUtils.Simulate.mouseDown(dragger.getDOMNode())

    was working not until I changed it to TestUtils.Simulate.mouseDown(dragger.getDOMNode(), {button: 0})

    . What event data should be passed to TestUtils.Simulate.mouseMove

    ?
  • document

    not part of the detached DOM that the test component is being passed to. This could be another reason for Simulate.mouseMove

    not working. What can I use in the test instead document

    ?

How can i use TestUtils.Simulate.mouseMove

?

+3


source to share


2 answers


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

+1


source


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);
    });
});

      

0


source







All Articles