Giter Site home page Giter Site logo

cypress-drag-drop's People

Contributors

bierik avatar brunocavalcante avatar ccheraa avatar christian-kolb avatar dependabot[bot] avatar dmaicher avatar fpagnoux avatar jonkoops avatar lvonlanthen avatar megos avatar rabbiveesh avatar samelawrence avatar sauloxd avatar thezoker avatar timvee avatar yokomotod avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cypress-drag-drop's Issues

Uncaught TypeError: Cannot read property 'types' of undefined

I am getting the following error when the dragstart method is called

image

Uncaught TypeError: Cannot read property 'types' of undefined

This error originated from your application code, not from Cypress.

When Cypress detects uncaught errors originating from your application it will automatically fail the current test.

This behavior is configurable, and you can choose to turn this off by listening to the 'uncaught:exception' event.

https://on.cypress.io/uncaught-exception-from-application

I have the require('cypress-drag-drop) in my command.js file. I am not sure how else to debug this error. Thoughts? I am using Cypress 3.2 and Chrome version 73.

MouseEvent construction failed due to "undefined" for clientX/Y passed to dragstart, dragover and drop

My test code:

cy.get(`[abc="val"]`)..drag(`#def`, {
    position: "center",
    force: true,
  })

Drag and drop failed in Chrome (Version 89.0.4389.114 (Official Build) (x86_64))

Analysis:
I made to print clientX/Y on dragstart, dragover and drop calls:

dragstart({ clientX, clientY } = {}) {
    cy.log("dragstart", clientX+', '+clientY)
    return cy
      .wrap(this.source)
      .trigger('pointerdown', {
        which: 1,
        button: 0,
        clientX,
        clientY,
        eventConstructor: 'PointerEvent',
        ...this.options,
      })
      .trigger('mousedown', {
        which: 1,
        button: 0,
        clientX,
        clientY,
        eventConstructor: 'MouseEvent',
        ...this.options,
      })
      .trigger('dragstart', { dataTransfer, eventConstructor: 'DragEvent', ...this.options })
  },

As shown below, "undefined" were passed.
Screen Shot 2021-04-13 at 10 39 30 AM

It appears MouseEvent constructor doesn't allow undefined coordinator values. And drag-and-drop failed. The valid clientX/Y need to be passed.

Workaround:

  • Simply comment out clientX/Y.

allow cy.xpath to be the source

please allow cy.xpath to be the source

//step cy.xpath(openBalanceInactiveColumnHandle).drag(amountsActiveColumnHandle);

// error Syntax error, unrecognized expression: //div[contains(./@id, "active__field-row") and text() = ' openBalance, totalDue '];

This element is not visible because of parent

Hi,

I am trying to use drag and drop in tests but it fails:
image

I added {force: true} to all triggers but the error still occurs. Where should I add {force: true} to disable error checking?

Element detached from the DOM when "mouseup" is triggered

I am seeing issues with "mouseup" when trying to execute multiple tests together. In my scenario i have 2 Columns and wanted to drag and drop components 2 different columns or in same column (either way). 1st test passed during 2nd test it failed while executing "mouseup". I can see the component has been added in Column but trigger event has failed.

Can you please suggest why running multiple tests same time failed? What changes we need to do?

image

image

Code Snippet

it(' "Button" Component added to Canvas', () => {
  cy.get('[data-cy-test="sidebar-library-basic"] [data-cy-test="button"]')
    .drag(`${Column_1}`);
  cy.get('button.toolbar__save-button').click();
  cy.get('#f-root-content button').should('be.visible');
});

it(' "streetAutocomplete" Component added to Canvas', () => {
  cy.get('[data-cy-test="sidebar-library-components"] [data-cy-test="streetAutocomplete"]')
    .drag(`${Column_2}`);
  cy.get('button.toolbar__save-button').click();
  cy.get('#f-root-content div label')
    .should('have.class', 'nexus-label--has-textfield');
});

Update TS types

AFAIK drag command is returning a Chainable<true> too, I just tested it by running

cy.wrap('.source')
          .drag(`.target`)
          .should(() => {
            // This works, you can create assertions here
          });

Also, the second definition generic parameter isn't actually used and can be removed

This

drag<K extends keyof HTMLElementTagNameMap>(targetSelector: K, options?: Options): true
drag<E extends Node = HTMLElement>(targetSelector: string, options?: Options): true
drag(targetAlias: string, options?: Options): true

should become

    drag<K extends keyof HTMLElementTagNameMap>(targetSelector: K, options?: Options): Chainable<true>
    drag(targetSelectorOrAlias: string, options?: Options): Chainable<true>

Even better if

.then(() => true)

Is updated to return sourceWrapper variable, so the return type of drag command would be Chainable<Element> as move does


On another note, adding import '@4tw/cypress-drag-drop' already instruct TS to pick up this package types, you don't need to tamper with tsconfig.json at all

all .drag command stop working on version 2.1.0

Hey guys, I've updated using yarn to version 2.1.0 and the .drag command stop working. I change it back to version 2.0.0 and it is working again.

I couldn't check what's wrong with the new version, but hope this issue warns other people.

dragenter, dragleave not emitted

Issue description

When executing a test of dnd, the plugin fails to emit dragenter and dragleave events, limiting related functionality to conditional logic with state awareness in a dragover handler. This is particularly annoying when modifying styles amongst several potential drop targets.

Steps to reproduce the issue

  1. Attach a dragenter or dragleave event handler to the drag target element
  2. Implement recognizable functionality in the handlers such as console logging or css class additions
  3. Execute dnd test

What's the expected result?

  • The handler functionality should be determined to have executed, e.g., a class is present on a target element, or a console message has been logged by the handler function

What's the actual result?

  • There is no evidence of function execution

Updating to the latest trigger api

It looks like the

.drag($draggedTo, {
  target: { position: 'bottomLeft' },
});

does not work currently as the code eg: here has to be adapted to the latest trigger api as in here

A sample fix would look like

this.target
      .trigger('drop', this.options.target.position, {
        dataTransfer,
        eventConstructor: 'DragEvent',
      })

I would be interested in solving this issue with your help if that works.
Also alongside, the target is typed wrong, as currently its as defined below

type Options = Partial<Cypress.ClickOptions & {
source: Cypress.ClickOptions
target: Cypress.ClickOptions
}>

dragend event is not emitted

Hello,

I face some difficulties using this plugin since it is not emitting the dragend event after the drop event is executed.
I have some code that is using the dragend event and therefore my tests are not properly working. Is there any reasons why it is not part of current implementation or will you consider adding ?

Thanks,

Thibault

feat : drag using pixels

you have done a good job , but i wish if the position was in pixels , i mean if we have a syntaxe like this

describe('Dragtest', () => {
  it('should dragndrop', () => {
    cy.visit('/yourpage');
    cy.get('.sourceitem').drag({bottom:'10px',left:'200px'});
  });
});

Can not install with cypress 7.0 or above

I get this error when running
npm install --save-dev @4tw/cypress-drag-drop

Could not resolve dependency:
npm ERR! peer cypress@"^2.1.0 || ^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" from @4tw/[email protected]

Looks like the update was made but not published

as of 7/20/2021
cypress is now on version 8!

Coordinates can be passed into drag function but are ignored

If you review the documentation for the trigger command, the options that can be passed in include coordinates from the top, left corner of the subject element where the pointer/mouse is located when the down/up/move/etc action is performed.
https://docs.cypress.io/api/commands/trigger.html#Coordinates

The drag being called on the row in the relative location of the drag handle:
cy.get(studyAct.studyactmillercontainer) // container for all of the rows in the miller column .should('be.visible') .find(studyAct.studyactmillerrow) // gets a list of all of the rows in the container .then($rows => { cy.wrap($rows).last().as('there') // alias for the last row in the list of rows cy.wrap($rows) .contains(studyAct.studyactmillerrow, 'Adverse Events') // gets a specific row based on the label text .focus() // 28, 18 is the relative location of the center of the reorder-icon that is the handle used to trigger the drag for the row element; it must be clicked to drag the row element. when using the .find('.reorder-icon') for the .drag command, the parent row is not moved .drag('@there', 28, 18, { force: true }) .wait('@graphql') // this request is not triggered cy.get('.v-progress-linear.loader').should('not.be.visible') })
image

The drag being called on the drag handle:
cy.get(studyAct.studyactmillercontainer) .should('be.visible') .find(studyAct.studyactmillerrow) .then($rows => { cy.wrap($rows).filter(':visible').last().as('there') cy.wrap($rows) .contains(studyAct.studyactmillerrow, 'Adverse Events') .focus() .find('.reorder-icon') .drag('@there', { force: true }) .wait('@graphql') cy.get('.v-progress-linear.loader').should('not.be.visible') })

image

There should be an object, and documentation on the use of the object. for passing in x,y coordinates for the trigger commands to use on triggering mouse/pointer ON a location. There should also be a separate object for use in moving TO a specific location.

elements found but no action was performed

I read about the commits that you made about the force : true, but still even though the elements were being found, no action was performed, they remained where they were....

Support for cypress 9.0?

Great project.
Are you planning to support Cypress 9? I'm downgrading by now just because I love this library.

npm ERR! Found: [email protected]
npm ERR! node_modules/cypress
npm ERR! dev cypress@"^9.0.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer cypress@"^2.1.0 || ^3.1.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" from @4tw/[email protected]

.drag() does not appear to work on elements selected from an array using .eq(), .first() and .last()

The project I am testing is using Vue Draggable - which may be the issue, as I know others have had problems getting drag and drop with Cypress to work reliably with that module.

To keep it simple I'll show you the line of code that is working and one that isn't:

Working code:
cy.get('.tools-drag-panel:nth-child(${startElement})').drag('.tools-drag-panel:nth-child(${targetElement})')

Broken code:
cy.get('.tools-drag-panel div').eq(startElement-1).drag('.tools-drag-panel:nth-child(${targetElement})')

In both of these example startElement and targetElement are in a list of draggable elements which are being referred to by their numbered position, e.g. 'Drag the element in position 4 to position 8'

Similarly if the eq() methods are replaced with .first() or .last() to get the first or last element the selector might refer to, drag and drop do not work either. In the above examples eq, first and last were used as the get() method was returning an array of elements.

cy.get(...).move is not a function

I can use cy.get(...).drag but not cy.get(...).move, am i missing something ?
I use it like this :

cy.get(".titleBlock").move("center");

how to use it

i wish if there were docs that explain to us how to setup this lib with cypress

Element could've already been detached from the DOM when "mouseup" is triggered

Trying to add a test for an app which uses react-dnd and in my case drop target node is removed from the DOM after the drop event is triggered.

At the time mouseup is triggered the node is no longer in the DOM and cypress returns an error.

CypressError: cy.trigger() failed because this element is detached from the DOM.

As I understand some implementations of DnD could listen for the drop event, some - for mouseup event and some for both.

According to the cypress docs on conditional testing we can not implement a condition logic to checks if drop target node still exists in the DOM before triggering mouseup because it has been removed from the DOM asynchronously.

Can we update the command so it accepts another parameter dropEvents (with default value ["drop"]) so a user can define specific event(s) to trigger?

On a separate note, not sure we need it to be an array.

If the proposed solution looks reasonable I can create a PR.

Full error:

CypressError: cy.trigger() failed because this element is detached from the DOM.

<div class="EmptyBlock_block__2auyt" data-cy="empty-block-placeholder" draggable="true"></div>

Cypress requires elements to be attached in the DOM to interact with them.

The previous command that ran was:

  > cy.trigger()

This DOM element likely became detached somewhere between the previous and current command.

Common situations why this happens:
  - Your JS framework re-rendered asynchronously
  - Your app code reacted to an event firing and removed the element

You typically need to re-query for the element or add 'guards' which delay Cypress from running new commands.

https://on.cypress.io/element-has-detached-from-dom

All 3 subject validations failed on this subject.

No dragend event on source

https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#dragend

Once the drag is complete, a dragend event is fired at the source of the drag (the same element that received the dragstart event
...
After the dragend event has finished propagating, the drag and drop operation is complete.

So after this.target.drop

drop({ clientX, clientY } = {}) {
return this.target.trigger('drop', { dataTransfer, force: this.force, position: this.position }).then(() => {

should be this.source.trigger('dragend', with screenX and screenY of drop

Allow drag from a position within the element

We have elements that are sensitive to where the mouse down occurs within the element. It would be nice to do the mouse down with more control (pixel offset, or position as in the drag input).

Dragging a non-DOM element?

What about dragging a non-DOM element, for example a dot drawn on the canvas? Same events, mousedown at a particular point, mousemove, mouseup, however no DOM element.

Clone mode does not take effect.

I want to copy the left column to the right, but it doesn't take effect. If only the left column is sorted, it is fine.

https://codesandbox.io/embed/strange-lovelace-8296e?fontsize=14&hidenavigation=1&theme=dark

import React, { useState } from 'react';
import { ReactSortable } from 'react-sortablejs';

export default () => {
  const [list1, setList1] = useState([
    { id: 1, name: '11' },
    { id: 2, name: '22' },
  ]);
  const [list2, setList2] = useState([
    { id: 3, name: '33' },
    { id: 4, name: '44' },
  ]);
  return (
    <div style={{ display: 'flex' }}>
      <ReactSortable
        list={list1}
        setList={setList1}
        animation={150}
        group={{ name: 'cloning-group-name', pull: 'clone' }}
      >
        {list1.map(item => (
          <div key={item.id}>{item.name}</div>
        ))}
      </ReactSortable>{' '}
      <ReactSortable
        list={list2}
        setList={setList2}
        animation={150}
        group={{ name: 'cloning-group-name', pull: 'clone' }}
      >
        {list2.map(item => (
          <div key={item.id}>{item.name}</div>
        ))}
      </ReactSortable>
    </div>
  );
};

This is OK:

cy.contains('22').then(test => {
      cy.contains('11').drag(test);
    });

This is not OK:

cy.contains('33').then(test => {
      cy.contains('11').drag(test);
    });

bounding box for selecting features in open layers map

I've been trying for 2 days to get cypress to do pointer down, moves, and up in order to simulate a user selecting multiple items on an open layers map. I was hoping this would be the silver bullet but I'm guessing true drag/drop needs to deliver a payload to the drop zone where as my situation does not.

Do you have any thoughts on how DragSimulator could be modified to do a "simple" bounding box technique?

Add index.d.ts

For TS users it will be useful. Now, if you use Cypress with TS you'll get this error:

Property 'drag' does not exist on type 'Chainable<JQuery<HTMLAnchorElement>>'

Cannot read property 'getBoundingClientRect' of undefined

I am getting below error :

TypeError: Cannot read property 'getBoundingClientRect' of undefined
      at Context.drag (https://www.seleniumeasy.com/__cypress/tests?p=src/support/index.ts:355:28)

The test is as simple as

    cy.visit('https://www.seleniumeasy.com/test/drag-and-drop-demo.html');
    cy.get('#todrag>span:nth-child(2)').drag('#mydropzone');

I have installed the node module and have added import '@4tw/cypress-drag-drop' in command.ts file.

index.js

I have made a change in index.js

if (isAttached(this.targetElement)) {
this.target
.trigger('mouseup', {
force: true, //i have added this line
which: 1,
button: 0,

but it is not reflecting in run time

How to use this library with typescript

My commands.ts is a typescript file.

When I add the line require('cypress-drag-drop');, I get this error:

Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i @types/node` and then add `node` to the types field in your tsconfig.ts(2580)

How can I solve this problem?

How can I use this with iframe?

Currently, I'm using this plug-in and it works fine, if there's no iframe.

Consider that my drag and drop elements are inside an iframe, then how can I use it, please guide me here.
@bierik
Thank you.

index.js:107 Exceeded maximum tries of: 5, aborting

I have a table of rows, I want to drag the first one and and drop it below all the others.

I have the following code

  cy.get('.search__table .search__table-row:first-child .drag-row')
    .move({ y: 500 });

When this code is executed, the drag-now element's ondragstart is fired. After that, the element is being dragged and moving on top of the final line, which fires ondragover event. This event does nothing, it just prevent's the default event from happening, which allows me to drop items on top of the row. It also has ondragenter event listener, which saves the location of the current drag'n drop process. In the end, the ondragend event of the .drag-now element is expected to fired.

However, the dragging fails mysteriously:

Exceeded maximum tries of: 5, aborting
dragover	@	index.js:107

EDIT: I'm not sure if this is the reason but I noticed that the library does not trigger ondragenter event at all.

cy.get(...).move(...) not working

Hi,

I tried the new child command move.

Nevertheless, this command is not effective.

Have you a hint on why the command is not working ?

Capture d’écran 2020-06-04 à 14 16 06

source code :

describe("Separator Test", function(){
    it("should pass", function(){
        cy.visit('http://localhost:8080');
        cy.get('div.separator').as('separator');
        cy.get('@separator').move({ x: 100, y: 100 }, {force:true})
    })
})

My goal is to move the vertical separator between the two panes 100px to the right.

Dragover event never triggered

Sometimes, this plugin never triggers an actual drag. I can't quite pinpoint the cause for this, but it seems to happen to me on a component which resizes when its dragged.

In any case, I looked through the code, and noticed that there's no assurance that the dragover event is ever called. I saw that this is b/c the dragover code is recursively called. However, as in my case, you may hit a stopping condition before even trying to dragover.

I wrote #47 to address this issue.

How wait for drop target to appear

Hi there,

Thanks so much for creating this awesome library. I'm currently struggling to do some basic drag and dropping and would really appreciate it if someone could point me in the right direction.

I simply want to drag an element to a target destination. However, the issue is the target destination is not rendered on the screen until the dragging begins. Therefore I get an error when doing cy.get('#myDragElement').drag('#target') that the target element could not be found.

Is there any way within this library that I can trigger the drag event and wait for the element to appear on the screen before dropping it? What's the best way to handle this? Thanks!

Dragula and drag and drop testing.

Hello everyone!

I use a lib dragula in my project and I'm trying to test it by cypress-drag-drop but it doesn't work.

Could you help me with it, how to make it works?

Thanks!

Idea for drag and dropping fixtures

Is it possible to add an implementation of a drag and drop function for fixtures (files/images/etc)?
Because right now it's available only for elements (due to README)

Implementation like:

const fileName = 'fileName.png';
cy.fixture(`${fileName}`).then(
      picture => {
        picture.drop('.photo-dropzone');
      })
);

In free time I can try to do PR with function

Drag and drop is not working on Cypress 9.1.0

I am using drag and drop on my project where in cypress version 8.4 drag and drop was working but when I updated it 9.1.0 it stopped working.
Can you please help me with it?

Thank You.

mouseenter event is not emitted

Issue description

To enable dragging, an element must have a draggable attribute set to true. It is possible to set this attribute in a mouseenter handler (alongside other functions such as css changes.) Perhaps due to the lack of support for hover functionality in Cypress, this plugin does not emit mouseenter, forcing changes to code to enable dnd tests.

Steps to reproduce the issue

  1. Attach a mouseenter handler to an undraggable element
  2. in the handler, set the draggable attribute of the element to true
  3. Set this element as dnd test source
  4. Dnd test will fail

What's the expected result?

  • source element becomes draggable, is dragged successfully, unicorns, and rainbows.

What's the actual result?

  • source element is not dragged, causing test to fail

Additional details / screenshot

I was able to substitute my logic in mousedown and mouseup handlers temporarily, and successfully tested as such. However this is an insufficient solution, and serves more to illustrate the limitation of this plugin rather than a suitable alternative.

encountered an error post drag and drop is complete

Hi team,

Please find the below code snippet where I'm trying to achieve drag and drop and getting an error on Test runner console.

Code Snippet:

it('using npm package', () => {

    cy.visit(`https://testautomationpractice.blogspot.com/`)
    cy.get('div#draggable').drag('div#droppable')

});

Error:

Timed out retrying after 10000ms: cy.trigger() failed because this element:

...

is being covered by another element:

...

Fix this problem, or use {force: true} to disable error checking.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.