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

@storycap-testrun/node

v2.0.0

Published

Node.js screenshot capture for Storybook Test Runner - Provides stable screenshot functionality using Playwright for visual regression testing

Readme


@storycap-testrun/node implements stable screenshot capture for @storybook/test-runner using the same reliability approach as storycap :camera:

Why @storycap-testrun/node?

Standard waitForPageReady in @storybook/test-runner provides only basic stability checks, often resulting in flaky visual tests.

@storycap-testrun/node solves this by implementing storycap's proven stability detection:

  • Metrics monitoring via CDP (Chrome DevTools Protocol) for rendering completion
  • Hash verification across multiple screenshot captures for content consistency
  • Flaky test prevention with masking and element removal capabilities

This ensures reliable visual regression testing without the common issues of timing-based approaches.

Features

  • High stability checks for rendering content
  • Accurate waiting for Play Function
  • Customization before and after screenshot capture using Hooks
  • Masking of unstable elements
  • Removal of unstable elements
  • Skipping of unstable elements
  • Integration with @storybook/test-runner
  • CDP-based metrics monitoring

Limitations

  • Single viewport per test run
  • No pseudo-state variants (:hover, :focus, etc.)
    • Intentionally excluded to avoid conflicts with other postVisit hooks
    • Workaround: Use Story play functions to set desired states before screenshot capture

Installation

Install via npm:

$ npm install --save-dev @storycap-testrun/node

Getting Started

Please set up @storybook/test-runner beforehand.

You can start using it immediately by calling the screenshot function in postVisit.

// .storybook/test-runner.ts
import type { TestRunnerConfig } from '@storybook/test-runner';
import { screenshot } from '@storycap-testrun/node';

const config: TestRunnerConfig = {
  async postVisit(page, context) {
    await screenshot(page, context, {
      // options...
    });
  },
};

export default config;

[!IMPORTANT] Since the screenshot function automatically performs stability checks internally, waiting functions like waitForPageReady are unnecessary.

$ test-storybook

Then, run @storybook/test-runner.

By default, the screenshot images are saved in the __screenshots__ directory.

TypeScript Setup

Enable type checking for screenshot parameters by extending your Storybook framework's module declaration.

Add this to a .d.ts file in your project (e.g., types/storybook.d.ts):

import type { ScreenshotParameters } from '@storycap-testrun/node';

// Replace it with the framework you are using.
declare module '@storybook/react' {
  interface Parameters {
    screenshot?: ScreenshotParameters;
  }
}

// For other frameworks, replace with your framework's module name

This enables IntelliSense and type checking when defining screenshot parameters in your stories.

API

screenshot(page, context, options)

  • page: Page
    • The Playwright page instance passed in postVisit.
  • context: TestContext
  • options: NodeScreenshotOptions
  • Returns: Promise<void>

Options

Options that can be specified as the third argument in the screenshot function.

output.dir

Type: string
Default: path.join(process.cwd(), '__screenshots__')

Specifies the root directory for saving screenshot images.

output.file

Type: string | ((context: NodeScreenshotContext) => string)
Default: path.join('[title]', '[name].png')

Specifies the file name for the screenshot image of each Story.

When specifying a string, the following templates can be used:

  • [id]: Story ID
  • [title]: Story's title
  • [name]: Story's name

When specifying a function, you can access the context object:

screenshot(page, context, {
  output: {
    file: (context) => path.join(context.title, `${context.name}.png`),
  },
});

flakiness.metrics.enabled

Type: boolean
Default: true

When set to true, it monitors several metrics related to the rendering of the Story and performs stability checks.

[!WARNING] As this process depends on CDP, it works only in Chromium browsers. If enabled in browsers other than Chromium, a warning will be displayed.

flakiness.metrics.retries

Type: number
Default: 1000

The number of retries during metrics monitoring. It continues monitoring for the specified number of frames (1 frame = 16ms) and ensures that the metrics stabilize.

flakiness.retake.enabled

Type: boolean
Default: true

This option calculates the hash value of the screenshot image and checks the stability of the rendering content by ensuring that there are no changes in the image.

[!TIP] In the case of Chromium, flakiness.metrics.enabled alone is often sufficient. Enabling this option means capturing screenshots at least twice, so it's recommended to disable it if it leads to performance degradation.

flakiness.retake.interval

Type: number
Default: 100

The interval in milliseconds before attempting to capture the screenshot again. The second capture is performed immediately for hash checking.

flakiness.retake.retries

Type: number
Default: 10

The number of times to repeat capturing the screenshot until the hash values of the images are identical. A value of 3 or more is recommended to achieve the effect of retries.

hooks

Type: NodeScreenshotHook[]
Default: []

Hooks for interrupting processes before and after screenshot capture. Please specify an object that implements the following interface.

export type BrowserScreenshotHook = {
  setup?: (page: Page, context: NodeScreenshotContext) => Promise<void>;
  preCapture?: (page: Page, context: NodeScreenshotContext) => Promise<void>;
  postCapture?: (
    page: Page,
    context: NodeScreenshotContext,
    filepath: string,
  ) => Promise<void>;
};

Each is executed in the following lifecycle:

| Method | Description | | :------------ | :---------------------------------------------------------- | | setup | Immediately after the screenshot function is executed | | preCapture | After waitForPageReady is executed | | postCapture | After the screenshot is captured, before the image is saved |

The built-in functions like Masking and Removal are implemented using Hooks.

fullPage

Type: boolean
Default: true

See Page | Playwright.

omitBackground

Type: boolean
Default: false

See Page | Playwright.

scale

Type: 'css' | 'device'
Default: 'device'

See Page | Playwright.

Parameters

These are parameters that can be specified for each Story.

// Button.stories.tsx
const meta: Meta<typeof Button> = {
  component: Button,
  parameters: {
    screenshot: {
      /* parameters... */
    },
  },
};

export default meta;

skip

Type: boolean
Default: false

Skips the screenshot capture. Useful in cases where you want to conduct tests with @storybook/test-runner but disable screenshot capture.

delay

Type: number
Default: None

The delay in milliseconds before capturing the screenshot. Waits after completing the basic stability checks.

mask

Type: string | { selector: string; color: string }
Default: None

Masks elements corresponding to the CSS selector with a rectangle. Useful for hiding elements that inevitably differ in content with each render.

remove

Type: string
Default: None

Removes elements corresponding to the CSS selector.

License

MIT © reg-viz

reg-viz