0

I've tried the solution provided here: How to implement drag and drop in cypress test? and have made more progress than when trying to use the cypress drag drop plugin, but have still not managed to get it to work properly.

Here is my code:

static dragMemberToDragDropList(memberName: string, dragDropListIndex: number): void {
    cy.get('[autotestid="draws_draggable_member"]').contains(memberName).then(member => {
        const draggable = member[0];
        cy.get('[autotestid="draws_dragdrop_list"]').eq(dragDropListIndex).then(list => {
            
            const coordinates = list[0].getBoundingClientRect();
            draggable.dispatchEvent(new MouseEvent('mousedown'));
            draggable.dispatchEvent(new MouseEvent('mousemove', {clientX: 10, clientY: 0}));
            draggable.dispatchEvent(new MouseEvent('mousemove', {clientX: coordinates.left+10, clientY: coordinates.top+10}));
            draggable.dispatchEvent(new MouseEvent('mouseup'));
            
            cy.wait(500);
        });
    });
}

The problem I've got is that even though the coordinates seem to be correct the element is dragged to the wrong place. In the image below A is where it's being dragged from, C is where I want it to go and B is where it ends up... enter image description here

I'm not sure if this is significant, but when I comment out the "mouseup" event so that when the test has completed I can see where the element ends up, and if I then move the mouse across the screen the element moves across the screen too. The bit that I think might be significant is that the element is some distance away from the mouse and when moving that exact distance and position between the two is maintained. The image below shows the relative positions (M is the mouse pointer):

enter image description here

I would have thought that the element would be in the same position as the pointer?

This issue is slowly driving me insane so any advice or suggestions would be appreciated!

P.S. I have also tried this:

it('drag drop test', () => {
    cy.visit('https://material.angular.io/cdk/drag-drop/examples#cdk-drag-drop-enter-predicate');

    cy.get('cdk-drag-drop-enter-predicate-example')
        .find('.example-box').contains('2').then(number => {
        const draggable = number[0];
        cy.get('cdk-drag-drop-enter-predicate-example')
            .find('#even').then(list => {
            
            const coordinates = list[0].getBoundingClientRect();
            draggable.dispatchEvent(new MouseEvent('mousedown'));
            draggable.dispatchEvent(new MouseEvent('mousemove', {clientX: 10, clientY: 0}));
            draggable.dispatchEvent(new MouseEvent('mousemove', {clientX: coordinates.left + 10, clientY: coordinates.top + 10}));
            draggable.dispatchEvent(new MouseEvent('mouseup'));
            
            cy.wait(500);
        });
    });
});

...but can't get that to work either.

MountainShack
  • 41
  • 1
  • 1
  • 6
  • Your test code works ok with the Angular 11 example [here](https://material.angular.io/cdk/drag-drop/examples#cdk-drag-drop-enter-predicate). Do you have a repo, or add the Angular code? –  Feb 20 '21 at 22:42
  • Thanks for the quick response @SteveZodiac. Great idea to try the test against the angular material site, interestingly I haven't been able to get it to work there either. I've added my test to the bottom of my issue description above, does this look correct? Does it work for you? Chances are that I'm doing something stupid, but would love to know what. – MountainShack Feb 21 '21 at 18:41
  • Yes, definitely something intriguing there! In my test I downloaded the one specific example from the StackBlitz link (top right) and ran it locally. That worked ok. Now going to the demo page directly as you did, it does not work with the default viewport (lists stacked vertically) but add `cy.viewport(1500,1000)` to get them side-by-side and it works again. –  Feb 21 '21 at 20:24
  • Also my local build stops working with stacked lists (`cy.viewport(800,660)`) so something is not right with the coordinates but I can't pick what it is. –  Feb 21 '21 at 20:38
  • Well I've come up with some sort of solution. I wasn't taking into consideration the height of the toolbar which I am doing now, seems to work. Although the whole thing feels a bit flaky as I have had to include a couple of cy.waits to get it to work. Thanks for your help Steve. – MountainShack Feb 22 '21 at 19:45
  • A conclusions I came to was the clientX, clientY values are relative to the element receiving the mousemove event, ie. draggable, so I changed `coordinates.left + 10` to deltaX where `const deltaX = droppableCoords.left - draggableCoords.left;` and similar for deltaY. That got exact positioning of `draggable` over `droppable` (i.e the RH list) during the test. –  Feb 23 '21 at 01:29
  • ***Except*** for when the viewport is too small for all the elements to be in view, then the `mousemove` event seems to cancel if the move takes it outside the viewport (just a theory, working on confirmation via docs). –  Feb 23 '21 at 01:32
  • I've ran into this same issue in the past couple days. Your solution fixes the visual, but then drop method doesn't fire for me. If I use the original coordinates, the drop event fires, but like you experienced, the visual element gets dragged way out of where it should. Even though the drop event gets fired, the dropevent.isPointerOverContainer is false for this situation and since I need to check for that, it's not a solution for me. I think I need to create a StackBlitz for this and report it to the CDK team. – Ulfius Mar 19 '21 at 20:46

0 Answers0