Skip to content
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

Dragend event is missing #145

Open
BillyTom opened this issue Nov 15, 2023 · 1 comment
Open

Dragend event is missing #145

BillyTom opened this issue Nov 15, 2023 · 1 comment

Comments

@BillyTom
Copy link

BillyTom commented Nov 15, 2023

Probably related to #18, but I created a new issue since the other is more the two years old.

Sometimes the event "dragend" or "drop" is not emitted. This means that the drag operation is not completed successfully, but no error is emitted.

I co-opted the page simple-drag-drop.glitch.me to create a test case to reproduce the issue:

describe("reproduce missing event bug", () => {
    it("should drag-and-drop C to A", () => {
        cy.visit("https://simple-drag-drop.glitch.me/");

        const dragAndDropTargetClass = 'drop-target';
        cy.contains<HTMLElement>('C').then(element => {
            element.addClass(dragAndDropTargetClass);
            cy.log('drop target class added')
        });
        cy.get('.' + dragAndDropTargetClass);

        cy.contains('A').drag('.' + dragAndDropTargetClass);
        cy.wait(1000);

        cy.get("div[draggable=true]").then((elements) => {
            cy.wrap(elements.text()).should("be.eq", "CBA");
        });
    });
});

This test fails to re-order the elements ABC:

image

Log entry:

01 visit https://simple-drag-drop.glitch.me/
02 contains C
03 log--- drop target class added ---
04 get .drop-target
05 contains A
06 get .drop-target
07 wrap <div.box>
08 trigger pointerdown, Object{3}
09 trigger mousedown, Object{3}
10 trigger dragstart, {datatransfer: {}, eventconstructor: DragEvent}
11 wrap <div.box.drop-target>
12 trigger dragover, {datatransfer: {}, eventconstructor: DragEvent}
13 trigger mousemove, {eventconstructor: MouseEvent}
14 trigger pointermove, {eventconstructor: PointerEvent}
15 wait 10
16 wrap <div.box.drop-target>
17 trigger dragover, {datatransfer: {}, eventconstructor: DragEvent}
18 trigger mousemove, {eventconstructor: MouseEvent}
19 trigger pointermove, {eventconstructor: PointerEvent}
20 wait 10
21 wrap <div.box.drop-target>
22 trigger dragover, {datatransfer: {}, eventconstructor: DragEvent}
23 trigger mousemove, {eventconstructor: MouseEvent}
24 trigger pointermove, {eventconstructor: PointerEvent}
25 wait 10
26 wrap <div.box.drop-target>
27 trigger dragover, {datatransfer: {}, eventconstructor: DragEvent}
28 trigger mousemove, {eventconstructor: MouseEvent}
29 trigger pointermove, {eventconstructor: PointerEvent}
30 wait 10
31 wrap <div.box.drop-target>
32 trigger dragover, {datatransfer: {}, eventconstructor: DragEvent}
33 trigger mousemove, {eventconstructor: MouseEvent}
34 trigger pointermove, {eventconstructor: PointerEvent}
35 wait 10
36 wait 1000
37 get div[draggable=true]3
38 wrap ABC
39 assert expected ABC to equal **CBA**

The events "dragstart" and "dragover" are emitted, but no "dragend" or "drop".

I copied a second test from this blog post that uses drag & drop with native javascript:

/**
 * Playground test. Used for debugging.
 * See https://reflect.run/articles/testing-drag-and-drop-workflows-using-cypress/
 */
describe("native dnd spec", () => {
    it("should drag-and-drop C to A", () => {
        cy.visit("https://simple-drag-drop.glitch.me/");

        // to hold the data that is
        // dragged during a drag-and-drop operation
        const dataTransfer = new DataTransfer();

        cy
            // getting "A"
            .get("div[draggable=true]")
            .first()
            // triggering the "dragstart" event to
            // initialize the dataTransfer object
            .trigger("dragstart", { dataTransfer });

        cy
            // getting "C"
            .get("div[draggable=true]")
            .eq(2)
            // dropping "C" into the "A" position defined in dataTransfer
            .trigger("drop", { dataTransfer });

        // now "C" is in the first position, and you need
        // to retrieve it again
        cy
            // getting "C"
            .get("div[draggable=true]")
            .first()
            .trigger("dragend")
            .then(() => {
                // "A" should now be in the position of "C" and vice versa
                cy.get("div[draggable=true]").then((elements) => {
                    cy.wrap(elements.text()).should("be.eq", "CBA");
                });
            });
    });
});

This second test works:

image

@mandarkslab
Copy link

mandarkslab commented Dec 1, 2023

I'm experiencing the same on cypress 13.5.1. "dropend" event never triggers once the element has been dragged over to the target.

I'm only seeing the following:

triggerdragover, Object{5}
triggermousemove, Object{4}
triggerpointermove, Object{4}

Currently using @4tw/[email protected]

As a quick and dirty workaround, it seems to work when I force a mouse-up event after the initial drag. The only issue is that you can't then assert the success of the "drag and drop" action using its '.then((status) => {})' chained method.

e.g.:

        cy.get(elementToDrag).drag(targetDropzone, {
            target: { position: 'center' },
            force: true
        })
        // Then add the below to force the end of the action
        cy.get(targetDropzone).trigger('mouseup', { force: true })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants