I submit a form using the following code and i want Puppeteer to wait page load after form submit.
await page.click("button[type=submit]");
//how to wait until the new page loads before taking screenshot?
// i don't want this:
// await page.waitFor(1*1000); //← unwanted workaround
await page.screenshot({path: 'example.png'});
How to wait for page load with puppeteer?
You can wait for navigation asynchronously to avoid getting null
on redirection,
await Promise.all([
page.click("button[type=submit]"),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
This will help you if the page.click already triggers a navigation.
await page.waitForNavigation();
According to the Official Documentation, you should use:
page.waitForNavigation(options)
options
<Object> Navigation parameters which might have the following properties:
timeout
<number> Maximum navigation time in milliseconds, defaults to 30 seconds, pass0
to disable timeout. The default value can be changed by using the page.setDefaultNavigationTimeout(timeout) method.waitUntil
<string|Array<string>> When to consider navigation succeeded, defaults toload
. Given an array of event strings, navigation is considered to be successful after all events have been fired. Events can be either:
load
- consider navigation to be finished when theload
event is fired.domcontentloaded
- consider navigation to be finished when theDOMContentLoaded
event is fired.networkidle0
- consider navigation to be finished when there are no more than 0 network connections for at least500
ms.networkidle2
- consider navigation to be finished when there are no more than 2 network connections for at least500
ms.- returns: <Promise<[?Response]>> Promise which resolves to the main resource response. In case of multiple redirects, the navigation will resolve with the response of the last redirect. In case of navigation to a different anchor or navigation due to History API usage, the navigation will resolve with
null
.
Readability:
You can use page.waitForNavigation()
to wait for a page to navigate:
await page.waitForNavigation();
Performance:
But since page.waitForNavigation()
is a shortcut for page.mainFrame().waitForNavigation()
, we can use the following for a minor performance enhancement:
await page._frameManager._mainFrame.waitForNavigation();
I know it is bit late to answer this. It may be helpful for those who are getting below exception while doing waitForNavigation.
(node:14531) UnhandledPromiseRejectionWarning: TimeoutError: Navigation Timeout Exceeded: 30000ms exceeded at Promise.then (/home/user/nodejs/node_modules/puppeteer/lib/LifecycleWatcher.js:142:21) at -- ASYNC -- at Frame. (/home/user/nodejs/node_modules/puppeteer/lib/helper.js:111:15) at Page.waitForNavigation (/home/user/nodejs/node_modules/puppeteer/lib/Page.js:649:49) at Page. (/home/user/nodejs/node_modules/puppeteer/lib/helper.js:112:23) at /home/user/nodejs/user/puppeteer/example7.js:14:12 at
The correct code that worked for me is as below.
await page.click('button[id=start]', {waitUntil: 'domcontentloaded'});
Similarly if you are going to a new page, code should be like
await page.goto('here goes url', {waitUntil: 'domcontentloaded'});
await Promise.all([
page.click(selectors.submit),
page.waitForNavigation({ waitUntil: 'networkidle0' }),
]);
This would be the first priority to use as it waits for all network to complete and assumes it is done when you don't have more than 0 network call for 500ms.
you can also use
await page.waitForNavigation({ waitUntil: 'Load' }}
or else, you can use
await page.waitForResponse(response => response.ok())
this function can also be used in various places as it only allows to proceed further when all the calls are a success that is when all the response status is ok i.e (200-299)
来源:https://stackoverflow.com/questions/46948489/puppeteer-wait-page-load-after-form-submit