I am trying to make the code execution wait for all images to load before puppeteer takes a screenshot. My DOM gets populated when initData() function is called, which is defined in the client side js file. Delay or timeout is an option but I am sure there must be a more efficient way of doing it.
(async (dataObj) => {
const url = dataObj.url;
const payload = dataObj.payload;
const browser = await puppeteer.launch({ headless: false,devtools:false});
const page = await browser.newPage();
await page.goto(url,{'waitUntil': 'networkidle0'});
await page.evaluate((payload) => {
initData(payload);
//initData is a client side function that populates the DOM, need to wait
//here till the images are loaded.
},payload)
await page.setViewport({ width: 1280, height: 720 })
await page.screenshot({ path: 'test.png' });
await browser.close();
})(dataObj)
Thanks in advance.
You can use Puppeteer's page. waitForNavigation() method here to explicitly wait for this event to happen and then continue your script. The accepted notation in Puppeteer's case is by using the Promise. all() method to wait for the click to happen and the navigation to happen before continuing.
evaluate() method. Evaluates a function in the page's context and returns the result. If the function passed to page. evaluteHandle returns a Promise, the function will wait for the promise to resolve and return its value.
As mentioned in another answer, image elements have a complete
property. You can write a function that returns true when all images in the document have been fetched:
function imagesHaveLoaded() { return Array.from(document.images).every((i) => i.complete); }
And you can wait for that function like so:
await page.waitForFunction(imagesHaveLoaded);
Putting the two together with your original code and adding a timeout so it doesn’t wait indefinitely, we get:
function imagesHaveLoaded() {
return Array.from(document.images).every((i) => i.complete);
}
(async (dataObj) => {
const url = dataObj.url;
const payload = dataObj.payload;
const browser = await puppeteer.launch({ headless: false, devtools: false});
const page = await browser.newPage();
await page.goto(url, { waitUntil: 'networkidle0' });
await page.evaluate((payload) => {
initData(payload);
}, payload);
await page.waitForFunction(imagesHaveLoaded, { timeout: YOUR_DESIRED_TIMEOUT });
await page.setViewport({ width: 1280, height: 720 })
await page.screenshot({ path: 'test.png' });
await browser.close();
})(dataObj)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With