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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@impulselab/testing

v0.0.11

Published

E2E testing library with Puppeteer for browser automation

Readme

Impulse Testing

E2E testing library that records user interactions and replays them as automated tests

Impulse Testing is a modern E2E testing library built on Puppeteer that allows you to record real user interactions in your browser and automatically replay them as tests. No coding required for test creation! Just click, type, and interact naturally with your application.

Key Features

  • 📹 Interactive Recording: Record user interactions as YAML stories in a visible browser
  • 🔄 Automated Replay: Execute stories headlessly for fast, reliable testing
  • 📸 Visual Regression: Screenshot comparison with pixel-perfect diff detection
  • 🎯 Smart Selectors: Automatic generation of stable CSS selectors for elements
  • 💻 CLI Interface: Intuitive interactive shell for story management
  • 🚀 CI/CD Ready: Non-interactive mode designed for continuous integration
  • ⚡ Zero Config: Interactive onboarding with auto-detection of project types

Quick Start

1. Initialize Your Project

Run Impulse Testing for the first time to set up your project:

npx @impulselab/testing --init

The interactive onboarding will:

  • Create the .testing/ directory structure
  • Generate a config.yml with your project settings
  • Auto-detect your framework (Next.js, Vite, etc.)
  • Configure lifecycle commands for starting/stopping your application

2. Record Your First Story

Create a new test by recording your interactions:

npx @impulselab/testing --new

Then:

  1. Enter a name for your story (e.g., "User Login Flow")
  2. Confirm or edit the auto-generated ID (e.g., user-login-flow)
  3. Enter your application's start URL (default: http://localhost:3000)
  4. A browser window will open—interact with your app naturally
  5. Click "Take Snapshot" to capture screenshots at key moments
  6. Click "Stop Recording" when done

Your interactions are saved as a reusable YAML story in .testing/stories/{story-id}/story.yml.

3. Run Tests

Interactive Mode (Local Development)

npx @impulselab/testing

Select a story from the list and watch it execute. If screenshots differ, you'll see a visual diff and can choose to accept or reject changes.

CI Mode (Automated Testing)

npx @impulselab/testing --ci

Runs all stories headlessly with automatic failure on screenshot mismatches. Perfect for CI/CD pipelines.

CLI Commands

Default Mode (Interactive)

npx @impulselab/testing

Opens an interactive shell where you can:

  • Browse and select existing stories
  • Create new stories
  • Execute tests with visual feedback

Recording Mode

npx @impulselab/testing --new

Directly starts the story creation flow, skipping the interactive menu.

CI/CD Mode

npx @impulselab/testing --ci

Runs all stories in non-interactive mode:

  • No user prompts
  • Auto-fails on screenshot mismatches
  • Proper exit codes (0 = pass, 1 = fail)

Run Specific Stories

# Run a single story
npx @impulselab/testing --story user-login

# Run multiple stories
npx @impulselab/testing --story login --story checkout --story profile

# Run specific stories in CI mode
npx @impulselab/testing --ci --story login --story checkout

Help and Version

npx @impulselab/testing --help
npx @impulselab/testing --version

Configuration

Config File Structure

Impulse Testing uses .testing/config.yml to manage your test environment:

lifecycle:
  start:
    - command: "npm run dev"
      keepAlive: true    # Keep process running during tests
    - command: "npm run db:start"
      timeout: 10000     # 10 seconds to for database startup
  stop:
    - command: "npm run db:stop"
      timeout: 10000

screenshots:
  diffThreshold: 0.001  # Percentage of pixels allowed to differ (0-100), we recommand using the smaller number possible

Configuration Options

lifecycle.start: Commands to start your application

  • command: Shell command to execute
  • keepAlive: If true, process stays running; if false, waits for completion
  • timeout: Maximum time to wait (milliseconds)

lifecycle.stop: Commands to stop your application and clean up resources

screenshots.diffThreshold: Tolerance for pixel differences

  • 0: Pixel-perfect matching (strictest)
  • 0.001: Allow 0.001% of pixels to differ (recommended)
  • Higher values: More tolerant of minor rendering differences

Story Structure

Stories are stored as YAML files in .testing/stories/{story-id}/story.yml:

id: user-login-flow
name: User Login Flow
start:
  url: http://localhost:3000
  resolution:
    width: 1920
    height: 1080
  pixelRatio: 1
  deviceScaleFactor: 1
actions:
  - type: click
    selector: "#login-button"
  - type: input
    selector: "#email"
    value: "[email protected]"
  - type: input
    selector: "#password"
    value: "password123"
  - type: click
    selector: "#submit-button"
  - type: screenshot
    name: "1760513305222-zd1kqk.png"

Available Action Types

Navigation Actions

  • navigate: Navigate to a URL
  • goBack: Browser back button
  • goForward: Browser forward button
  • reload: Reload current page

Interaction Actions

  • click: Click an element
  • input: Type text into an input field
  • select: Select dropdown option
  • check: Check a checkbox or radio button
  • uncheck: Uncheck a checkbox
  • hover: Hover over an element
  • focus: Focus an element
  • blur: Remove focus from an element

Scrolling Actions

  • scroll: Scroll the page
  • scrollIntoView: Scroll element into viewport

Wait Actions

  • wait: Wait for specified milliseconds
  • waitForSelector: Wait for element to appear
  • waitForNavigation: Wait for page navigation

Advanced Actions

  • uploadFile: Upload files to file inputs
  • executeScript: Execute custom JavaScript
  • screenshot: Capture and compare screenshot

Selector Strategy

Impulse Testing automatically generates stable CSS selectors using this priority:

  1. ID attribute (#unique-id) - Most stable and preferred
  2. Test attributes ([data-testid="value"], [data-test="value"]) - Recommended for test stability
  3. Complex selectors - Auto-generated using classes and structure

Best Practice: Add data-testid attributes to important elements for more reliable tests.

Workflow

Recording Workflow

  1. Start Recording: Run npx @impulselab/testing --new
  2. Provide Metadata: Enter story name, ID, and start URL
  3. Interact Naturally: Click, type, and navigate as a real user would
  4. Capture Snapshots: Click "Take Snapshot" button at key moments to capture visual states
  5. Stop Recording: Click "Stop Recording" when your user flow is complete
  6. Story Saved: Actions and screenshots are automatically saved to .testing/stories/

Testing Workflow

Local Development

  1. Run Interactive Mode: npx @impulselab/testing
  2. Select Story: Choose from the list of available stories
  3. Watch Execution: See each action execute in real-time
  4. Review Results: If screenshots differ:
    • VS Code diff viewer opens automatically
    • Choose to accept new screenshot or keep baseline
    • Test passes only if you accept changes

CI/CD Pipeline

  1. Add to Pipeline: Add npx @impulselab/testing --ci to your CI config
  2. Automatic Execution: All stories run headlessly without user interaction
  3. Screenshot Validation: Any pixel differences cause test failure
  4. Exit Codes:
    • 0 = All tests passed
    • 1 = One or more tests failed

Example GitHub Actions:

name: E2E Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: '18'
      - run: npm install
      - run: npx @impulselab/testing --ci

Screenshot Comparison

Visual Regression Testing

When a story includes screenshot actions, Impulse Testing automatically:

  1. Captures the current viewport as a PNG image
  2. Compares pixel-by-pixel with the baseline screenshot
  3. Calculates the percentage of different pixels
  4. Applies Threshold: Uses diffThreshold from config (default 0.1%)

Resolution Modes

Interactive Mode (Local)

When differences are detected:

  • Opens VS Code diff viewer showing side-by-side comparison
  • Presents CLI prompt with two options:
    • Keep old screenshot (fail test): Baseline unchanged, test marked as failed
    • Accept new screenshot (update baseline): Baseline updated, test passes
  • User navigates with arrow keys and confirms with Enter

CI Mode (Automated)

When differences are detected:

  • Automatically keeps old screenshot
  • Marks test as failed
  • No user interaction required
  • No baseline updates

Project Structure

.testing/                      # All test-related files
├── config.yml                 # Main configuration file
├── stories/                   # Test stories organized by ID
│   ├── user-login-flow/
│   │   └── story.yml          # Story actions and metadata
│   ├── checkout-process/
│   │   └── story.yml
│   └── ...
├── screenshots/               # Reference screenshots for comparison
│   ├── user-login-flow/
│   │   ├── 0.png
│   │   ├── 1.png
│   │   └── ...
│   └── ...
└── temp/                      # Temporary files (mismatched screenshots, errors)
    ├── error-1234567890.png   # Diagnostic screenshots on failures
    └── ...

Important Files:

  • config.yml: Application lifecycle, screenshot settings, output options
  • stories/{id}/story.yml: Recorded actions and test metadata
  • screenshots/{id}/*.png: Baseline images for visual regression testing

Development

Building from Source

# Clone repository
git clone https://github.com/impulse-studio/testing.git
cd testing

# Install dependencies
pnpm install

# Build TypeScript
pnpm build

# Run in development mode (uses demo/ directory)
pnpm dev

Development Scripts

# Format code with Biome
pnpm format

# Type checking and linting
pnpm checks

# Run built CLI
pnpm start

Project Scripts

  • pnpm build: Compile TypeScript to dist/
  • pnpm dev: Run CLI in development mode against demo/ directory
  • pnpm format: Auto-format code using Biome
  • pnpm checks: Run TypeScript compiler and Biome linter (no emitting)

Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

License

See LICENSE for details


Built with: PuppeteerTypeScriptZodCommander.jsInquirer by Impulse Lab