javascript Cypress -拖放在基于React的网站上不起作用

ctrmrzij  于 2023-05-27  发布在  Java
关注(0)|答案(3)|浏览(155)

我正在努力与赛普拉斯的任何拖放行动的React为基础的网站。Cypress Jmeter 板中的操作不会失败,但项目不会被拖动。
我有一组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>

“可丢弃”区域:

<div data-testid='pages-section-in-menu-list' data-rbd-droppable-id="inMenu" data-rbd-droppable-context-id="0" class="droppable-place">
</div>

我的代码:

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');

    }

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

有什么想法吗

dy1byipe

dy1byipe1#

我遇到了同样的问题,我找到了这个解决方案。希望对你有用:

  • 将以下代码添加到cypress/support/commands.js文件中
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');
                });
        });
});
  • 那么你可以在测试中这样做
describe('example to drag & drop in react web app', () => {
 it('drag & drop', () => {
   cy.visit(
     'https://react-beautiful-dnd.netlify.app/iframe.html?id=single-vertical-list--basic'
   )
   cy.get('[data-rbd-draggable-id="1"]').dragAndDrop(
     '[data-rbd-draggable-id="1"]',
     '[data-rbd-draggable-id="4"]'
   )
 })
})
2lpgd968

2lpgd9682#

下面是对我有效的方法,请注意dropdragend之间的小等待。这一部分非常重要:

cy.get('element to be dragged').trigger('dragstart');
cy.get('target where we will drop the element')
  .trigger('dragenter', { force: true })
  .trigger('dragover', { force: true })
  .trigger('drop', { force: true })
  .wait(50)
  .trigger('dragend', { force: true });

我不得不使用力,因为我拖动的元素在几毫秒内不可见。导致扳机动作失败,所以加力就能解决。

goqiplq2

goqiplq23#

为了简化@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");
        });
});

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

cy.get("subject").drag("target")

相关问题