Cypress · Browser testing end to end
How do you test drag-and-drop interactions in Cypress?
Short answer
For native HTML5 drag and drop, trigger dragstart, dragover and drop with a shared dataTransfer. For pointer-based libraries, trigger mouse or pointer events, or use a drag-and-drop plugin.
Drag and drop is not a single browser event. Native HTML5 drag and drop uses dragstart, dragenter, dragover, drop and dragend, and the dataTransfer object must be shared across the sequence. Cypress's trigger dispatches synthetic events, so the test has to recreate that sequence faithfully.
cy.get("[data-cy=card]").then((card) => {
const dataTransfer = new DataTransfer();
cy.wrap(card).trigger("dragstart", { dataTransfer });
cy.get("[data-cy=done-column]")
.trigger("dragenter", { dataTransfer })
.trigger("dragover", { dataTransfer })
.trigger("drop", { dataTransfer });
cy.wrap(card).trigger("dragend", { dataTransfer });
});Match the library
- Native HTML5: dragstart, dragenter, dragover, drop and dragend
- Mouse-based libraries: mousedown, mousemove, mouseup with realistic coordinates
- Pointer-based libraries: pointerdown, pointermove, pointerup
- A plugin such as cypress-drag-drop can wrap the common native sequence
- Assert the final state, not the intermediate event count
Cypress trigger does not perform a real OS-level drag. If the library listens for coordinates or pointer capture, passing clientX and clientY or using real interaction events may be required. Read the library's event handling rather than guessing which event to fire.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1Why does drag and drop need dataTransfer shared across events?
- 2How would you test a React drag-and-drop library?
- 3When would you use a plugin instead of triggering events?
- 4What should the final assertion check?
Say it in the interview
Drag and drop depends on the library. For native HTML5 I create one DataTransfer and pass it through dragstart, dragover, drop and dragend. For pointer-based libraries I trigger the pointer sequence with coordinates or use a plugin. I always assert on the final user-visible result, such as the card appearing in the new column, rather than on the number of events fired.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Cypress mock interview and get scored feedback on depth, clarity and confidence.