Skip to content

Instantly share code, notes, and snippets.

@superMDguy
Last active December 12, 2022 20:13
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save superMDguy/f10d29b17ef0a473fb2700f3c72661cd to your computer and use it in GitHub Desktop.
Save superMDguy/f10d29b17ef0a473fb2700f3c72661cd to your computer and use it in GitHub Desktop.
SortableJS drag and drop testing utilities for cypress
// Cypress-ized and modified version of https://github.com/kemokid/scripting-sortable/blob/master/script_sortable_dnd.js
export function triggerSortableDragAndDrop(elemDrag, elemDrop) {
/*
Summary of what events this fires:
On elemDrag:
mouseDown
dragstart
On elemDrop:
dragover (repeat until it moves)
drop
mouseup
*/
const DELAY_INTERVAL_MS = 10
const MAX_TRIES = 10
let startingDropRect
function rectsEqual(r1, r2) {
return r1.top === r2.top && r1.right === r2.right && r1.bottom === r2.bottom && r1.left === r2.left
}
// trigger dragging process on top of drop target
// We sometimes need to do this multiple times due to the vagaries of
// how Sortable manages the list re-arrangement
var counter = 0
function dragover() {
counter++
console.log('DRAGOVER #' + counter)
const currentDropRect = elemDrop.getBoundingClientRect()
if (rectsEqual(startingDropRect, currentDropRect) && counter < MAX_TRIES) {
return cy
.wrap(elemDrop)
.trigger('dragover', 'bottom')
.wait(DELAY_INTERVAL_MS)
.then(() => dragover())
} else {
if (rectsEqual(startingDropRect, currentDropRect)) {
if (counter !== 1) console.log("drop target rect hasn't changed, trying again")
return drop().then(() => {
throw new Error(`wasn't able to budge drop target after ${MAX_TRIES} tries, aborting`)
})
} else {
return drop()
}
}
}
function drop() {
console.log('DROP')
// release dragged element on top of drop target
return cy
.wrap(elemDrop)
.trigger('drop')
.trigger('mouseup', {
which: 1,
button: 0
})
}
// start dragging process
console.log('DRAGSTART')
cy
.wrap(elemDrag)
.trigger('mousedown', {
which: 1,
button: 0
})
.trigger('dragstart')
// after a delay, do the first dragover; this will run up to MAX_TRIES times
// (with a delay between each run) and finally run drop() with a delay:
return cy.wait(DELAY_INTERVAL_MS).then(() => {
startingDropRect = elemDrop.getBoundingClientRect()
return dragover()
})
}
@bierik
Copy link

bierik commented Dec 20, 2018

Thank you very much for this great script.
I did an npm package which converts it in a cypress command: https://www.npmjs.com/package/cypress-drag-drop

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment