cypress-example-recipes
cypress-example-recipes copied to clipboard
Example of drag and drop to element
I think it would make sense to have a third example in the drag and drop recipe which shows how straightforward it is in Cypress to drag one element to another. A colleague of mine was trying to figure this out for a while, before I noticed that you could just use something like this:
cy.get(".drag-handle")
.trigger("mousedown", { which: 1 })
cy.get(".drag-target")
.trigger("mousemove")
.trigger("mouseup")
Drag and drop that is this straightforward to use is a massive advantage of Cypress compared to other testing frameworks, so it would make sense to have this information more readily available in the recipe for people using Cypress with a mindset from a less intuitive framework.
I wasn't sure if I that was addressed to me or a maintainer, but if it's addressed to me sure thing.
I just used this method, and it works without a hitch. Definitely should be in the guide.
Yes, this is open to be picked up by anyone to add to the docs. 🙌
I tried to make a PR here: https://github.com/cypress-io/cypress-example-recipes/pull/221
but unfortunately the test fails (no balls are dropped into the hoop)
Also, this doesn't seem to work when using react-dnd (7.0.2).
Someone posted a workaround here: https://github.com/cypress-io/cypress/issues/1752 which won't work for me either :-(
I think it would make sense to have a third example in the drag and drop recipe which shows how straightforward it is in Cypress to drag one element to another. A colleague of mine was trying to figure this out for a while, before I noticed that you could just use something like this:
cy.get(".drag-handle") .trigger("mousedown", { which: 1 }) cy.get(".drag-target") .trigger("mousemove") .trigger("mouseup")Drag and drop that is this straightforward to use is a massive advantage of Cypress compared to other testing frameworks, so it would make sense to have this information more readily available in the recipe for people using Cypress with a mindset from a less intuitive framework.
I have tried this approach with absolutely no effect whatsoever.
I have just tried it and works perfectly.. (cypress 3.2.0)
@Kadrian I'm facing the same problem, did you got any solution??
how do we drag a CSV file and drop it the application?
What worked for me is to change which : 1 to button: 0. Not sure if there is anything specific to my application (it's dependency on jQuery). Thanks to the great docs by cypress.
cy.get(`source-element-to-be-dragged`)
.trigger("mousedown", { button: 0 }); // <-- was not working when using which : 1
cy.wait(500); //not a fan of arbitrary waiting, but this is giving a smooth transition to the drag-and-drop action
cy.get(`target-element-to-drop`)
.trigger("mousemove")
.trigger('mouseleave'); // <-- have issues with mouseup. Hence using mouseleave + a dummy action below to finish the drop event.
// Important: Since mouse leave is not a complete mouse event, had to do some other dummy click to complete the drop part.
cy.get('some-other-dummy-element-outside-the-grid').click();
@fboechats, @Kadrian , @hellfireSteve I invite you to try this and let me know how it goes.
Can it done using x,y index of screen instead of target element? Just a thought, it would be more useful.
Here's my solution. Use button 0, not 1, Force every click, don't forget to click on the target element before mouseup. This will work for some not for others but I hope it helps!
cy.visit("/your-page");
cy.get("yourSelector")
.trigger("mousedown", { button: 0 }, { force: true })
.trigger("mousemove", 200, -200, { force: true })
cy.get("yourTargetForDrop").click()
.trigger("mouseup", { force: true });
These guys https://github.com/4teamwork/cypress-drag-drop literally trigger drag-n-drop stuff. The only that works for my project
@josephgroark quick question, why do you have to do this?
don't forget to click on the target element before mouseup.
It does seem necessary, but it doesn't make any intuitive sense to me because a real user wouldn't click before releasing the mouse button.
For me, doing drag and drop with react-dnd, neither this recipe or the @4tw/cypress-drag-drop plugin was working.
My case was dragging the first element of a list down two places, reordering the list. What ended up solving my case was this
cy.get(".list__first-item")
.trigger("dragstart")
.trigger("dragleave");
cy.get(".list__third-item")
.trigger("dragenter")
.trigger("dragover")
.trigger("drop")
.trigger("dragend");
Getting drag and drop to work in a test requires we reproduce the mouse events that the component is expecting.
As mentioned in https://github.com/cypress-io/cypress/issues/845, this can be quite difficult if you don't know the underlying code, and is why there isn't one solution that works for everything.
For me, the only solution that worked with an older version of jQuery UI draggable items was:
cy.get('.drag-handle')
.click()
.trigger("mousedown", { which: 1, pageX: 0, pageY: 0 });
cy.get(".drag-target")
.trigger("mousemove", 50, 0)
.trigger("mouseup");
This is my solution:
cy.get('@AssetClass')
.trigger("mousedown", { button: 0 }); // <-- was not working when using which : 1
cy.get('@dropZone')
.trigger("mousemove") // optional
.click({force: true}); // The dropzone seems to be not visible for Cypress
The .click() command is really important to use it.
My solution for a custom command with Typescript testing an Angular app, based on pravynandas post:
declare namespace Cypress {
interface Chainable {
/**
* Custom command to drag an element onto antother one
* @param targetElement The target element to drop the element on, or a selector to pick an element
*/
dragTo(targetElement: Cypress.Chainable<JQuery<HTMLElement>> | string): void;
}
}
Cypress.Commands.add(
'dragTo',
{
prevSubject: 'element',
},
function (
subject: JQuery,
targetElement: Cypress.Chainable<JQuery<HTMLElement>> | string
) {
if (typeof targetElement == 'string') {
cy.wrap(subject).should('have.attr', 'cdkdrag'); // angular specific, optional check
cy.get(targetElement).should('have.attr', 'cdkdroplist'); // angular specific, optional check
cy.wrap(subject).trigger('mousedown', { button: 0 });
cy.wait(500);
cy.get(targetElement).trigger('mousemove').trigger('mouseleave');
cy.get(targetElement).click().click();
} else {
cy.wrap(subject).should('have.attr', 'cdkdrag'); // angular specific, optional check
targetElement.should('have.attr', 'cdkdroplist'); // angular specific, optional check
cy.wrap(subject).trigger('mousedown', { button: 0 });
cy.wait(500);
targetElement.trigger('mousemove').trigger('mouseleave');
targetElement.click().click();
}
}
);
After many hours of trying combinations of the various solutions above...
I was able to find a solution for VueDraggable 2.24.3 with Cypress v7.7.0 -
cy.get('@from')
.trigger('pointerdown', { button: 0 })
.trigger('dragstart');
cy.get('@to')
.trigger('dragover')
.trigger('drop');
After many hours of trying combinations of the various solutions above...
I was able to find a solution for VueDraggable 2.24.3 with Cypress v7.7.0 -
cy.get('@from') .trigger('pointerdown', { button: 0 }) .trigger('dragstart'); cy.get('@to') .trigger('dragover') .trigger('drop');
Can confirm this works for Cypress v7.7.0 and if you are using django-admin-sortable2!
This is my solution:
cy.get('@AssetClass') .trigger("mousedown", { button: 0 }); // <-- was not working when using which : 1 cy.get('@dropZone') .trigger("mousemove") // optional .click({force: true}); // The dropzone seems to be not visible for CypressThe .click() command is really important to use it.
This one works with Material CDK drag and drop. Thanks for sharing @gfilomena 👍
.trigger('dragover') .trigger('drop')
You are a life savior!!! I can confirm this works on Vue with VueDraggableNext 2.1.1 and Cypress v12