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

playhar

v0.0.8

Published

Record HAR files from browser sessions and convert them into structured mocks for automated testing. Combines Mustachr and Workhar into a complete capture → sanitize → replay workflow.

Readme

Playhar 🎭

Playhar is a CLI and TypeScript library that extends the power of mustachr and workhar to help you record, sanitize, and replay API traffic in Playwright tests.

It helps you:

  • Record real API traffic using Playwright.
  • Replace secrets or dynamic values with {{ mustache }} tokens.
  • Extract responses into editable .json files.
  • Rebuild those .har files for use with page.routeFromHAR().

Installation

npm install --save-dev playhar

Also ensure you have Playwright installed:

npm install -D @playwright/test

Example: Mocking a Login Flow

Here's how you can use Playhar to record and mock an authenticated login flow, including sensitive data redaction and dynamic token injection.


1. Install Playhar

npm install --save-dev playhar

2. Create playhar.config.ts

This config sets up Playhar to record network traffic, extract secrets, and sanitize responses automatically:

import { defineConfig } from 'playhar';

export default defineConfig({
  directory: './tests/playhar',
  baseRequestUrl: 'https://example.com/api',
  extractions: [
    // Extract secrets from .env.test
    {
      type: 'env',
      path: '.env.test',
    },
    // Extract Bearer auth header tokens
    {
      type: 'regex',
      property: 'BEARER_TOKEN',
      search: '\\bBearer\\s+([A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+\\.[A-Za-z0-9\\-_]+|\\w{20,})',
      replace: 'Bearer {{ property }}'
    },
    // Extract auth tokens from responses
    {
      type: 'regex',
      property: 'BEARER_TOKEN',
      search: '\\"token\\":\\"[^"]*\\"',
      replace: '"token":"{{ property }}"'
    },
  ],
});

3. Create a .env.test File

Store your real test credentials here:

[email protected]
VITE_TEST_PASSWORD=cR45H 0V3r1D3

These values will be replaced with mustache templates during recording.

4. Record a Flow

  1. Run your app in development mode:
npm run dev
  1. Start recording:
npx playhar record
  1. When prompted:

    • Recording name: login-flow
    • URL: http://localhost:5173
  2. Playwright will launch a Chromium browser.

  3. Click the "Record" button in the Playwright dialog.

  4. Complete the login process in your app.

  5. Click "Stop Recording" and copy the generated Playwright script (if you want).

  6. Click "Continue" to finish recording.

Playhar will automatically sanitize the recorded HAR file and extract all API responses into structured JSON files.

5. Create Your Test

Install jsonwebtoken to dynamically generate a fake token for your tests:

npm install jsonwebtoken

Then create a Playwright test file like login.spec.ts:

import { expect, test } from '@playwright/test';
import * as playhar from 'playhar';
import jwt from 'jsonwebtoken';

test('Login flow', async ({ page }) => {

    // Generate a fake JWT token.
    const token = jwt.sign(
        { userId: '123', email: '[email protected]' },
        'fake-secret',
        { expiresIn: '1h' }
    );

    // Define dynamic injections for the test
    const injections = playhar.defineInjections({
        BEARER_TOKEN: token,
        VITE_TEST_EMAIL: '[email protected]',
        VITE_TEST_PASSWORD: 'password',
    });

    // Rebuild the mocked HAR with injected values
    const har = await playhar.mock({
        name: 'login-flow',
        injections,
    });

    // Route all API calls through the mocked HAR
    await page.routeFromHAR(har, {
        url: 'https://example.com/api',
    });

    // Perform the login actions
    await page.goto('http://localhost:5173/login');
    await page.getByRole('textbox', { name: 'Email address' }).fill(injections.VITE_TEST_EMAIL);
    await page.getByRole('textbox', { name: 'Password' }).fill(injections.VITE_TEST_PASSWORD);
    await page.getByRole('button', { name: 'Log in' }).click();

    // Validate success
    await page.waitForTimeout(3000);
    await expect(page.locator('#dom-body')).toContainText('Welcome, John 👋');
});

6. Result

✅ Your test now mocks the backend, uses dynamic tokens, and never leaks secrets into your fixtures! ✅ You can run it offline, without relying on a real backend.


Example: Editing Recorded Fixtures

One of Playhar's biggest strengths is that your API responses are stored as editable JSON files.

After recording a flow, you can open the extracted JSON files and modify them manually to fit your test scenarios.


Modify the HAR JSON fixtures

Suppose you want your test to validate the user's name as "Dade Murphy" instead of the originally recorded "John Doe."

Locate the extracted JSON file(s):

recordings/
    └── login-flow/
        └── json/
            └── https:/
                └── example.com/
                        └── api/
                            └── auth/
                                └── login_0.json

Modify the JSON:

Before:

{
    "statusCode": 200,
    "success": true,
    "message": "User Authorized",
    "token": "{{ BEARER_TOKEN }}",
    "user": {
        "_id": "5fc70d8cf1d4867c0eff5fed7700eff48",
        "firstName": "John",
        "lastName": "Doe",
        ...
    }
}

After:

{
    "statusCode": 200,
    "success": true,
    "message": "User Authorized",
    "token": "{{ BEARER_TOKEN }}",
    "user": {
        "_id": "5fc70d8cf1d4867c0eff5fed7700eff48",
        "firstName": "Dade", // <-- Updated
        "lastName": "Murphy", // <-- Updated
        ...
    }
}

Update your test assertion:

await expect(page.locator('#dom-body')).toContainText('Welcome, Dade 👋');

✅ You didn't need to re-record the flow.
✅ You didn't have to mock network requests manually.
✅ You kept the test fast, predictable, and fully offline.


Pro Tip

You can even script changes to your JSON files if you want to generate different test states — like multiple users, different roles, or edge cases.


CLI Usage

playhar record --url <url> [options]
playhar mock [options]

playhar record

Launches a browser, records network traffic to a .har file, replaces values using mustachr, and extracts .json responses using workhar.

playhar record --url http://localhost:5173 --config ./playhar.config.ts

You’ll be prompted to name the recording (e.g., auth-flow), and specify the URL to open for recording in the browser. Once finished interacting, close the browser to complete the recording and extraction process.


playhar mock

Rebuilds a HAR file from extracted JSON responses, optionally injecting values back into mustache tokens.

playhar mock --config ./playhar.config.ts --name auth-flow --injections ./injections.json --out ./mocked.har

You can then use the rebuilt .har in a test:

await page.routeFromHAR('./mocked.har');

Programmatic API

import { record, mock, configFromFile } from 'playhar';

const config = await configFromFile({
    file: './playhar.config.ts',
    fallbacks: [],
});

await record({
    config,
    name: 'auth-flow',
    url: 'http://localhost:5173',
});

await mock({
    config,
    name: 'auth-flow',
    injections: {
        SECRET_TOKEN: 'mocked-token',
    },
    toHarFile: './mocked.har',
});

Folder Structure

recordings/
  └── auth-flow/
       ├── api.har          ← Extracted & templated HAR
       ├── .workhar         ← Internal mapping file
       └── json/            ← Individual response files

File Types

  • .har: The Playwright-recorded HAR file (sanitized with mustache tokens).
  • .json: Extracted response bodies for each request.
  • .workhar: Internal mapping of requests/responses used by Workhar.

Testing

Playhar ships with 100% test coverage using Vitest.

npm test

License

MIT © 2025