【问题标题】:playwright drag and drop剧作家拖放
【发布时间】:2021-02-19 10:34:34
【问题描述】:

尝试测试一些拖放功能,好像剧作家没有拖放功能,所以我使用mouse.move()mouse.down()mouse.up()

尽管我的尝试似乎失败了,但目标并没有被移动。代码如下:

test("drag and drop test", async () => {
  await page.goto("https://www.w3schools.com/html/html5_draganddrop.asp");
  await page.waitForSelector("#accept-choices");
  await page.click("#accept-choices");
  await page.waitForSelector("#div1");
  let xStart, yStart, xFinish, yFinish, elementHandle, rect;
  elementHandle = await page.$("#div1");
  rect = await elementHandle.boundingBox();
  xStart = rect.x + rect.width / 2;
  yStart = rect.y + rect.height / 2;
  elementHandle = await page.$("#div2");
  rect = await elementHandle.boundingBox();
  xFinish = rect.x + rect.width / 2;
  yFinish = rect.y + rect.height / 2;
  console.log(`move from (${xStart}, ${yStart}) to (${xFinish},${yFinish})`);
  await page.screenshot({ path: "before drag.png" });
  await page.mouse.move(xStart, yStart);
  await page.mouse.down();
  await page.mouse.move(xFinish, yFinish);
  await page.mouse.up();
  await page.screenshot({ path: "after drag.png" });
});

【问题讨论】:

标签: node.js drag-and-drop playwright


【解决方案1】:

我也一直在纠结如何让剧作家drag and drop 成为可能。

例如,我需要垂直移动,

重新排序之前 1 2 3

重新排序后 2 1 3

    const exampleOneDrag = await page.$(
      `[data-testid="${exampleOne}-drag-icon-button"]`
    )
    const exampleTwoDrag = await page.$(
      `[data-testid="${exampleTwo}-drag-icon-button"]`
    )
    const oneBoundingBox = await exampleOneDrag?.boundingBox()
    const twoBoundingBox = await exampleTwoDrag?.boundingBox()

    if (oneBoundingBox && twoBoundingBox) {
      await page.mouse.move(
        oneBoundingBox.x + oneBoundingBox.width / 2,
        oneBoundingBox.y + oneBoundingBox.height / 2,
        { steps: 5 }
      )
      await page.mouse.down()
      await page.mouse.move(
        twoBoundingBox.x + twoBoundingBox.width / 2,
        twoBoundingBox.y + twoBoundingBox.height / 2,
        { steps: 5 }
      )
      await page.mouse.up()
    }

能够做到这一点的关键是steps:5 选项。我不完全确定它的作用,但我从这里找到了:https://github.com/codeceptjs/CodeceptJS/blob/e815d82af028e904051b5b6c70873164e1df1bfd/lib/helper/Playwright.js#L2289-L2307e

希望这对你有用。我认为你的情况,你应该这样改变

  await page.mouse.move(xStart, xFinish);
  await page.mouse.down();
  await page.mouse.move(yStart, yFinish);

【讨论】:

  • 感谢您的回答,即使定义了step 选项,我也无法让我的示例正常工作,您有工作示例可以分享吗?您是否能够在代码中进行拖放以垂直移动?
  • @user3770935 当然,我发现step 将路径从起点到终点分成多个步骤,并执行许多较小的动作。首先,我建议增加步长(我们从 5 增加到 15)。如果您看到它正在重新排序但未应用,可能完成任务太快了,所以我在await page.mouse.up() 之后添加了await page.waitForTimeout(4000)。希望对您的情况有所帮助。
  • 看起来像是一个众所周知的问题,HTML5 拖动事件不是由鼠标移动触发的。看到这个线程:github.com/puppeteer/puppeteer/issues/1376@hardkoded 评论,在这里看到github.com/puppeteer/puppeteer/issues/… 似乎我们需要dispatchEvent
【解决方案2】:

1.13.0 版为此添加了 API 方法。查看documentation
复制自文档:

page.dragAndDrop(source, target[, options])

  • 来源:string
  • 目标:string
  • 选项:Object
    • force boolean 是否绕过可操作性检查。默认为 false。
    • noWaitAfter boolean 启动导航的操作正在等待这些导航发生并等待页面启动 加载。您可以通过设置此标志来选择退出等待。你会 仅在特殊情况下才需要此选项,例如导航到 无法访问的页面。默认为 false。
    • timeout number 最大时间以毫秒为单位,默认为 30 秒,传递 0 禁用超时。默认值可以更改 通过使用browserContext.setDefaultTimeout(timeout)page.setDefaultTimeout(timeout) 方法。
    • trial:boolean 设置后,此方法仅执行可操作性检查并跳过操作。默认为假。有用 等到元素准备好执行操作而不执行 它。
  • 返回:Promise<void>

【讨论】:

    猜你喜欢
    • 2021-01-01
    • 2021-06-24
    • 2021-08-02
    • 2022-12-06
    • 1970-01-01
    • 2022-11-18
    • 2022-07-20
    • 2022-11-04
    • 2022-12-22
    相关资源
    最近更新 更多