reppners / ngx-drag-drop

Angular directives using the native HTML Drag And Drop API
https://reppners.github.io/ngx-drag-drop/
BSD 3-Clause "New" or "Revised" License
311 stars 121 forks source link

Automated tests don't work - Drag and Drop doesn't change status / target area is empty #80

Open maniaxmultimedia opened 4 years ago

maniaxmultimedia commented 4 years ago

Hello, thanks for DnD, my automated tests don't work, they finished with success but there are no changes in status and no reaction. I tried a few JS functions, Selenium and now I use Cypress.io framework to automate DnD but it doesn't work despite positive results of steps. There are no errors in stacktrace or console.

What can I do? Some suggestions? Thanks in advance.

// Cypress.io Framework Test
it.only('NGX Drag & Drop - Cypress.io TEST', function() {
           cy.visit('https://reppners.github.io/ngx-drag-drop/')
        cy.get('mat-card').first().trigger('dragover');
        cy.get('.my-dropzone').trigger('drop',{ force:true });       
        })
reppners commented 2 years ago

Hi! I had a hard time and no success in getting automated tests to work, yet. Last time I tried was a while ago, so tooling might has gotten way better and maybe I should give it another go.

As for advice I would try to trigger mouse events and hope that this in turn triggers the engine to emit drag events (just like a browser should do). Emitting the actual drag events should be the job of the browser/test-framework. Otherwise you need to read up on the HTML5 Drag and drop spec to exactly know when to emit which event on what element. That can be done, but that would not catch any inconsistency in between browsers (which should not exist in a perfect world and browsers are getting really close these days but still there are quirks especially in old apis like drag and drop).

tzahari commented 5 months ago

I use the official cypress plugin @4tw/cypress-drag-drop for testing drag and drop. But it does not work with npx-drag-drop The element is not moved...

Small Cypress test wich shows, that the Drag & Drop is not working:

import '@4tw/cypress-drag-drop';

describe('test npx-drap-drop', () => {

    it('Test', () => {
        cy.viewport(1024,786);
        cy.visit('https://reppners.github.io/ngx-drag-drop/');
        cy.get('#mat-tab-link-2').click();

        cy.get('div.col:eq(0) mat-list-item:eq(0) span.mdc-list-item__primary-text').should('have.text', 'Left');
        cy.get('div.col:eq(0) mat-list-item:eq(1) span.mdc-list-item__primary-text').should('have.text', 'Lefter');
        cy.get('div.col:eq(0) mat-list-item:eq(2) span.mdc-list-item__primary-text').should('have.text', 'Leftest');

        cy.get('div.col:eq(0) mat-list-item:eq(1)')
            .drag('div.col:eq(0) mat-list-item:eq(2)');

        cy.get('div.col:eq(0) mat-list-item:eq(0) span.mdc-list-item__primary-text').should('have.text', 'Left');
        cy.get('div.col:eq(0) mat-list-item:eq(1) span.mdc-list-item__primary-text').should('have.text', 'Leftest');
        cy.get('div.col:eq(0) mat-list-item:eq(2) span.mdc-list-item__primary-text').should('have.text', 'Lefter');
    });
});
aleixsuau commented 1 week ago

Hey, thanks for your library 🙏

It seems it does not work when the dndPlaceholderRef element is placed in the dndDropzone.

For example, without the dndPlaceholderRef element, the following lines work:

cy.get(dragSelector).trigger('dragstart', { force: true });
cy.get(dropSelector).trigger('drop', { force: true });

But not when it is present.

These seem to be the relevant lines (https://github.com/reppners/ngx-drag-drop/blob/26074c7e1c32477217a3fc39cd2629db50459fe4/projects/dnd/src/lib/dnd-dropzone.directive.ts#L233):

      const dropIndex = this.getPlaceholderIndex();
      // if for whatever reason the placeholder is not present in the DOM but it should be there
      // we don't allow/emit the drop event since it breaks the contract
      // seems to only happen if drag and drop is executed faster than the DOM updates
      if (dropIndex === -1) {
        return; // 
      }

dropIndex === -1 is true when the dndPlaceholderRef element is present so dndDrop does not emit and the element is not dropped.

To solve it and show the dndPlaceholderRef before dropping we need to trigger the dragover event first:

cy.get(dragSelector).trigger('dragstart', { force: true });
cy.get(dropSelector).trigger('dragover', { force: true });
cy.get(dropSelector).trigger('drop', { force: true });