Take periodic screenshots of a webpage using Puppeteer

I have created a function in Puppeteer that captures screenshots of a webpage at specified intervals while it loads. Here’s the code I’ve written:

const captureScreenshots = async (browserInstance, pageUrl, intervalDuration, totalFrames) => {
  const newPage = await browserInstance.newPage();

  // Set the viewport dimensions
  await newPage.setViewport({ width: 1280, height: 800 });

  await newPage.goto(pageUrl, { waitUntil: "networkidle0" });

  const imagePromises = [];
  return new Promise((resolve) => {
    const intervalHandle = setInterval(async () => {
      imagePromises.push(
        newPage.screenshot({
          captureBeyondViewport: true,
          fullPage: true,
          encoding: "base64",
        })
      );
      if (imagePromises.length >= totalFrames) {
        clearInterval(intervalHandle);
        resolve(imagePromises);
      }
    }, intervalDuration);
  });
};

const runScreenshotTest = async (pageUrl) => {
  const browserInstance = await puppeteer.launch({ timeout: 100000 });
  try {
    const images = await captureScreenshots(browserInstance, pageUrl, 42, 24);
    return images[images.length - 1];
  } finally {
    // await browserInstance.close();
  }
};

Currently, the line to close the browser is commented out, which leads to a zombie process when the function ends. When I uncomment it, I encounter a problem where the browser gets closed before the image promises are fulfilled. I initially thought the await would handle this as expected, since the return from the try block waits on the promises. However, that’s not happening.

What’s the correct approach to ensure all promises resolve before closing the browser?

I considered using code like this:

while (true) {
  if (Promise.all(imagePromises)) {
    await browserInstance.close();
  }
}

But this method seems very inefficient, so I’m seeking a better way to await the promises and properly close the browser.

hey, i think u can use Promise.all(imagePromises).then(...) to wait until all promises are fullfiled. like this: Promise.all(imagePromises).then(() => browserInstance.close());. this way, it waits for all to resolve b4 closing. give it a shot!