Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

waitForNavigation hanging, even though page was loaded

Tags:

puppeteer

I'm trying to automatically login to a website using puppeteer, with the following script:

const puppeteer = require('puppeteer');
async function logIn(userName, password) {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://foo.com'); //anonymized host
    await page.type('[name="Email"]', userName);
    await page.type('[name="Pass"]', password);
    page.click('[type=submit]');
    await page.waitForNavigation({waitUntil: 'load'});
}

logIn('[email protected]')

The awaitfor waitForNavigation eventually times out at 30 seconds. Launching puppeteer with {headless: false} on the same script, I can check in chromium's devtools that document.readyState evals to "complete" way before the timeout thresold interval. Am I doing something wrong?

like image 791
bsam Avatar asked Mar 22 '18 07:03

bsam


2 Answers

According to Puppeteer documentation proper pattern for clicking on submit and waiting for navigation is like this:

await Promise.all([
  page.waitForNavigation({ waitUntil: 'load' }),
  page.click('[type=submit]'),
]);
like image 52
Everettss Avatar answered Oct 28 '22 22:10

Everettss


Adding to the answer of Everettss, I would like to present a more modern code. Basically instead of doing any operation and calling waitFornavigation, the motive is to do the other way around. Something like this:

//Get the promise which isn't resolved yet
const navigationPromise = page.waitForNavigation(); 

//Perform the activity (Click, Goto etc). Note that the link is any valid url
await page.goto(link);

//wait until the navigationPromise resolves
await navigationPromise;

This helps to avoid race condition as per this discussion

This code makes use of async/await which is much more readable than promise-based code

like image 44
Prashanth Wagle Avatar answered Oct 28 '22 22:10

Prashanth Wagle