Why am I frequently receiving the "ProtocolError - Page.captureScreenshot timed out" error in Puppeteer despite increasing the timeout?

This topic was automatically generated from Slack. You can find the original thread here.

I’m receiving the error “ProtocolError - Page.captureScreenshot timed out” in Puppeteer when trying to take a screenshot quite frequently. I’ve already increased the timeout, but the error persists (not always), and I don’t understand the reason.

I’m sorry to hear that you’re experiencing issues with Puppeteer when taking screenshots. Since the error is not consistent, it might be related to specific web pages or network conditions. To better understand the issue and help you find a solution, could you please provide more information about the web pages you’re trying to capture and any specific configurations you’re using in your Puppeteer setup?

"I’m trying to capture the page ‘Gráficos em tempo real de índices, futuros, Forex e Bitcoin no TradingView.

And I’m using custom Node.js code to run Puppeteer.

Here is the code:"

Thank you for providing the URL and mentioning that you’re using custom Node.js code with Puppeteer. However, I don’t see the actual code you’re using in your message. Could you please share the code snippet you’re using to capture the screenshot? This will help me better understand the issue and provide a solution.

It looks like you have a Pipedream component that uses Puppeteer to take a screenshot of a webpage. The component takes a URL and a filename as input, sets cookies, waits for specific elements to load, and then takes a screenshot of the page. The screenshot is saved to the /tmp directory with the given filename. If you have any questions or need help with this code, feel free to ask!

I’m getting the error “ProtocolError - Page.captureScreenshot timed out.” when running the code I sent earlier.

I apologize for the inconvenience you’re experiencing. The “ProtocolError - Page.captureScreenshot timed out” error might be caused by the Puppeteer script taking longer than expected to capture the screenshot. To help you further, could you please provide more information about your code, such as the specific elements you’re waiting for or any additional configurations you’re using? This will help me better understand the issue and provide a solution.

I don’t actually see the code in the message above, I think that’s why Pi is having trouble

I deleted it afterward

But it would be this code:

import { puppeteer } from '@pipedream/browsers';
import fs from "fs";

export default defineComponent({
  key: "puppeteer-screenshot",
  name: "Take a Screenshot",
  version: "0.1.8",
  type: "action",
  props: {
    puppeteer: {
      type: "app",
      app: "puppeteer",
    },
    url: {
      type: "string",
      label: "URL",
      description: "Enter the URL you'd like to take a screenshot of here",
      default: "{{steps.data_processing_discord.URL}}",
    },
    filename: {
        type: "string",
        label: "Name File",
        description: "Enter the filename",
        default: "{{steps.data_processing_discord[\"Source+Symbol\"]}}-{{steps.data_processing_discord.Data}}",
      },
    data: { type: "data_store" }

  },
  async run({ steps, $ }) {
    const { filename } = this;
    const { url } = this;

    const browser = await puppeteer.browser();
    const page = await browser.newPage();
    await page.setViewport({ width: 1920, height: 1080 });

    // Load the previously saved cookie.
    const sessionidValue = await this.data.get("sessionid");
    const cachecValue = await this.data.get("cachec");
    const cookieSessionID = {
      name: 'sessionid',
      value: sessionidValue,
      domain: '.[tradingview.com](http://tradingview.com)',
      path: '/',
    };
    const cookieCachec = {
      name: 'cachec',
      value: cachecValue,
      domain: '.[tradingview.com](http://tradingview.com)',
      path: '/',
    };

    // Set the cookie on the page
    await page.setCookie(cookieSessionID, cookieCachec);
    
    // Configure the navigation timeout
    await page.setDefaultNavigationTimeout(0);
    await page.goto(url);
    await page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 100000 });
    // await page.waitForTimeout(3000);
    
    const elementChart = 'body > div.js-rootresizer__contents.layout-with-border-radius > div.layout__area--center';
    try {
      // Wait until the element with the desired selector is loaded
      await page.waitForSelector(elementChart, { timeout: 100000 }); // Timeout set in milliseconds
      console.log('The elementChart is loaded.');
    } catch (error) {
      console.error('The elementChart was not found or did not load in time.');
    }

    const elementWidgetBar = 'body > div.js-rootresizer__contents.layout-with-border-radius > div.layout__area--right > div > div.widgetbar-tabs > div > div > div > div > button.button-I_wb5FjE.isActive-I_wb5FjE.apply-common-tooltip.common-tooltip-vertical.accessible-I_wb5FjE';
    // Check if the element is loaded and click on it.
    try {
      await page.waitForSelector(elementWidgetBar, { timeout: 5000 });
      
      // If the element is available, click on it.
      await page.click(elementWidgetBar);
      console.log('Clicked on the element to hide the widgetbar');

    } catch (error) {
      console.log('The element to hide the widgetbar was not found or did not load in time. Action ignored.');
    }

    // Select element to screenshot
    // const select = await page.$(elementChart)

    // Screenshot
    // await select.screenshot();
    // const screenshot = await select.screenshot({ timeout: 0 });

    console.log('Running the screenshot.');
    const screenshot = await page.screenshot({
      clip: { x: 56, y: 42, width: 1810, height: 995 }, timeout: 100000 
    });
    console.log('Screenshot executed.');

    await browser.close();

    console.log('Browser closed.');

    const fn = `${filename.replace(/[&\/\\#, +()$~%.'"":*?<>{}]/g, "-")}.png`;
    fs.writeFileSync('/tmp/' + fn, screenshot)

    $.export(
      "filename", fn,      
    );
    $.export(
      "PathFL", "/tmp/" + fn
    );
    // return screenshot.toString('base64');
  },
});

given this code, can you help with the issue above?