【问题标题】:Puppeteer confirm傀儡师确认
【发布时间】:2018-04-09 08:34:26
【问题描述】:

我正在努力学习木偶。我已经成功编写了登录页面和一些导航的脚本。然后我让它点击一个按钮。该页面会弹出一个 window.confirm,我希望我的脚本接受它以继续下一步,但我不知道如何。

谁能指出我正确的方向?

【问题讨论】:

  • 在 puppeteer 中有一个模拟按键的选项,我感觉关闭确认对话框就像按 Enter 一样简单,.. 所以也许 -> page.keyboard.press(String.fromCharCode(13));

标签: javascript confirm puppeteer


【解决方案1】:

刚刚在这里做了一个简单的测试,当出现确认对话框时。只需按 Enter 即可关闭对话框。

所以我们可以在 puppeteer 中做的就是做到这一点。 我打开了一个带有确认框的快速网页,..

例如。

<div>Before confirm</div>
<script>
  window.confirm("confirm");
  document.write("<div>After Confirm</div>");
</script>

现在是我们的木偶脚本。

await delay(1000);
await page.keyboard.press(String.fromCharCode(13));  
await page.screenshot({path: 'screenshot.png'});
await browser.close();

做上面我的截图是

Before confirm
After Confirm

如果按下确认对话框,这正是我们所期望的,.. 附言。 delay 只是一个基于 setTimeout 等待的简单 promise,因此我们有机会出现确认对话框。

如果你目前没有 Promise 延迟功能,这里有一个供你使用。

const delay = (ms) =>
  new Promise((resolve) => setTimeout(resolve, ms));

更新:不幸的是,对话框不能可靠地响应按键。但是 puppeter 确实有一个我们也可以附加的对话事件。

page.on("dialog", (dialog) => {
  console.log("dialog");
  dialog.accept();
});

您甚至可以关闭并阅读发送的消息等。更多信息在这里-> https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#class-dialog

【讨论】:

  • 谢谢,基思。所以我试过了,没有任何反应。奇怪的是,如果我手动输入 return 操作完成。
  • 只是为了确认一下,我使用了您在上面发布的示例,没有任何更改,并且与我上面写的相同。我什么都得不到。 Google Chrome 65.0.3325.181 (Official Build) (64-bit) 我需要做些什么来设置我的环境吗?
  • without any change 你是否实现了承诺延迟功能,因为我没有展示。你也没有收到任何错误吗?如果按钮按下不起作用,您至少应该显示Before confirm。
  • 其实我不熟悉 promises 所以我这样做了:await page.waitFor(1000);我确认确实引入了暂停。问题不在于缺乏延迟。 Return 只是没有做预期的事情或没有触发。但是我不明白为什么。
  • 为了清楚起见,这是我运行的:const puppeteer = require('puppeteer'); (async () =&gt; { const browser = await puppeteer.launch({headless: false, slowMo: 100}) const page = await browser.newPage() await page.goto('file:///Users/bierman/Documents/Applications/bin/arris/test.html') await page.focus() await page.waitFor(1000); await page.keyboard.press(String.fromCharCode(13)); await browser.close() })()
【解决方案2】:

确认提示由位于window.confirm的全局函数confirm(&lt;string&gt;)触发。该函数冻结脚本的执行,直到给出响应,然后将其返回给调用者。如果用户接受提示,则返回值为true。

由于我们正在网页中处理自定义浏览器会话,因此您可以使用任何您想要的内容覆盖全局变量。

所以在运行触发确认窗口的动作之前运行

await page.evaluate(`window.confirm = () => true`)

那么当页面代码调用confirm()时,它会立即得到true响应,而不显示任何提示。

【讨论】:

  • 谢谢!我不再有那个调制解调器,所以我现在不维护有问题的脚本,但很高兴知道这一点。
  • 救了我的命!谢谢!
【解决方案3】:

谢谢,基思!它现在就像一个魅力。如果有人感兴趣,我已经在这里发布了。

https://gist.github.com/mbierman/5b3e671fa4e848eec899ff486d0cdc26

#!/usr/bin/env node

/**
 * @name Reboot Arris modem. 
 *
 * @desc Puppeteer script for rebooting an Arris modem. 
 * since the specific navigation for your modem will vary, this 
 * is more of an example and isn't guaranteed to work for your particular
 * modem. 
 * Many thanks to https://stackoverflow.com/users/6870228/keith for his help!
 *
 */

const puppeteer = require('puppeteer')
const screenshot = 'arris.png';

/* Enter your user name and password here between the 's */
const USER = '';
const PASS = '';

    const delay = (ms) =>
    new Promise((resolve) => setTimeout(resolve, ms));

(async () => {

    const browser = await puppeteer.launch({headless: true})
    const page = await browser.newPage()

        console.log("Login...");
    await page.goto('http://192.168.0.1/login.asp');
    await page.type('#id_username', USER, { delay: 10 });
    await page.type('input[type="password"]', PASS, { delay: 10 });
    await page.click('[value="Login"]');
        console.log("Going home...");
    await page.goto('http://192.168.0.1/home.asp');
    await page.click('#alertExitButton');
        console.log("Config...");
    await page.goto('http://192.168.0.1/RgConfiguration.asp');
    console.log('Submit request...');
    page.click('input[type="submit"]');
    console.log('Pause...');

    await page.on("dialog", (dialog) => {
    console.log("Dialog is up...");
        delay(1000);
    console.log("Accepted...");
    dialog.accept();
        delay(1000);
    });

        await delay(3000);
        console.log("Exiting.");
    browser.close();
    process.exit(1);
})()

【讨论】:

    【解决方案4】:

    我们正在构建要传递的对象,所以它有点不同,但我想我会分享。

    我们为操作创建一个对象:

    type: "operation",
    name: "Touch Delete button from tracks-hero-tmp",
    description: "Click and confirm delete and verify track cluster is 1 less",
    actions: [
      { method: 'waitForSelector', value: '[tg-name=track_hero_delete_btn]' },
      { method: 'focus', value: '[tg-name=track_hero_delete_btn]' },
      { method: 'click', value: '[tg-name=track_hero_delete_btn]', accept_dialog: 'false' },
      { method: 'screenshot' }
    ],
    

    然后将“accept_dialog”设置为一个布尔值,该布尔值会传递给异步函数,我们将对话响应设置如下:

      if (accept_dialog) {
        await dialog.accept();
      } else {
        await dialog.dismiss();
      }
    

    希望这对某人有所帮助。 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-25
      • 1970-01-01
      • 1970-01-01
      • 2020-11-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-28
      • 2014-06-06
      相关资源
      最近更新 更多