I am trying to take a screenshot using Node.js with puppeteer. I am not using page.screenshot() because the screenshot needs to contain the entire desktop. Instead, I am screenshotting with ImageMagick's import command.
My current code works most of the time. But other times, it fails with strange results, such as:
The problem seems to be that page.bringToFront() does not wait for the page to load fully.
I am new to both Node and puppeteer. Please suggest a way to:
Adding a delay to the code does not seem to be the best solution.
Any suggestion on code improvement would be helpful.
const puppeteer = require('puppeteer');
const execSync = require('child_process').execSync;
const sleep = require('sleep');
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
'--ignore-certificate-errors',
'--no-sandbox',
'--disable-infobars',
'--disable-setuid-sandbox',
'--incognito',
'--window-size=1600,1200',
'--start-maximized',
"--disable-gpu"],
// slowMo: 250, // slow down by 1550ms
});
await browser.newPage();
await browser.newPage();
const pages = await browser.pages();
await Promise.all([
grabpage(pages[0], 'https://www.cnn.com', 'cnn'),
grabpage(pages[1], 'https://www.bbc.com', 'bbc'),
grabpage(pages[2], 'https://www.rediff.com', 'rediff'),
]);
// Someday we will close the browser also.
})();
async function grabpage(page, url, path) {
await page.goto(url);
var infront =page.bringToFront();
infront.then(
sleep.sleep(5),
execSync('import -window root ' + path +'.jpg'),
);
console.log('took Screenshot: '+path+'.jpg')
}
Rediff page not loaded fully without sleep
You're making it all confusing by trying to run everything in parallel with Promise.all. Because you have only one instance of browser, when you run grabpage 3 times in parallel, they're all competing for control over browser and can get in between each other's awaits.
I would also suggest that you open and close individual pages in grabpage. You'd have to switch it to pass browser in and do const page = await browser.newPage();
so you end up with
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
'--ignore-certificate-errors',
'--no-sandbox',
'--disable-infobars',
'--disable-setuid-sandbox',
'--incognito',
'--window-size=1600,1200',
'--start-maximized',
"--disable-gpu"],
// slowMo: 250, // slow down by 1550ms
});
await grabpage(browser, 'https://www.cnn.com', 'cnn'),
await grabpage(browser, 'https://www.bbc.com', 'bbc'),
await grabpage(browser, 'https://www.rediff.com', 'rediff'),
})();
async function grabpage(browser, url, path) {
const page = await browser.newPage();
await page.goto(url);
execSync('import -window root ' + path +'.jpg')
// await page.screenshot({path: `${path}.png`}); //if you just need to take a screenshot, not the whole desktop
await page.close();
}
not sure why you need to take the full desktop, though if you start-maximized. i guess you care about the tiny bit of OS chrome that you get in the screenshot.
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