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

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

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

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

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

【问题讨论】:

    标签: javascript node.js google-chrome-devtools puppeteer e2e-testing


    【解决方案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);
        }
        

        【讨论】:

          猜你喜欢
          • 2016-03-25
          • 2017-05-15
          • 2022-12-29
          • 1970-01-01
          • 2016-04-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-15
          相关资源
          最近更新 更多