如何在Pupeteer中模拟拖放动作

时间:2019-04-25 11:59:28

标签: puppeteer

我在逆止器中使用人偶引擎,我想执行拖放操作并捕获屏幕截图。但是鼠标向下和鼠标向上无法正常工作。

下面是代码:

page.mouse.move(location of element);
page.mouse.down();
page.mouse.move(target);
page.mouse.up();

但是它没有选择源元素,但没有拖动。

2 个答案:

答案 0 :(得分:0)

这可能是其中之一。

首先,您的/* If css and fonts are in same folder*/ @font-face { font-family: "CustomFont"; src: url('CustomFont.ttf'); } /* If fonts is outside of your css folder*/ @font-face { font-family: "CustomFont"; src: url('../CustomFont.ttf'); } /* Absolute static path of fonts file*/ @font-face { font-family: "CustomFont"; src: url('file:///C:/Users/Administrator/fonts/CustomFont.ttf'); } /* Url path of fonts file*/ @font-face { font-family: "CustomFont"; src: url('http://localhost/wordpress/Your-font-folder-path/CustomFont.ttf'); } 通话中没有await。请参见documentation,除非您希望其异步运行(例如事件处理),否则应等待每次返回诺言的调用。

第二,就像@Thomas提到的那样,可能需要等待/休眠才能使元素可见并启用。使用page.mouse可以做到。

除此之外,这是我用于拖放的实用方法:

await page.waitFor(ms)

答案 1 :(得分:0)

我知道这个回复可能晚了,我刚刚遇到了这个问题,即 await page.mouse.move() 在 web 应用程序使用 Rafael js 库绘制形状的画布上根本不显示任何移动在画布上,如尺子、椭圆形、矩形……等。 问题是可能与坐标有关的与页面视口相关的不正确。 因此,如果您将 Puppeteer 选项设置为如下所示:

const args = [
    "--start-maximized", // Launch browser in maximum window
    "--no-default-browser-check", // Disable the default browser check, do not prompt to set it as such
    "--disable-popup-blocking",
    "--disable-web-security",
    "--no-first-run", // Skip first run wizards
    "--test-type" // Removes "Chrome is being controlled by automated test software", needs to be combined with ignoreDefaultArgs: ["--enable-automation"]
];
const igrDefaultArgs = [
    //"--enable-automation" // Will remove --enable-automation from default launched args for puppeteer
];
const options = {
    args,
    headless: false, // default is true
    slowMo: 50,
    ignoreDefaultArgs: igrDefaultArgs,
    defaultViewport: null, // Launch page in max resolution and disables defaults to an 800x600 viewport
    //defaultViewport: {width:1920, height:1080}, // Launch page in max resolution and disables defaults to an 800x600 viewport
    devtools: false,
    ignoreHTTPSErrors: true,
  };

此后,如果您使用了以下其中一项:

  1. await page.screenshot(...);
  2. pages = await browser.pages();让 actualNumber = pages.length;

出于某种原因,上述内容会弄乱视口。所以我创建了一个函数来纠正这样的视口行为:

/**
 * function to fix Page.setViewport() behavior, especially when maximizing a page,
 * or open a study with multiple pages. The issue is the View port revert to default settings which is { width: 800, height: 600 }
 * especially when open a study with multiple windows or maximizing the current page
 * @param page - current page object.
 * returns nothing
 */
const page_correctPageViewPortBehavior = async (page) => {
    // makes chromium set the viewport by inferring the current screen resolution. Seems to only work with headless: false
    await page.setViewport({
        width: 0,
        height: 0
    });
    // Note: use the following code if the above alone didn't work for you.
    // need this to refresh the page and this will correct page view port behavior
    //await page.reload();
}

现在,对于 dragAndDrop() 方法,我是这样使用的:

const dragAndDrop = async (page, fromX, fromY, toX, toY, options = {}) => {
    await page_correctPageViewPortBehavior(page);
    await page.mouse.move(fromX, fromY);
    await page.mouse.down();
    await page.mouse.move(toX, toY, options);
    await page.mouse.up();
}

然后使用dragAndDrop()方法:

await dragAndDrop(page, x, y, x, y - 20, {steps: 20});

最后,在计算fromX、fromY、toX、toY的值时,需要添加一个偏移值来补偿出现在Chromium顶部的“Chrome正在被自动化测试软件控制”的栏。我已经手动计算了这些,但我应该找到一种更简洁的方法来动态计算。应将以下内容添加到代码的全局变量部分:

// Put the following in Global variables area
// following constants are used to compensate for the difference between
// the real window and the page (DOM rendering area in the broweser window)
// That's because when using "--test-type" as passed arguments for Puppeteer, it will show the following bar:
// "Chrome is being controlled by automated test software"
// Me, To Do, need to find another neat way to calculate those dynamically
const xDomOffset = 8; // Offset value from screen left, to page left
const yDomOffset = 104; // Offset value from screen top to page top

然后在代码中的某处使用:

\\ Calculate fromX, fromY from BoundBox of original element, and toX, toY from BoundBox of destination element, then correct their values with the following:
fromX += xDomOffset;
fromY += yDomOffset;
toX += xDomOffset;
toY += yDomOffset;

作为一个非常重要的最后说明,上述所有功能仅适用于

headless: false

因此,它们仅适用于 GUI Chromium,这是 await page.mouse 事件的问题,它们仅适用于 headless = false。所以请考虑到这一点。