npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

screenshot-helper

v1.3.7

Published

A helper for taking automated web screenshots using Playwright.

Downloads

66

Readme

screenshot-helper

Automate high-quality screenshots of web pages for testing, visual review, and documentation.

screenshot-helper is a flexible Node.js utility designed to programmatically capture screenshots of web apps with minimal boilerplate. It supports scenario lists, custom setup and cleanup logic, device presets, and easy integration into your QA or CI flows.


Features

  • Automates screenshots from a scenario configuration
  • Works with Playwright to simulate real browser environments (desktop/mobile, etc.)
  • Supports UI interaction setup (before) and post-setup cleanup (cleanup)
  • Granular capture: full-page, clipped to element, function-based, etc.
  • Use filters to selectively run a subset of scenarios
  • Strong integration for visual testing and asset generation
  • Errors in scenarios (including Playwright errors) are always caught: process never crashes, errors are highlighted and remaining scenarios continue.
  • Full ES module (ESM) support everywhere; tested with Vitest.

Installation

npm install screenshot-helper

For development/contributors:

npm install --save-dev vitest

Running the Tests

This project uses Vitest for all unit and integration tests and supports top-level import/export JavaScript syntax out of the box. No Babel or legacy Jest config is needed with Node.js (>=18).

npm test

Or run a single test file:

npx vitest run test/your.test.js

Basic Usage

Define your scenarios and call the runner. Each scenario can have:

  • name: Unique name for the output file
  • route: URL path (relative to your baseURL)
  • full: Capture the entire page (true) or just the viewport (false)
  • selector: (optional) CSS selector for element-only screenshots
  • before: (optional) Async function for custom setup (e.g., open a modal, wait for element)
  • cleanup: (optional) Async function for removing overlays/ads/etc before the screenshot
import launchScreenshotsRunner from 'screenshot-helper';

const baseURL = 'http://localhost:8888';
const devices = {
  desktop: { viewport: { width: 1280, height: 1080 }, deviceScaleFactor: 2 },
  mobile: { viewport: { width: 375, height: 812 }, deviceScaleFactor: 2 }
};
const loadTimeoutMs = 8000; // optional: max wait for networkidle before acting
const loadTimeoutAction = 'continue'; // or 'skip' to abandon the scenario
const debug = true; // optional: verbose logging for stuck runs

const scenarioData = [
  {
    name: 'simple-homepage',
    route: '/',
    full: true
  },
  {
    name: 'cookie-banner',
    route: '/',
    selector: '#cookie-consent-banner',
    before: async (page, locator, device) => {
      await page.waitForFunction(() => !!window.cookieconsent);
      await page.evaluate(() => window.cookieconsent.show());
      // device is now available as a third argument (e.g. 'desktop' or 'mobile')
      if (device === 'mobile') {
        // special handling for mobile...
      }
      if (!await locator.isVisible()) return false; // skip screenshot if banner is not visible
    }
  },
  {
    name: 'third-party-capture',
    route: '/external-widget-demo',
    before: async page => {
      await page.click('#widget-opener');
    },
    cleanup: async page => {
      await page.evaluate(() => {
        let el = document.querySelector('.third-party-banner');
        if (el) el.remove();
      });
    },
    full: true
  }
];

// Optionally pass a filter to only run a subset of scenarios
const filter = process.argv[2];

// To provide HTTP Basic Auth credentials to all requests
const httpCredentials = {
  username: 'yourUsername',
  password: 'yourPassword',
};

launchScreenshotsRunner({ scenarioData, baseURL, devices, filter, httpCredentials, loadTimeoutMs, loadTimeoutAction, debug });

Scenario Configuration

  • name: string (required)
    Used for the output filename and reporting.
  • route: string (required)
    Path relative to baseURL
  • full: boolean
    Capture the entire page (true) or just viewport/selector area (false)
  • selector: string
    CSS selector for element screenshot (optional; use type: 'element' for clarity)
  • before: (page, locator?) => Promise
    An async function run prior to the screenshot, for setup (e.g., open menus, wait for content)
  • cleanup: (page) => Promise
    An async function run just before the screenshot (after setup), ideal to remove overlays/ads, etc.

Scenario Types

screenshot-helper supports 3 scenario type modes for maximum control:

  • Default (Page)

    • Omit type, or use any unrecognized value.
    • Screenshots the full page or just the viewport (if full: true) after running optional before and cleanup hooks.
    • selector is ignored.
    • If full: true, the page is scrolled to capture the entire length.
  • Element (type: 'element')

    • Only screenshots the area of a specific DOM element, as matched by selector.
    • If full: true, the screenshot will output multiple PNG files ("tiles/fragments") per element, scrolling through both axes using Playwright. This pans through overflow within the selected element via element.scrollTo, so containers wider or taller than the viewport are robustly covered. Files are named with letter suffixes (e.g. ...001a-, ...001b-, etc).
    • Receives before(page, locator, device) and cleanup(page, locator, device) for custom setup/teardown.
  • Function (type: 'function')

    • For advanced/edge scenarios requiring full Playwright scripting.
    • Hooks are given both the page object and a locator for chaining or ignoring as you wish: before(page, locator, device).
    • Does not perform any screenshot by default—your hook code should perform interactions as needed. You can use these for setup, or for logic-only tasks that do not result directly in a screenshot.

Advanced Patterns

Use type: 'element' for element screenshots, or type: 'function' scenarios for full scriptable logic. You can chain Playwright's page and locator methods inside your hooks, interact with dynamic JS elements, or conditionally skip screenshots.


CLI Filtering

You can filter which scenarios are run by passing a substring as a CLI argument:

node screenshots.js homepage

Will only run scenarios whose name includes "homepage".

Load timeouts

  • loadTimeoutMs caps how long the runner waits for a page to reach networkidle before proceeding.
  • loadTimeoutAction controls behavior on timeout: 'skip' stops the scenario immediately, 'continue' runs hooks/screenshot even if the page never reached networkidle.
  • The same loadTimeoutMs is reused for asset waits (ensureAssetsLoaded), so hanging images/fonts won’t stall forever.

Debug logging

  • Pass debug: true to launchScreenshotsRunner to print step-by-step progress (navigation, load waits, hooks, and screenshot points) for each scenario/device. Useful when runs hang or stall.

Testing

Run tests with:

npm test

Unit and integration tests are in [test/].


Contributing

PRs and suggestions welcome! Please open an issue first to discuss feature ideas or bugs.


License

ISC (see LICENSE file)


See also: