Reputation: 3433
I am struggling to test drag and drop with Cypress and Angular Material Drag and Drop. So the goal is to move "Get to work" from Todo to Done. I have created the following test, that should make it easy for you to reproduce:
You can play with the Stackblitz here.
describe('Trying to implement drag-n-drop', () => {
before(() => {
Cypress.config('baseUrl', null);
cy.viewport(1000, 600);
cy.visit('https://angular-oxkc7l-zirwfs.stackblitz.io')
.url().should('contain', 'angular')
.get('h2').should('contain', 'To do');
});
it('Should work, based on this https://stackoverflow.com/a/54119137/3694288', () => {
const dataTransfer = new DataTransfer;
cy.get('#cdk-drop-list-0 > :nth-child(1)')
.trigger('dragstart', { dataTransfer });
cy.get('#cdk-drop-list-1')
.trigger('drop', { dataTransfer });
cy.get('#cdk-drop-list-0 > :nth-child(1)')
.trigger('dragend');
cy.get('#cdk-drop-list-1').should('contain', 'Get to work');
});
it('Should work, with this library https://github.com/4teamwork/cypress-drag-drop', () => {
cy.get('#cdk-drop-list-0 > :nth-child(1)')
.drag('#cdk-drop-list-1');
cy.get('#cdk-drop-list-1').should('contain', 'Get to work');
});
});
The result from running the above test, looks like this:
Here is a repo to develop a solution.
Thanks for the help.
Events fired, found using the chrome debugger:
Item
Drop zone
Solution
After @Richard Matsen's awesome answer I ended up with adding his answer as a custom command. The solution looks like this
support/drag-support.ts
export function drag(dragSelector: string, dropSelector: string) {
// Based on this answer: https://stackoverflow.com/a/55436989/3694288
cy.get(dragSelector).should('exist')
.get(dropSelector).should('exist');
const draggable = Cypress.$(dragSelector)[0]; // Pick up this
const droppable = Cypress.$(dropSelector)[0]; // Drop over this
const coords = droppable.getBoundingClientRect();
draggable.dispatchEvent(<any>new MouseEvent('mousedown'));
draggable.dispatchEvent(<any>new MouseEvent('mousemove', {clientX: 10, clientY: 0}));
draggable.dispatchEvent(<any>new MouseEvent('mousemove', {
// I had to add (as any here --> maybe this can help solve the issue??)
clientX: coords.left + 10,
clientY: coords.top + 10 // A few extra pixels to get the ordering right
}));
draggable.dispatchEvent(new MouseEvent('mouseup'));
return cy.get(dropSelector);
}
support/commands.ts
// Add typings for the custom command
declare global {
namespace Cypress {
interface Chainable {
drag: (dragSelector: string, dropSelector: string) => Chainable;
}
}
}
// Finally add the custom command
Cypress.Commands.add('drag', drag);
in the spec file
it('🔥 Thx to Stackoverflow, drag and drop support now works 🔥', () => {
cy.drag('#cdk-drop-list-0 > :nth-child(1)', '#cdk-drop-list-1')
.should('contain', 'Get to work');
});
A small giph, because I'm just so happy it finally works 😲
CI
Now it also works in CI 🔥 (and electron locally). Tested with CircleCI 2.0.
Upvotes: 62
Views: 85965
Reputation: 93
Try to use this code for the drag and drop for the cypress.
cy.get('.red') .trigger("dragstart", { dataTransfer })
.trigger("mouseup", { force: true });
cy.get('[data-test-id="ruleEditor-react-flow-canvas"]').trigger("drop", { dataTransfer });
cy.get('#target')
.trigger("dragend", { dataTransfer })
.trigger("mousemove")
.trigger("mousedown", { which: 1 })
.trigger("mousemove", {
clientX: 800,
clientY: 400,
screenX: 800,
screenY: 400,
pageX: 800,
pageY: 400,
})
.trigger("mouseup", { force: true });
Upvotes: 0
Reputation: 1
for some reasons the drag was not working for me so tried this way around and it worked fine for me :)
export function DragAndDrop(sourceName: string, WhereToBeDraggedselector: string) {
cy.get(sourceName)
.should('be.visible')
.and('not.be.disabled')
.trigger('mousedown', { eventConstructor:'MouseEvent'})
.trigger('mousemove', { eventConstructor:'MouseEvent'})
cy.get(WhereToBeDraggedselector).trigger('mouseover', {eventConstructor: 'MouseEvent'}).click();}
Upvotes: 0
Reputation: 71
##. Cypress Mouse Drag and Drop a inside page scroller from Left, Right and Both side. Try the code below:
1. Drag and Drop from Left:
const dragLeftScoller = cy.leftGraphNavigator().first();
dragLeftScoller.trigger('mousedown', 100, 100, { force: true}).trigger('mousemove', 600, 600, { force: true });
dragLeftScoller.trigger('mouseup', { force: true });
2. Drag and Drop from Right:
const dragRightScoller =cy.rightGraphNavigator().first();
dragRightScoller.trigger('mousedown', 100, 100, { force: true }).trigger('mousemove', -30, -30, { force: true });
dragRightScoller.trigger('mouseup', { force: true });
3. Overlap -Drag and Drop from Left and Right : Increase and decrease the value of 1200 and -30 to adjust overlapping for your application:
const dragLeftScoller =cy.leftGraphNavigator().first();
dragLeftScoller.trigger('mousedown', 100, 100, { force: true }).trigger('mousemove', 1200, 1200, { force: true });
dragLeftScoller.trigger('mouseup', { force: true });
const dragRightScoller =cy.rightGraphNavigator().first();
dragRightScoller.trigger('mousedown', 100, 100, { force: true }).trigger('mousemove', -30, -30, { force: true });
dragRightScoller.trigger('mouseup', { force: true });
Upvotes: 0
Reputation: 2103
None of the listed solutions worked for me (Angular 14.1). It seems some newer versions of Angular Material CDK do not accept anymore the simulated drags that Cypress offers. This helped:
npm install --save-dev cypress-real-events
or
yarn add --dev cypress-real-events
It should be at least version 1.7.2 because of issue 234 (parameter position
was ignored).
"cypress-real-events"
to "compilerOptions"
/"types"
in cypress/tsconfig.json
, e.g.{
"compilerOptions": {
"target": "es5",
"lib": ["es6", "dom"],
"types": ["cypress", "node", "cypress-real-events"],
"esModuleInterop": true
},
"include": ["**/*.ts"]
}
cypress/support/commands.ts
:import 'cypress-real-events/support';
declare global {
namespace Cypress {
interface Chainable {
dragTo(dropSelector: string): void;
}
}
}
Cypress.Commands.add('dragTo', { prevSubject: 'element' }, function (subject, targetEl) {
/*
* Currently realMouseDown etc. only works in browsers based on Chromium.
* see https://github.com/dmtrKovalenko/cypress-real-events#requirements
*/
if (Cypress.isBrowser('firefox')) this.skip();
/*
* explicit scrollBehavior because default breaks some tests
*/
cy.wrap(subject)
.first()
.realMouseDown({ button: 'left', position: 'center', scrollBehavior: 'nearest' })
.realMouseMove(10, 0, { position: 'center', scrollBehavior: 'nearest' });
cy.get(targetEl)
.first()
.realMouseMove(10, 0, { position: 'center', scrollBehavior: 'nearest' })
.realMouseUp({ position: 'center', scrollBehavior: 'center' });
/*
* workaround for a problem where the original drag selector did work only once
*/
cy.wait(1000); // eslint-disable-line cypress/no-unnecessary-waiting
});
cy.get('#foo').dragTo('#bar')
(use whatever selectors you want)Upvotes: 1
Reputation: 1
Testing drag and drop elements sorting within a single list (Angular Material 13 + Cypress 10)
const dragDropElement =
(wrapperSelector, draggableSelector, droppableSelector) => {
// a few extra pixels to get the ordering right
const offset = 10;
const getCoords = (elem) => {
// top left coordinates with scroll
// use jQuery from Cypress
const offset = cy.$$(elem).offset();
return {
top: offset.top,
left: offset.left
};
};
// event data
const createEventData = (top = 0, left = 0, data = {}) => {
return {
bubbles: true,
cancelable: true,
composed: true,
clientX: left,
clientY: top,
screenX: left,
screenY: top,
...data
};
};
// get wrapper element (cdkdroplist)
cy.get(wrapperSelector).then(el => {
const wrapper = el[0]; // wrapper
// get draggable element (cdkdrag)
cy.get(draggableSelector).then(el => {
const draggable = el[0]; // pick up this
// get droppable element (cdkdrag)
cy.get(droppableSelector).then(el => {
const droppable = el[0]; // drop over this
// get coordinates for picked up and dropped element
const dragCoords = getCoords(draggable);
const dropCoords = getCoords(droppable);
// mouse down on picked element
draggable.dispatchEvent(new MouseEvent('mousedown',
createEventData(dragCoords.top + offset, dragCoords.left + offset, {
buttons: 1, // needed to start dragging
})
));
// small mouse move with picked element
draggable.dispatchEvent(new MouseEvent('mousemove',
createEventData(dragCoords.left + offset * 2, dragCoords.top + offset)
));
// mouse move picked element to target coordinates
draggable.dispatchEvent(new MouseEvent('mousemove',
createEventData(dropCoords.top + offset, dropCoords.left + offset)
));
// mouse up on wrapper element with dropped element coordinates
wrapper.dispatchEvent(new MouseEvent('mouseup',
createEventData(dropCoords.top + offset, dropCoords.left + offset)
));
});
});
});
};
And call this method to move for example the third element before the first:
dragDropElement(
'#cdk-drop-list-0',
'#cdk-drop-list-0 > :nth-child(3)',
'#cdk-drop-list-0 > :nth-child(1)'
);
Upvotes: 0
Reputation: 17
cy.visit("/your-page-link");
cy.get("your-Selector")
.trigger("mousedown", { button: 0 , force: true })
.trigger("mousemove", 200, -200, { force: true })
cy.get("Target-For-Drop").click()
.trigger("mouseup", { force: true });
Upvotes: 1
Reputation: 91
const dataTransfer = new DataTransfer();
cy.get('#your-item-id').trigger('dragstart', { dataTransfer });
cy.get('#your-dropable-div').trigger('drop', { dataTransfer });
Upvotes: 0
Reputation: 1
for me the code from @bkucera works, thanks for that. but I had to chance 3 things in order to works for me as expected:
1.
let _to = {
x: from.x + dx * (i),
y: from.y - dy * (i),
}
i = i+1
had to use some delay, steps and smooth:true
delay: 30,
steps: 30,
smooth: true,
Upvotes: 0
Reputation: 27
If there is not any steps involved in beween drag and drop then use below steps :
Download this for running scripts having drag and drop
npm install --save-dev @4tw/cypress-drag-drop
Go to cypress.json
"compilerOptions": {
"types": ["cypress", "@4tw/cypress-drag-drop"]
}
add this on cypress.json
Go on command.js
require('@4tw/cypress-drag-drop')
USE
cy.get('Class or id which you want to drag ').drag('Class or id where you want to drop')
Upvotes: 2
Reputation: 27
You just need to replace the class or id from where you want to drag and drop
const dataTransfer = new DataTransfer();
cy.get('ID or class which you want to drag').trigger('dragstart',{
dataTransfer
});
cy.get('ID or class where you want to drop').trigger('drop',{
dataTransfer
});
Upvotes: -1
Reputation: 11
In case anyone is also struggling with cdkDropListEntered not being triggered, you might want to check if there is any scrolling going on.
Since scrolling is handled by CDK (e.g. https://github.com/angular/components/blob/master/src/cdk/scrolling/viewport-ruler.ts#L131), I had to add the scroll position to any mouse events. The scroll position is computed like this (corresponding to above link):
const win = subject[0].ownerDocument.defaultView;
const window = win;
const document = window.document;
const documentElement = document.documentElement;
const documentRect = documentElement.getBoundingClientRect();
const top =
-documentRect.top ||
document.body.scrollTop ||
window.scrollY ||
documentElement.scrollTop ||
0;
const left =
-documentRect.left ||
document.body.scrollLeft ||
window.scrollX ||
documentElement.scrollLeft ||
0;
where subject is the result yielded e.g. by a cy.get command.
Upvotes: 1
Reputation: 18043
I've written up a small example for how to implement drag and drop.
It works by adding a dragTo
command like so:
/// <reference types="cypress"/>
it('works', () => {
cy.visit('https://angular-oxkc7l-zirwfs.stackblitz.io/')
cy.contains('To do', { timeout: 15000 }) // ensure page is loaded -__-
const item = '.example-box:not(.cdk-drag-placeholder)'
cy.get('#cdk-drop-list-1').children(item).should('have.length', 5)
cy.get('.example-box:contains("Get to work")').dragTo('.example-box:contains("Get up")')
cy.get('#cdk-drop-list-1').children(item).should('have.length', 6)
// interpolates 10 extra mousemove events on the way
cy.get('#cdk-drop-list-0').dragTo('#cdk-drop-list-1', { steps: 10 })
cy.get('#cdk-drop-list-1').children(item).should('have.length', 7)
// sets steps >= 10
cy.get('#cdk-drop-list-0').dragTo('#cdk-drop-list-1', { smooth: true })
cy.get('#cdk-drop-list-1').children(item).should('have.length', 8)
cy.get('#cdk-drop-list-0').dragTo('#cdk-drop-list-1')
cy.get('#cdk-drop-list-1').children(item).should('have.length', 9)
})
To add it, try putting this in your support/index.js
or pasting it at the bottom of a spec file (warning: poor code quality):
const getCoords = ($el) => {
const domRect = $el[0].getBoundingClientRect()
const coords = { x: domRect.left + (domRect.width / 2 || 0), y: domRect.top + (domRect.height / 2 || 0) }
return coords
}
const dragTo = (subject, to, opts) => {
opts = Cypress._.defaults(opts, {
// delay inbetween steps
delay: 0,
// interpolation between coords
steps: 0,
// >=10 steps
smooth: false,
})
if (opts.smooth) {
opts.steps = Math.max(opts.steps, 10)
}
const win = subject[0].ownerDocument.defaultView
const elFromCoords = (coords) => win.document.elementFromPoint(coords.x, coords.y)
const winMouseEvent = win.MouseEvent
const send = (type, coords, el) => {
el = el || elFromCoords(coords)
el.dispatchEvent(
new winMouseEvent(type, Object.assign({}, { clientX: coords.x, clientY: coords.y }, { bubbles: true, cancelable: true }))
)
}
const toSel = to
function drag (from, to, steps = 1) {
const fromEl = elFromCoords(from)
const _log = Cypress.log({
$el: fromEl,
name: 'drag to',
message: toSel,
})
_log.snapshot('before', { next: 'after', at: 0 })
_log.set({ coords: to })
send('mouseover', from, fromEl)
send('mousedown', from, fromEl)
cy.then(() => {
return Cypress.Promise.try(() => {
if (steps > 0) {
const dx = (to.x - from.x) / steps
const dy = (to.y - from.y) / steps
return Cypress.Promise.map(Array(steps).fill(), (v, i) => {
i = steps - 1 - i
let _to = {
x: from.x + dx * (i),
y: from.y + dy * (i),
}
send('mousemove', _to, fromEl)
return Cypress.Promise.delay(opts.delay)
}, { concurrency: 1 })
}
})
.then(() => {
send('mousemove', to, fromEl)
send('mouseover', to)
send('mousemove', to)
send('mouseup', to)
_log.snapshot('after', { at: 1 }).end()
})
})
}
const $el = subject
const fromCoords = getCoords($el)
const toCoords = getCoords(cy.$$(to))
drag(fromCoords, toCoords, opts.steps)
}
Cypress.Commands.addAll(
{ prevSubject: 'element' },
{
dragTo,
}
)
Upvotes: 17
Reputation: 653
For those who are struggling with Drag and Drop and "react-beautiful-dnd" library, here is a piece of code that helped me (nothing else did). It's extracted from this post
Cypress.Commands.add('dragAndDrop', (subject, target) => {
Cypress.log({
name: 'DRAGNDROP',
message: `Dragging element ${subject} to ${target}`,
consoleProps: () => {
return {
subject: subject,
target: target
};
}
});
const BUTTON_INDEX = 0;
const SLOPPY_CLICK_THRESHOLD = 10;
cy.get(target)
.first()
.then($target => {
let coordsDrop = $target[0].getBoundingClientRect();
cy.get(subject)
.first()
.then(subject => {
const coordsDrag = subject[0].getBoundingClientRect();
cy.wrap(subject)
.trigger('mousedown', {
button: BUTTON_INDEX,
clientX: coordsDrag.x,
clientY: coordsDrag.y,
force: true
})
.trigger('mousemove', {
button: BUTTON_INDEX,
clientX: coordsDrag.x + SLOPPY_CLICK_THRESHOLD,
clientY: coordsDrag.y,
force: true
});
cy.get('body')
.trigger('mousemove', {
button: BUTTON_INDEX,
clientX: coordsDrop.x,
clientY: coordsDrop.y,
force: true
})
.trigger('mouseup');
});
});
});
Upvotes: 0
Reputation: 617
I kept having the problem with dropevent.isPointerOverContainer always being false with the other solutions here, so instead of mouseup at the end, I had to use click(). It was the only way to get the pointer position and drag position to be in the correct location to fire the drop() event in my component.
export function drag(dragSelector: string, dropSelector: string) {
// Based on this answer: https://stackoverflow.com/questions/55361499/how-to-implement-drag-and-drop-in-cypress-test
cy.get(dragSelector).should('exist').get(dropSelector).should('exist');
const draggable = Cypress.$(dragSelector)[0]; // Pick up this
const droppable = Cypress.$(dropSelector)[0]; // Drop over this
const coords = droppable.getBoundingClientRect();
draggable.dispatchEvent(<any>new MouseEvent('mousedown'));
draggable.dispatchEvent(<any>new MouseEvent('mousemove', {clientX: 10, clientY: 0}));
draggable.dispatchEvent(<any>new MouseEvent('mousemove', {clientX: coords.left + 40, clientY: coords.top + 10}));
cy.get(dropSelector).click();
// draggable.dispatchEvent(new MouseEvent('mouseup'));
return cy.get(dropSelector);
}
// Add typings for the custom command
declare global {
namespace Cypress {
interface Chainable {
drag: (dragSelector: string, dropSelector: string) => Chainable;
}
}
}
// Finally add the custom command
Cypress.Commands.add('drag', drag);
Upvotes: 0
Reputation: 618
Try this:
it('should drag and drop the element', () => {
const myItem = cy.get('my-item').first();
myItem.trigger('mousedown', 100, 100, { force: true }).trigger('mousemove', 300, 300, { force: true });
myItem.click().trigger('mouseup', { force: true });
});
Upvotes: 1
Reputation: 54
Here's my cypress command for this:
Cypress.Commands.add(
'dragTo',
(selector: string, position: { x: number; y: number }) => {
const log = Cypress.log({
message: `Drag ${selector} to (${position.x}, ${position.y})`,
consoleProps: () => ({ selector, position })
});
log.snapshot('before');
const ret = cy
.get(selector, { log: false })
.trigger('mouseover', { force: true, log: false })
.trigger('mousedown', {
button: 0,
log: false
})
.trigger('mousemove', {
pageX: 10,
pageY: 10,
log: false
})
.then(el => {
log.snapshot('Drag start');
return el;
})
.trigger('mousemove', {
pageX: position.x,
pageY: position.y,
force: true,
log: false
})
.then(event => {
log.snapshot('Drag End');
return event;
})
.trigger('mouseup', { force: true, log: false })
.then(() => {
log.snapshot('after');
});
log.end();
return ret;
}
);
Upvotes: 1
Reputation: 20300
Not Angular specific, but should be generic and simple enough to tweak if needed.
I did try a lot of recipes out there and also cypress-file-upload
but that wouldn't work with webp for example.
The command below seems to work for most cases and reflects pretty closely what a user would do
Cypress.Commands.add('dropFile', {prevSubject: true}, (subject, fileName, fileType) => {
return cy.fixture(fileName, 'binary').then((data) => {
return Cypress.Blob.binaryStringToBlob(data, fileType).then(blob => {
const file = new File([blob], fileName, {type: fileType});
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
cy.wrap(subject)
.trigger("dragenter", {force: true})
.trigger("drop", {dataTransfer})
})
})
})
Ensure fixturesFolder
is specified in your cypress.json config file. Then you simply use like below
cy.get("#dropzone").dropFile("myfile1.webp", "image/webp")
cy.get("#dropzone").dropFile("myfile2.jpg", "image/jpeg")
Upvotes: 0
Reputation: 819
After a lot of battling, I managed to make the drag and drop work with this:
cy.get('.list .item')
.contains(startpos)
.trigger('dragstart', { dataTransfer: new DataTransfer });
cy.get('.list .item')
.eq(endpos)
.trigger('drop')
.trigger('dragend');
Pretty easy to use.
Upvotes: 8
Reputation: 23483
Dispatching MouseEvents seems to be the only way to test Angular Material drag and drop.
You should also be aware of the following issue, which tests in Protractor but also applies to this Cypress test
CDK DragDrop Regression between 7.0.0-beta.2 and 7.0.0-rc.2: Protractor tests stopped working #13642,
It seems that (for want of a better explanation) an additional nudge is needed on the mousemove.
The steps given as a workaround (Protractor syntax),
private async dragAndDrop ( $element, $destination ) {
await browser.actions().mouseMove( $element ).perform();
await browser.actions().mouseDown( $element ).perform();
await browser.actions().mouseMove( {x: 10, y: 0 } ).perform();
await browser.actions().mouseMove( $destination ).perform();
return browser.actions().mouseUp().perform();
}
can be translated into a Cypress test, the simplest form I found is
it('works (simply)', () => {
const draggable = Cypress.$('#cdk-drop-list-0 > :nth-child(1)')[0] // Pick up this
const droppable = Cypress.$('#cdk-drop-list-1 > :nth-child(4)')[0] // Drop over this
const coords = droppable.getBoundingClientRect()
draggable.dispatchEvent(new MouseEvent('mousedown'));
draggable.dispatchEvent(new MouseEvent('mousemove', {clientX: 10, clientY: 0}));
draggable.dispatchEvent(new MouseEvent('mousemove', {
clientX: coords.x+10,
clientY: coords.y+10 // A few extra pixels to get the ordering right
}));
draggable.dispatchEvent(new MouseEvent('mouseup'));
cy.get('#cdk-drop-list-1').should('contain', 'Get to work');
cy.get('#cdk-drop-list-1 > .cdk-drag').eq(3).should('contain', 'Get to work');
});
Notes
mousemove
in the Cypress test, it also fails. cy.get(..).trigger()
syntax does not seem to work with Angular, but native dispatchEvent()
does.dragstart, dragend
may not be appropriate for Angular Material, as the code shows the event received is type CdkDragDrop
rather than a DataTransfer object.Cypress.$(...)
to cy.get(...).then(el => {...})
, to take advantage of cypress' auto retry in commands.If the list is fetched by an async Angular service (httpClient) during component construction, using this in the test
const draggable = Cypress.$('#cdk-drop-list-0 > :nth-child(1)')[0]
will not work, because the nth-child will not be present immediately, only after the fetch completes.
Instead, you can use cy.get()
to provide retries up to a timeout (default 5 seconds).
cy.get('#cdk-drop-list-0 > :nth-child(1)').then(el => {
const draggable = el[0] // Pick up this
cy.get('#cdk-drop-list-1 > :nth-child(4)').then(el => {
const droppable = el[0] // Drop over this
const coords = droppable.getBoundingClientRect()
draggable.dispatchEvent(new MouseEvent('mousemove'));
draggable.dispatchEvent(new MouseEvent('mousedown'));
draggable.dispatchEvent(new MouseEvent('mousemove', {clientX: 10, clientY: 0}));
draggable.dispatchEvent(new MouseEvent('mousemove', {clientX: coords.x+10, clientY: coords.y+10}));
draggable.dispatchEvent(new MouseEvent('mouseup'));
})
cy.get('#cdk-drop-list-1').should('contain', 'Get to work');
cy.get('#cdk-drop-list-1 > .cdk-drag').eq(3).should('contain', 'Get to work');
})
or my preference is to use a 'canary' test to ensure loading is complete, something like
before(() => {
cy.get('#cdk-drop-list-0 > :nth-child(1)') // Canary - wait 5s for data
})
it('should...', () => {
const draggable = Cypress.$('#cdk-drop-list-0 > :nth-child(1)')[0] // Pick up this
const droppable = Cypress.$('#cdk-drop-list-1 > :nth-child(4)')[0] // Drop over this
...
})
Warning - this is a quick hack to get over Typescript compiler problems, and could be improved.
Cast MouseEvent
to <any>
as per MouseEvent in TypeScript error not matching signature
Type return of getBoundingClientRect()
to ClientRect
, and use properties left and top instead of x and y.
const coords: ClientRect = droppable.getBoundingClientRect()
draggable.dispatchEvent(new (<any>MouseEvent)('mousemove'));
draggable.dispatchEvent(new (<any>MouseEvent)('mousedown'));
draggable.dispatchEvent(new (<any>MouseEvent)('mousemove', {clientX: 10.0, clientY: 0.0}));
draggable.dispatchEvent(new (<any>MouseEvent)('mousemove', {clientX: coords.left + 10.0, clientY: coords.top + 10.0}));
draggable.dispatchEvent(new (<any>MouseEvent)('mouseup'));
Upvotes: 45
Reputation: 3709
Did you take a look at the official recipe that does exactly the same?
It uses this combination of triggered events
cy.get('.selector')
.trigger('mousedown', { which: 1 })
.trigger('mousemove', { clientX: 400, clientY: 500 })
.trigger('mouseup', {force: true})
to drag&drop the item, let me know if you need some more help when you have tried it 😉
Upvotes: 2