question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Simulate drag and drop

See original GitHub issue

We have some a custom drag-n-drop multi select form control in our project and we’ve added a small helper to simulate drag and drop events (we found the code posted somewhere and we tweaked it a bit). Our project is using React DnD but I believe that the helper would apply to any generic html5 DnD implementation.

I wonder whether this is something that would be useful to add and maintain here.

Relevant code or config


const fireMouseEvent = function (
    type: string,
    elem: EventTarget,
    centerX: number,
    centerY: number
) {
    const evt = document.createEvent('MouseEvents');
    evt.initMouseEvent(
        type,
        true,
        true,
        window,
        1,
        1,
        1,
        centerX,
        centerY,
        false,
        false,
        false,
        false,
        0,
        elem
    );
    return elem.dispatchEvent(evt);
};

export const dragAndDrop = (elemDrag: HTMLElement, elemDrop: HTMLElement) => {
    act(() => {
        // calculate positions
        let pos = elemDrag.getBoundingClientRect();
        const center1X = Math.floor((pos.left + pos.right) / 2);
        const center1Y = Math.floor((pos.top + pos.bottom) / 2);

        pos = elemDrop.getBoundingClientRect();
        const center2X = Math.floor((pos.left + pos.right) / 2);
        const center2Y = Math.floor((pos.top + pos.bottom) / 2);

        // mouse over dragged element and mousedown
        fireMouseEvent('mousemove', elemDrag, center1X, center1Y);
        fireMouseEvent('mouseenter', elemDrag, center1X, center1Y);
        fireMouseEvent('mouseover', elemDrag, center1X, center1Y);
        fireMouseEvent('mousedown', elemDrag, center1X, center1Y);

        // start dragging process over to drop target
        const dragStarted = fireMouseEvent(
            'dragstart',
            elemDrag,
            center1X,
            center1Y
        );
        if (!dragStarted) {
            return;
        }

        fireMouseEvent('drag', elemDrag, center1X, center1Y);
        fireMouseEvent('mousemove', elemDrag, center1X, center1Y);
        fireMouseEvent('drag', elemDrag, center2X, center2Y);
        fireMouseEvent('mousemove', elemDrop, center2X, center2Y);

        // trigger dragging process on top of drop target
        fireMouseEvent('mouseenter', elemDrop, center2X, center2Y);
        fireMouseEvent('dragenter', elemDrop, center2X, center2Y);
        fireMouseEvent('mouseover', elemDrop, center2X, center2Y);
        fireMouseEvent('dragover', elemDrop, center2X, center2Y);

        // release dragged element on top of drop target
        fireMouseEvent('drop', elemDrop, center2X, center2Y);
        fireMouseEvent('dragend', elemDrag, center2X, center2Y);
        fireMouseEvent('mouseup', elemDrag, center2X, center2Y);
    });
};

// example usage
dragAndDrop(screen.getByText('text of item to drag'), screen.getByLabelText('label of area to drop'));

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:14
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

12reactions
kentcdoddscommented, Sep 1, 2020

Yeah, for this kind of thing I think that Cypress is the place to go. Simulating drag-and-drop in an environment which does not support layout like jsdom (which is where most people use user-event) would be very tricky to get legit confidence from.

2reactions
kentcdoddscommented, Nov 14, 2020

That’s a: “I don’t think I would use it, but some people like yourself and others who use user-event in a real browser might. This means I’ll accept a pull request for it, but I won’t maintain it.” 😅

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to simulate HTML5 Drag and Drop events in javascript?
Your best bet is to recreate a fake event object. In my unit tests for a drag-and-drop file upload library (Droplit, shameless plug),...
Read more >
Create the `simulateDragDrop` function which can be used ...
Create the `simulateDragDrop` function which can be used to simulate clicking and dragging one DOM Node onto another - native_js_drag_and_drop_helper.js.
Read more >
Simulate Drag and Drop
Simulate Drag and Drop. If you want to simulate a draggable window, that will be easy: just check the "Draggable" option for the...
Read more >
39 How To Test HTML5 Drag and Drop
As a workaround we can simulate dragging and dropping by executing JavaScript with Selenium. Let's dig in with an example.
Read more >
Simulate Drag and Drop with JavaScript and CasperJS
Our function is essentially just triggering a long sequence of mouse and drag events to simulate the same events that are triggered when ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found