# playwright-test

> Run mocha, zora, uvu, tape and benchmark.js scripts inside real browsers with playwright.

Latest version **14.1.15** (published 2026-05-28) · MIT license · 0 weekly downloads

## Install

```sh
npm install playwright-test
pnpm add playwright-test
yarn add playwright-test
bun add playwright-test
```

Provides the commands `pw-test`, `playwright-test`.

## Health

**Score 65/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 14.1.15 |
| Published | 2026-05-28 |
| First published | 2020-02-13 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=16.0.0 |
| Dependencies | 33 |
| Unpacked size | 242.3 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| Author | Hugo Dias <hugomrdias@gmail.com> (hugodias.me) |
| Maintainers | achingbrain, hugomrdias |
| Keywords | playwright, test, tests, test-runner, mocha, tape, benchmark, benchmark.js, zora, coverage, istanbul, nyc, code coverage, uvu |

## Links

- npm: https://www.npmjs.com/package/playwright-test
- Repository: hugomrdias/playwright-test
- npm.io page: https://npm.io/package/playwright-test

## Dependencies (33)

- [c8](https://npm.io/package/c8.md) ^10.1.3
- [ora](https://npm.io/package/ora.md) ^9.0.0
- [sade](https://npm.io/package/sade.md) ^1.8.1
- [sirv](https://npm.io/package/sirv.md) ^3.0.0
- [util](https://npm.io/package/util.md) ^0.12.5
- [execa](https://npm.io/package/execa.md) ^9.3.0
- [kleur](https://npm.io/package/kleur.md) ^4.1.5
- [polka](https://npm.io/package/polka.md) ^0.5.2
- [tempy](https://npm.io/package/tempy.md) ^3.1.0
- [assert](https://npm.io/package/assert.md) ^2.1.0
- [buffer](https://npm.io/package/buffer.md) ^6.0.3
- [events](https://npm.io/package/events.md) ^3.3.0
- [lodash](https://npm.io/package/lodash.md) ^4.17.21
- [nanoid](https://npm.io/package/nanoid.md) ^5.0.9
- [esbuild](https://npm.io/package/esbuild.md) 0.25.11
- [premove](https://npm.io/package/premove.md) ^4.0.0
- [process](https://npm.io/package/process.md) ^0.11.10
- [chokidar](https://npm.io/package/chokidar.md) ^4.0.3
- [camelcase](https://npm.io/package/camelcase.md) ^9.0.0
- [exit-hook](https://npm.io/package/exit-hook.md) ^4.0.0
- [lilconfig](https://npm.io/package/lilconfig.md) ^3.1.3
- [p-timeout](https://npm.io/package/p-timeout.md) ^6.1.4
- [source-map](https://npm.io/package/source-map.md) 0.6.1
- [tinyglobby](https://npm.io/package/tinyglobby.md) ^0.2.14
- [acorn-loose](https://npm.io/package/acorn-loose.md) ^8.3.0
- [test-exclude](https://npm.io/package/test-exclude.md) ^7.0.1
- [merge-options](https://npm.io/package/merge-options.md) ^3.0.4
- [v8-to-istanbul](https://npm.io/package/v8-to-istanbul.md) ^9.3.0
- [path-browserify](https://npm.io/package/path-browserify.md) ^1.0.1
- [playwright-core](https://npm.io/package/playwright-core.md) 1.60.0
- [stream-browserify](https://npm.io/package/stream-browserify.md) ^3.0.0
- [source-map-support](https://npm.io/package/source-map-support.md) ^0.5.21
- [esbuild-plugin-wasm](https://npm.io/package/esbuild-plugin-wasm.md) ^1.1.0

## Alternatives

- [duck](https://npm.io/package/duck.md) — 4.2M weekly downloads
- [ava](https://npm.io/package/ava.md) — 560.2K weekly downloads
- [storybook-addon-module-mock](https://npm.io/package/storybook-addon-module-mock.md) — 71.7K weekly downloads
- [vest](https://npm.io/package/vest.md) — 50.1K weekly downloads
- [@ethereum-waffle/mock-contract](https://npm.io/package/@ethereum-waffle/mock-contract.md) — 40.0K weekly downloads

## Recent versions

- 14.1.15 (latest) — 2026-05-28
- 14.1.13 — 2026-03-18
- 14.1.12 — 2025-08-12
- 14.1.11 — 2025-07-21
- 14.1.10 — 2025-07-21
- 14.1.9 — 2025-02-11
- 14.1.8 — 2025-02-10
- 14.1.7 — 2024-11-19
- 14.1.6 — 2024-09-10
- 14.1.5 — 2024-09-06
- 14.1.4 — 2024-07-23
- 14.1.3 — 2024-05-07
- 14.1.2 — 2024-05-02
- 14.1.1 — 2024-02-08
- 14.1.0 — 2024-01-31
- … 91 more at https://npm.io/package/playwright-test/versions

## README

# playwright-test [![NPM Version](https://img.shields.io/npm/v/playwright-test.svg)](https://www.npmjs.com/package/playwright-test) [![NPM Downloads](https://img.shields.io/npm/dt/playwright-test.svg)](https://www.npmjs.com/package/playwright-test) [![NPM License](https://img.shields.io/npm/l/playwright-test.svg)](https://www.npmjs.com/package/playwright-test) ![tests](https://github.com/hugomrdias/playwright-test/workflows/tests/badge.svg)

> Run mocha, zora, uvu, tape and benchmark.js scripts inside real browsers with `playwright`.

## Install

```shell
pnpm install playwright-test
```

## Usage

```shell
playwright-test [files] [options]
# or
pw-test [files] [options]

```

## Options

```shell
Description
    Run mocha, zora, uvu, tape and benchmark.js scripts inside real browsers with `playwright` and in Node.

  Usage
    $ playwright-test [files] [options]

  Options
    -r, --runner       Test runner. Options: mocha, tape, zora, uvu, none, taps and benchmark. Internal runners are autodetected by default. It also accepts a path to a module or a module ID that exports a `playwrightTestRunner` object.
    -b, --browser      Browser to run tests. Options: chromium, firefox, webkit.  (default chromium)
    -m, --mode         Run mode. Options: main, worker and node.  (default main)
    -d, --debug        Debug mode, keeps browser window open.  (default false)
    -w, --watch        Watch files for changes and re-run tests.
    -i, --incognito    Use incognito window to run tests.  (default false)
    -e, --extension    Use extension background_page to run tests.  (default false)
    --cov              Enable code coverage in istanbul format. Outputs '.nyc_output/coverage-pw.json'.  (default false)
    --report-dir       Where to output code coverage in instanbul format.  (default .nyc_output)
    --before           Path to a script to be loaded on a separate tab before the main script.
    --sw               Path to a script to be loaded in a service worker.
    --assets           Folder with assets to be served by the http server.  (default process.cwd())
    --cwd              Current directory.  (default /Users/hd/code/playwright-test)
    --extensions       File extensions allowed in the bundle.  (default js,cjs,mjs,ts,tsx)
    --config           Path to the config file
    -v, --version      Displays current version
    -h, --help         Displays this message


  Examples
    $ playwright-test test.js --runner tape
    $ playwright-test test --debug
    $ playwright-test "test/**/*.spec.js" --browser webkit --mode worker --incognito --debug

    $ playwright-test bench.js --runner benchmark
    # Uses benchmark.js to run your benchmark see playwright-test/mocks/benchmark.js for an example.

    $ playwright-test test --cov && npx nyc report --reporter=html
    # Enable code coverage in istanbul format which can be used by nyc.

    $ playwright-test "test/**/*.spec.js" --debug --before ./mocks/before.js
    # Run a script in a separate tab. Check ./mocks/before.js for an example.
    # Important: You need to call `self.PW_TEST.beforeEnd()` to start the main script.

  Runner Options
    All arguments passed to the cli not listed above will be fowarded to the runner.
    $ playwright-test test.js --runner mocha --bail --grep 'should fail'

    To send a `false` flag use --no-bail.
    Check https://mochajs.org/api/mocha for `mocha` options or `npx mocha --help`.

  Notes
    DEBUG env var filtering for 'debug' package logging will work as expected.
    $ DEBUG:app playwright-test test.js

    Do not let your shell expand globs, always wrap them.
    $ playwright-test "test/**" GOOD
    $ playwright-test test/** BAD
```

## Client

This client package exposes the `playwright-test` options and some Playwright browser context methods to be used in tests.

```ts
import * as Client from 'playwright-test/client'

it('should setoffline', async () => {
  if (Client.mode === 'main' && Client.options.extension === false) {
    globalThis.addEventListener('offline', () => {
      console.log('offlineee')
    })
    await Client.context.setOffline(true)
    equal(navigator.onLine, false)
    await Client.context.setOffline(false)
    equal(navigator.onLine, true)
  }
})

it('should geolocation', async () => {
  if (Client.mode === 'main') {
    const deferred = pdefer()
    await Client.context.setGeolocation({
      latitude: 59.95,
      longitude: 30.316_67,
    })
    await Client.context.grantPermissions(['geolocation'])

    navigator.geolocation.getCurrentPosition((position) => {
      deferred.resolve(position)
    })

    const position = (await deferred.promise) as GeolocationPosition
    equal(position.coords.latitude, 59.95)
  }
})
```

## Flow control

All test runners support automatic flow control, which means you don't need to call special function or trigger any event in your tests to stop the run. The `none` runner does not support flow control.

To manually stop the run you can use `process.exit`:

```js
process.exit(0) // stops the run and exits with success
process.exit(1) // stops the run and exits with failure
```

## Custom test runner

You can define a custom test runner by passing a path to a file or a node module id that exports an object called `playwrightTestRunner` that implements the `TestRunner` interface.

```shell

$ playwright-test test.js --runner ./my-runner.js
# or
$ playwright-test test.js --runner my-runner

```

You can also just define you test runner in the config file.

```js
// playwright-test.config.js
/** @type {import('../src/runner.js').RunnerOptions} */
const config = {
  testRunner: {
    compileRuntime: (options, paths) => {
      return `
import mocha from 'mocha/mocha.js'
mocha.setup({
    reporter: 'spec',
    timeout: 5000,
    ui: 'bdd',
})

${paths.map((url) => `await import('${url}')`).join('\n')}

  mocha
    .run((f) =>{
      process.exit(f)
    })
        `
    },
  },
}

export default config
```

````ts
export interface TestRunner {
  /**
   * Module ID name used to import the test runner runtime.
   * Used in auto detection of the test runner.
   */
  moduleId: string
  /**
   * Options made available to the compiled runtime.
   * This is useful to pass options to the test runner.
   *
   * @example
   * ```js
   * const options = JSON.parse(process.env.PW_OPTIONS)
   * const testRunnerOptions = options.testRunner.options
   * ```
   */
  options?: unknown
  /**
   * Esbuild config for the test runner
   */
  buildConfig?: BuildOptions
  /**
   * Compile runtime entry point for esbuild
   *
   * @param options - Runner options
   * @param testPaths - Test paths
   * @returns
   */
  compileRuntime: (options: RunnerOptions, testPaths: string[]) => string
}
````

## Config

> The config file needs to be commonjs for now, so if your package is pure ESM you need to use `.cjs` extension.

Configuration can be done with cli flags or config files.

```text
package.json, // using property `pw-test` or `playwright-test`
.playwright-testrc.json,
.playwright-testrc.js,
.playwright-testrc.cjs,
playwright-test.config.js,
playwright-test.config.cjs,
.pw-testrc.json,
.pw-testrc.js,
.pw-testrc.cjs,
pw-test.config.js,
pw-test.config.cjs,
.config/playwright-testrc.json
.config/playwright-testrc.js
.config/playwright-testrc.cjs
.config/pw-testrc.json
.config/pw-testrc.js
.config/pw-testrc.cjs
```

The config type can be imported from the entrypoint.

```ts
/** @type {import('playwright-test').RunnerOptions} */
const config = {
  // ...
}

export default config
```

The config file can also export a function that receives the cli options as argument.

```ts
/** @type {import('playwright-test').ConfigFn} */
function buildConfig(cliOptions) {
  return {
    buildConfig: {
      bundle: cliOptions.mode !== 'node',
    },
  }
}

export default buildConfig
```

### Interface

```ts
export interface RunnerOptions {
  input?: string[]
  testRunner: TestRunner
  cwd: string
  extensions: string
  browser: 'chromium' | 'firefox' | 'webkit'
  debug: boolean
  mode: 'main' | 'worker' | 'node'
  incognito: boolean
  extension: boolean
  assets: string
  before?: string
  sw?: string
  cov: boolean
  reportDir: string
  buildConfig: BuildOptions
  buildSWConfig: BuildOptions
  browserContextOptions?: BrowserContextOptions
  beforeTests: (opts: RunnerOptions) => Promise<unknown>
  afterTests: (
    opts: RunnerOptions,
    beforeTestsOutput: unknown
  ) => Promise<unknown>
}
```

## Run in CI

Check our CI config `.github/workflows/main.yml` and the playwright [Github Action](https://playwright.dev/docs/ci/#github-actions)

## License

MIT © [Hugo Dias](http://hugodias.me)

---
_Source: https://npm.io/package/playwright-test · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
