|
@@ -0,0 +1,160 @@
|
|
|
+/**
|
|
|
+ * This entire file was coppied from the following github repo: https://github.com/4teamwork/cypress-drag-drop/blob/master/index.js
|
|
|
+ *
|
|
|
+ * Full credit to the "cypress-drag-drop" package...
|
|
|
+ */
|
|
|
+
|
|
|
+const dataTransfer = new DataTransfer()
|
|
|
+
|
|
|
+function omit(object = {}, keys = []) {
|
|
|
+ return Object.entries(object).reduce((accum, [key, value]) => (key in keys ? accum : { ...accum, [key]: value }), {})
|
|
|
+}
|
|
|
+
|
|
|
+function isAttached(element) {
|
|
|
+ return !!element.closest('html')
|
|
|
+}
|
|
|
+
|
|
|
+const DragSimulator = {
|
|
|
+ MAX_TRIES: 5,
|
|
|
+ DELAY_INTERVAL_MS: 10,
|
|
|
+ counter: 0,
|
|
|
+ targetElement: null,
|
|
|
+ rectsEqual(r1, r2) {
|
|
|
+ return r1.top === r2.top && r1.right === r2.right && r1.bottom === r2.bottom && r1.left === r2.left
|
|
|
+ },
|
|
|
+ createDefaultOptions(options) {
|
|
|
+ const commonOptions = omit(options, ['source', 'target'])
|
|
|
+ const source = { ...commonOptions, ...options.source }
|
|
|
+ const target = { ...commonOptions, ...options.target }
|
|
|
+ return { source, target }
|
|
|
+ },
|
|
|
+ get dropped() {
|
|
|
+ const currentSourcePosition = this.source.getBoundingClientRect()
|
|
|
+ return !this.rectsEqual(this.initialSourcePosition, currentSourcePosition)
|
|
|
+ },
|
|
|
+ get hasTriesLeft() {
|
|
|
+ return this.counter < this.MAX_TRIES
|
|
|
+ },
|
|
|
+ set target(target) {
|
|
|
+ this.targetElement = target
|
|
|
+ },
|
|
|
+ get target() {
|
|
|
+ return cy.wrap(this.targetElement)
|
|
|
+ },
|
|
|
+ dragstart(clientPosition = {}) {
|
|
|
+ return cy
|
|
|
+ .wrap(this.source)
|
|
|
+ .trigger('pointerdown', {
|
|
|
+ which: 1,
|
|
|
+ button: 0,
|
|
|
+ ...clientPosition,
|
|
|
+ eventConstructor: 'PointerEvent',
|
|
|
+ ...this.options.source,
|
|
|
+ })
|
|
|
+ .trigger('mousedown', {
|
|
|
+ which: 1,
|
|
|
+ button: 0,
|
|
|
+ ...clientPosition,
|
|
|
+ eventConstructor: 'MouseEvent',
|
|
|
+ ...this.options.source,
|
|
|
+ })
|
|
|
+ .trigger('dragstart', { dataTransfer, eventConstructor: 'DragEvent', ...this.options.source })
|
|
|
+ },
|
|
|
+ drop(clientPosition = {}) {
|
|
|
+ return this.target
|
|
|
+ .trigger('drop', {
|
|
|
+ dataTransfer,
|
|
|
+ eventConstructor: 'DragEvent',
|
|
|
+ ...this.options.target,
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ if (isAttached(this.targetElement)) {
|
|
|
+ this.target
|
|
|
+ .trigger('mouseup', {
|
|
|
+ which: 1,
|
|
|
+ button: 0,
|
|
|
+ ...clientPosition,
|
|
|
+ eventConstructor: 'MouseEvent',
|
|
|
+ ...this.options.target,
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ if (isAttached(this.targetElement)) {
|
|
|
+ this.target.trigger('pointerup', {
|
|
|
+ which: 1,
|
|
|
+ button: 0,
|
|
|
+ ...clientPosition,
|
|
|
+ eventConstructor: 'PointerEvent',
|
|
|
+ ...this.options.target,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ dragover(clientPosition = {}) {
|
|
|
+ if (!this.counter || (!this.dropped && this.hasTriesLeft)) {
|
|
|
+ this.counter += 1
|
|
|
+ return this.target
|
|
|
+ .trigger('dragover', {
|
|
|
+ dataTransfer,
|
|
|
+ eventConstructor: 'DragEvent',
|
|
|
+ ...this.options.target,
|
|
|
+ })
|
|
|
+ .trigger('mousemove', {
|
|
|
+ ...this.options.target,
|
|
|
+ ...clientPosition,
|
|
|
+ eventConstructor: 'MouseEvent',
|
|
|
+ })
|
|
|
+ .trigger('pointermove', {
|
|
|
+ ...this.options.target,
|
|
|
+ ...clientPosition,
|
|
|
+ eventConstructor: 'PointerEvent',
|
|
|
+ })
|
|
|
+ .wait(this.DELAY_INTERVAL_MS)
|
|
|
+ .then(() => this.dragover(clientPosition))
|
|
|
+ }
|
|
|
+ if (!this.dropped) {
|
|
|
+ console.error(`Exceeded maximum tries of: ${this.MAX_TRIES}, aborting`)
|
|
|
+ return false
|
|
|
+ } else {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ },
|
|
|
+ init(source, target, options = {}) {
|
|
|
+ this.options = this.createDefaultOptions(options)
|
|
|
+ this.counter = 0
|
|
|
+ this.source = source.get(0)
|
|
|
+ this.initialSourcePosition = this.source.getBoundingClientRect()
|
|
|
+ return cy.get(target).then((targetWrapper) => {
|
|
|
+ this.target = targetWrapper.get(0)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ drag(sourceWrapper, targetSelector, options) {
|
|
|
+ this.init(sourceWrapper, targetSelector, options)
|
|
|
+ .then(() => this.dragstart())
|
|
|
+ .then(() => this.dragover())
|
|
|
+ .then((success) => {
|
|
|
+ if (success) {
|
|
|
+ return this.drop().then(() => true)
|
|
|
+ } else {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ move(sourceWrapper, options) {
|
|
|
+ const { deltaX, deltaY } = options
|
|
|
+ const { top, left } = sourceWrapper.offset()
|
|
|
+ const finalCoords = { clientX: left + deltaX, clientY: top + deltaY }
|
|
|
+ this.init(sourceWrapper, sourceWrapper, options)
|
|
|
+ .then(() => this.dragstart({ clientX: left, clientY: top }))
|
|
|
+ .then(() => this.dragover(finalCoords))
|
|
|
+ .then(() => this.drop(finalCoords))
|
|
|
+ },
|
|
|
+}
|
|
|
+
|
|
|
+function addChildCommand(name, command) {
|
|
|
+ Cypress.Commands.add(name, { prevSubject: 'element' }, (...args) => command(...args))
|
|
|
+}
|
|
|
+
|
|
|
+addChildCommand('drag', DragSimulator.drag.bind(DragSimulator))
|
|
|
+addChildCommand('move', DragSimulator.move.bind(DragSimulator))
|