如何始终如一地填写输入字段?
How can I consistently fill out input fields?
我不确定为什么,但似乎有些字段对我不起作用。
我在一个站点上运行良好:
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:等到元素可见
仅仅等待选择器是行不通的,我们必须等到元素在视口上正确可见并且导航请求完成。
// 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 });
只是在您当前的代码上添加上述更改就得到了这个结果,
请注意上面的结果截图在提交按钮上没有任何内容,其他选择器也是如此。
修复 2:正确传递数据
这是可选的,以防第一个修复没有改变任何东西。
步骤 1
不是传递两个参数,而是传递一个带大括号的参数。
await page.evaluate((sel, val) => {
const ele = document.querySelector(sel);
if (!ele) {
return;
}
ele.value = val;
}, (sel, val)); // <-- Look here
第 2 步
如果上面的第1步不行,那就试试。所以如果是angular的app,应该知道元素变了,把上面改成这样,
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)
我不确定为什么,但似乎有些字段对我不起作用。
我在一个站点上运行良好:
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:等到元素可见
仅仅等待选择器是行不通的,我们必须等到元素在视口上正确可见并且导航请求完成。
// 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 });
只是在您当前的代码上添加上述更改就得到了这个结果,
请注意上面的结果截图在提交按钮上没有任何内容,其他选择器也是如此。
修复 2:正确传递数据
这是可选的,以防第一个修复没有改变任何东西。
步骤 1
不是传递两个参数,而是传递一个带大括号的参数。
await page.evaluate((sel, val) => {
const ele = document.querySelector(sel);
if (!ele) {
return;
}
ele.value = val;
}, (sel, val)); // <-- Look here
第 2 步
如果上面的第1步不行,那就试试
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)