Search code examples
javascriptnode.jsgulpscreenshotpuppeteer

How can you take several hundred screenshots with Puppeteer?


I have a folder with several hundred html files. I need to take screenshots of each one and I thought I could use Puppeteer in my Gulp task.

function takeScreenshots() {
    return gulp.src(path.join(paths.dest.stage, "**/*.html"))
        .pipe(tap(async (file) => {
            const browser = await puppeteer.launch({ headless: true });
            const page = await browser.newPage();
            await page.setViewport({
                width: 1024,
                height: 768,
                deviceScaleFactor: 1,
            });
            await page.goto("file://" + file.path);
            await page.screenshot({ path: path.join(path.dirname(file.path), path.basename(file.basename, ".html") + ".jpg"), quality: 10 });
            await browser.close();
        }));
}

When I run this, my computer's fan goes on, things lock up, and I get this message:

(node:85389) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 exit listeners added to [process]. Use emitter.setMaxListeners() to increase limit
(Use `node --trace-warnings ...` to show where the warning was created)

I think it's trying to do all of the screenshots at the same time but I don't know how to tell it to take one, finish, then move onto the next one and etc.


Solution

  • I did a quick search but didn't found any way to synchronous pipes.so I wrote a workaround.

    1- first thing you will add all files to "files" array using pipe & gulp-tap

    2- then subscribe at "end" event

    3- then write your business logic which depends on files array

    function takeScreenshots() {
      const files = [];
      return gulp
        .src(path.join(paths.dest.stage, "**/*.html"))
        .pipe(
          tap((file) => {
            files.push(file);
          })
        )
        .on("end", async () => {
          const browser = await puppeteer.launch({ headless: true });
          const page = await browser.newPage();
          await page.setViewport({
            width: 1024,
            height: 768,
            deviceScaleFactor: 1,
          });
    
          for (let i = 0, len = files.length; i < len; i++) {
            const file = files[i];
            await page.goto("file://" + file.path);
            await page.screenshot({
              path: path.join(
                path.dirname(file.path),
                path.basename(file.basename, ".html") + ".jpg"
              ),
              quality: 10,
            });
          }
    
          await browser.close();
        });
    }