Cypress - 拖放不适用于基于反应的网站

mlr*_*uez 9 javascript drag-and-drop reactjs cypress

我正在与 Cypress 进行斗争,以实现基于反应的网站上的任何拖放操作。Cypress 仪表板中的操作不会失败,但项目根本不会被拖动。

我拥有的是一组 div,它们是“在菜单中”的页面列表(因此它们对用户可见),另一组 div 是“不在菜单中”(因此它们对用户不可见) )。我想要做的是将“不在菜单中”页面移至“在菜单中”部分。

这些是网站中的元素:

“可拖动”项目:

<div data-testid='pages-section-not-in-menu-list' data-rbd-droppable-id="notInMenu" data-rbd-droppable-context-id="0" class="draggable-place">
    <div class="page1">Page1</div>
    <div class="page2">Page2</div>
    <div class="page3">Page3</div>
</div>
Run Code Online (Sandbox Code Playgroud)

“可放置”区域:

<div data-testid='pages-section-in-menu-list' data-rbd-droppable-id="inMenu" data-rbd-droppable-context-id="0" class="droppable-place">
</div>
Run Code Online (Sandbox Code Playgroud)

我的代码:

public dragAndDropPagesToInMenu(): void {

        const dataTransfer = new DataTransfer();
        cy.wait(3000);
        cy.log("Dragging one page to `In Menu` section");
        cy.get("div[class='page3']")
            .first()
            .trigger('dragstart', { dataTransfer });
        cy.get("div[data-testid='pages-section-in-menu-list']")
            .eq(0)
            .trigger('drop', { dataTransfer });
        cy.get("div[class='page3']")
            .last()
            .trigger('dragend');

    }
Run Code Online (Sandbox Code Playgroud)

我还尝试了以下解决方案,但到目前为止没有一个有效:

有任何想法吗?

ran*_*tao 3

为了简化@Agustin Catalano的答案,您可以将自定义命令作为子命令,通过将{ prevSubject: "element" }第二个参数传递给Cypress.Commands.add,如下所示:

// cypress/support/commands.ts

declare global {
    namespace Cypress {
        interface Chainable {
            /** Custom command to drag subject to target */
            drag(target: string, options?: Partial<TypeOptions>): Chainable<Element>

        }
    }
}


/** Adds custom command `cy.drag` to the global `cy` object  */
Cypress.Commands.add("drag", { prevSubject: "element" }, (
  subject: Cypress.JQueryWithSelector<HTMLElement>, 
  target: string, 
  _options?: Partial<Cypress.TypeOptions>
) => {
    const BUTTON_INDEX = 0;
    const SLOPPY_CLICK_THRESHOLD = 10;

    cy.get(target)
        .first()
        .then($target => {
            let coordsDrop = $target[0].getBoundingClientRect();

            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");
        });
});
Run Code Online (Sandbox Code Playgroud)

这样,您只需在查询链中指定主题的选择器一次:

cy.get("subject").drag("target")
Run Code Online (Sandbox Code Playgroud)