如何连续填写输入字段?

时间:2019-05-23 20:34:02

标签: node.js puppeteer

我不确定为什么,但是似乎有些字段对我不起作用。

这在一个站点上对我来说很好:

await page.click(USERNAME_SELECTOR);
await page.keyboard.type(CREDS.username);
await page.click(PASSWORD_SELECTOR);
await page.keyboard.type(CREDS.password);
await page.click(LOGIN_BUTTON_SELECTOR);
await page.waitForNavigation();

但是,在https://app.member.virginpulse.com/上,它似乎对我不起作用。这应该足够简单,因为输入字段都具有ID(#username$password)...但是,它似乎并没有正确填写。

const puppeteer = require('puppeteer');
const email = "foo@bar.com";
const password = "foopass";
const emailInputSel = "#username";
const passwordInputSel = "#password";
const signInButtonSel = ".login-submit input";
const homeUrl = "https://app.member.virginpulse.com";

async function run() {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto(homeUrl, {waitUntil: 'domcontentloaded'});
    //----from here---
    await page.waitFor(emailInputSel);
    await page.$eval(emailInputSel, (e,v) => e.value = v, email);
    await page.$eval(passwordInputSel, (e,v) => e.value = v, password);
    //----to here----- i've tried several things
    await page.screenshot({path: 'screenshot.png'});
    ...

我尝试过的其他事情:

await page.evaluate((sel, val) => {
    const ele = document.querySelector(sel);
    if (!ele) {
        return;
    }
    ele.value = val;
}, sel, val);

await page.evaluate((sel) => {
    const ele = document.querySelector(sel);
    if (!ele) {
        return;
    }
    ele.click(); ele.focus();
}, sel);
await page.keyboard.type(val);

似乎没有正确填写数据的信息。有谁知道发生了什么以及如何使它正常工作?

1 个答案:

答案 0 :(得分:2)

修复1:等到元素可见为止。

仅等待选择器将不起作用,我们必须等待,直到元素在视口中正确可见并且导航请求完成为止。

// wait until all requests are done
await page.goto(homeUrl, { waitUntil: "networkidle0" });

// wait until the email selector is visible on viewport
await page.waitForSelector(emailInputSel, { visible: true }); 

只需在您当前的代码上添加以上更改,就可以得到这个结果,

enter image description here

请注意,上面的结果屏幕快照在“提交”按钮上没有任何内容,其他选择器也是如此。

修复2:正确传递数据

这是可选的,以防第一个修复程序没有任何改变。

步骤1

与其传递两个参数,不如通过括号将一个参数传递。

await page.evaluate((sel, val) => {
    const ele = document.querySelector(sel);
    if (!ele) {
        return;
    }
    ele.value = val;
}, (sel, val)); // <-- Look here

步骤2

如果上述步骤1不起作用,请尝试执行trigger the change。因此,如果它是一个有角度的应用程序,则应该知道该元素已更改,将上面的内容更改为此,

await page.evaluate((sel, val) => {
  const ele = document.querySelector(sel);
  if (!ele) {
    return;
  }
  ele.value = val;

  // Trigger the change here
  var event = new Event('input', {
    'bubbles': true,
    'cancelable': true
  });

  ele.dispatchEvent(event);

}, (sel, val));

可选

如果您想多次重用同一件事,可以用这种方式重写它们,

const fillInput = (sel, val) => {
  await page.waitForSelector(sel, { visible: true });
  await page.evaluate((sel, val)=>{}) // the code from above function should be here
}

然后这样打电话

await fillInput(emailInputSel, email)