Reputation: 3041
I want to use Puppeteer to enter a value in an input field. According to the documentation, this seems straightforward (examples from docs):
await page.type('#mytextarea', 'Hello'); // Types instantly
await page.type('#mytextarea', 'World', {delay: 100}); // Types slower, like a user
So I've created the following test script:
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({headless: false}); // devtools: true
const page = await browser.newPage();
await page.goto('https://mycoolsite/index.html');
page.on('console', msg => console.log(new Date().toISOString() + ' ' + msg._text));
const selector = '#barcode';
await page.waitForSelector(selector);
await page.type(selector, "1234");
})();
It works up to the page.type() line. Meaning, it launches an instance of Chromium, goes to the correct URL, displays the expected output from the console in the log. But does not type a value in the field. I'm not seeing any errors in either the node output or the browser console output.
To rule out a silent failure, I changed the selector name to something that doesn't exist (e.g., "#qwertyuiop") and got a failure as expected.
I found a workaround if I replace the line await page.type(selector, "1234");
with the following:
const element = await page.$(selector);
await page.evaluate(element => { element.setAttribute('value', 1234); }, element);
That feels like a hack. Why does puppeteer correctly set the value with page.evaluate but not the documented page.type method?
Upvotes: 2
Views: 10773
Reputation: 2708
const selector = '#barcode';
await page.waitForSelector(selector);
await page.focus(selector); //you need to focus on the textField
await page.keyboard.type(selector, "1234"); //you are also missing keyboard property
Upvotes: 1
Reputation: 3041
Figured it out...
The input was contained by a hidden element.
Changing the line
await page.waitForSelector(selector);
to
await page.waitForSelector(selector, {visible: true, timeout: 3000 });
solved it. Apparently an element has to be visible before page.type() will work, whereas setting the element's value via attribute doesn't care as long as it's part of the DOM.
(From the docs - the visible option causes puppeteer to wait for element to be present in DOM and to be visible. Defaults to false.)
Upvotes: 5