如何使用 Puppeteer 填充输入字段?

Posted

技术标签:

【中文标题】如何使用 Puppeteer 填充输入字段?【英文标题】:How to fill an input field using Puppeteer? 【发布时间】:2018-06-06 14:00:09 【问题描述】:

我正在使用Puppeteer 进行 E2E 测试,现在我正在尝试使用以下代码填充输入字段:

await page.type('#email', 'test@example.com');

它有效,但我发现电子邮件地址是一个字符一个字符地输入到字段中,就好像真人在打字一样。

是否可以一次用电子邮件地址填写输入字段?

【问题讨论】:

【参考方案1】:

只需像这样设置输入值:

await page.$eval('#email', el => el.value = 'test@example.com');

这是在 Wikipedia 上使用它的示例:

const puppeteer = require('puppeteer');

(async () => 
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://en.wikipedia.org', waitUntil: 'networkidle2');

    await page.waitForSelector('input[name=search]');

    // await page.type('input[name=search]', 'Adenosine triphosphate');
    await page.$eval('input[name=search]', el => el.value = 'Adenosine triphosphate');

    await page.click('input[type="submit"]');
    await page.waitForSelector('#mw-content-text');
    const text = await page.evaluate(() => 
        const anchor = document.querySelector('#mw-content-text');
        return anchor.textContent;
    );
    console.log(text);
    await browser.close();
)();

【讨论】:

谢谢!我浪费了很多时间试图让“类型”方法在登录时工作。看起来好像成功了,但是登录总是失败。 干得好,真的为我节省了很多时间。 顺便说一句。 waitFor 方法已弃用 这对我不起作用。此外,还有更简单的方法可以使用 page.type() 来执行此操作。请参阅下面的答案【参考方案2】:

另一种方法

await page.focus('#email')
await page.keyboard.type('test54')

【讨论】:

这行得通。问题是,在某些形式中,按键上有一个触发器可以做某事。如果只是设置输入字段值,这个触发器不会运行,表单提交也不能正常工作。【参考方案3】:

要扩展上面接受的答案,您也可以将 $eval 与局部范围的变量一起使用,

const myLocalValue = 'Adenosine triphosphate';    
await page.$eval('input[name=search]', (el, value) => el.value = value, myLocalValue);

这将从本地范围获取“myLocalValue”,并将其作为“值”传递到浏览器范围

【讨论】:

你好,亲爱的安德鲁!能否请您指出我可以阅读有关此语法的更多信息的来源? 您好 Mrrobot,我已经有一段时间没有看到这个了,我真的不记得我从哪里得到它了。快速查看文档显示了预期的原型和可选的“...args”。没有一个例子清楚地表明它,但它记录在here。 这非常有用。我完全困惑为什么简单地将字符串值更改为局部变量不起作用。伟大的扩展和超级有用。 这应该是公认的答案,静态值几乎没有用【参考方案4】:

page.evaluate()

您可以使用page.evaluate() 将电子邮件字符串分配给元素的value 属性:

await page.evaluate(() => 
  const email = document.querySelector('#email');
  email.value = 'test@example.com';
);

【讨论】:

【参考方案5】:

在最新版本的 Puppeteer(10.x) 中,所选答案对我不起作用。相反,对我有用的是以下命令。

test('should login', async () => 
const page = await browser.newPage();
page.setDefaultTimeout(6000);
await page.goto('https://www.saucedemo.com/');
await page.waitForSelector('#user-name');
await page.type('#user-name', 'standard_user');
await page.type('#password', 'secret_sauce');
await page.click('#login-button');
await page.waitForSelector('#contents_wrapper'););

【讨论】:

【参考方案6】:

对于Puppeteer Sharp,语法略有不同,有两种方法,但一种比另一种更好。这是一个完整的例子:

static async Task Main(string[] args)

    await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision);

    await using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions  Headless = true, Product = Product.Chrome ))
    await using (var page = await browser.NewPageAsync())
    
        try
        
            await page.GoToAsync(urlString);
            await page.WaitForSelectorAsync("#btnSubmit");

            await ReplaceText(page, "#inputUsernameId", usernameString);
            await ReplaceText(page, "#inputPasswordId", passwordString);

            await page.ClickAsync("#btnSubmit");
            await page.WaitForNavigationAsync();  // Optional, if the page is changing          
        
        catch (Exception ex)
        
            Console.WriteLine(ex);
            // Handle me / Log me
            throw;
        
    


private static async Task ReplaceText(Page page, string selector, string replacementValue)

    await page.WaitForSelectorAsync(selector).ConfigureAwait(false);
    await page.EvaluateExpressionAsync($"document.querySelector(\"selector\").value = \"replacementValue\"").ConfigureAwait(false);

    // Alternative older method below (not as reliable with async, but works):
    // await ele.FocusAsync().ConfigureAwait(false);
    //
    // await page.Keyboard.DownAsync("Control").ConfigureAwait(false);
    // await ele.PressAsync("A").ConfigureAwait(false);
    // await page.Keyboard.UpAsync("Control").ConfigureAwait(false);
    // await ele.PressAsync("Backspace").ConfigureAwait(false);
    //    
    // await ele.TypeAsync(replacementText).ConfigureAwait(false);
    // await ele.PressAsync("Tab").ConfigureAwait(false);

【讨论】:

以上是关于如何使用 Puppeteer 填充输入字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Puppeteer 从输入中删除现有文本?

如何禁用特定输入字段的自动填充

如何使用输入的文本字段填充 NSMutableArray

如何更改多个填充的复选框输入字段值?

如何使用 Json 对象填充动态添加的输入字段

如何从 Puppeteer 将文本输入到 Flash TextArea 中?