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 do this using promises, by getting all
<img>
tags on your document and loop check until the browser fetch all of them (whenimg.complete == true
for all imgs) then you resolve the promise.I've implemented a function for that, returns a promise that resolves when all imgs are fetched and rejects in case it reaches the timeout (initially 30 seconds but it is changeable).
Usage:
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:And you can wait for that function like so:
Putting the two together with your original code and adding a timeout so it doesn’t wait indefinitely, we get: