0

I have used puppeteer to capture the screenshot of my page in React JS. But it is taking a blank screenshot instead of the actual charts present on the page. Here is my code.

const puppeteer = require('puppeteer');

const url = process.argv[2];
if (!url) {
    throw "Please provide URL as a first argument";
}
async function run () {
    return new Promise(async (resolve, reject) => {
        try {
            const browser = await puppeteer.launch({args: ['--no-sandbox', '--disable-setuid-sandbox'],headless: true, ignoreHTTPSErrors:true});
            const page = await browser.newPage();
            
             await page.goto(url, {
                    timeout: 30000,
                    waitUntil: "networkidle0"
                });
            await page.content(); 
            let imgDataBase64 = await page.screenshot({quality:100, fullPage: true, encoding: "base64", type: "jpeg"});
            await browser.close();
            return resolve(imgDataBase64);
        } catch (e) {
            return reject(e);
        }
    })
}
run().then(console.log).catch(console.error);

The reason for the same could be document is getting loaded first before the chart loads. And puppeteer takes the screenshot as soon as the document loads. Can anyone please help me with this? We have to be sure that there is no delay in chart loading after the document is loaded so that screenshot can be captured properly. Please help. Thanks in advance.

  • This probably won't help, but you need to provide functions to both `then` and `catch`. – Bart Barnard Mar 29 '22 at 10:12
  • which functions ? – Ananya Oberoi Mar 29 '22 at 10:15
  • e.g. `run().then( res => console.log(res) ).catch( err => console.error(err) )` – Bart Barnard Mar 29 '22 at 10:26
  • but how it's going to help us..? – Ananya Oberoi Mar 29 '22 at 12:34
  • [What is the explicit promise construction antipattern and how do I avoid it?](https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it). Puppeteer is already promise-based, so there's no need for `new Promise` here. Simply `return imgDataBase64;`. `await page.content();` throws away the result -- this is pointless. Otherwise, I don't see how the screenshot could occur before the page loads. You're using `networkidle0` which is quite aggressive. You could try `{waitUntil: "load"}` I suppose, but that shouldn't be any different. – ggorlen Mar 29 '22 at 13:56
  • Is there a selector or rendering condition you can add to a `waitForFunction`? I can't offer any more help without the actual page behavior as a [mcve]. – ggorlen Mar 29 '22 at 14:00

1 Answers1

0

Puppeteer seems to have a bug with elements outside the viewport. Thanks to this discussion on github, unforce image clipping should solve your problem :

const body = await page.$("body")

let imgDataBase64 = await page.screenshot({
   type: "jpeg",
   clip: await body.boundingBox()
});
Ybochatay
  • 46
  • 3