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

@camperaid/watest

v2.6.2

Published

Web Application Testsuite

Readme

watest

WATest (Web Application Testsuite) is a lightweight, minimal-dependency test framework designed for webdriver-based E2E testing. Also works great for unit and integration tests.

Install

npm install @camperaid/watest --save

Add to package.json:

{
  "scripts": {
    "test": "watest"
  }
}

Run tests:

npm test

Project Structure

tests/
├── meta.js          # Root test configuration
├── unit/
│   ├── meta.js      # Folder-specific config
│   ├── t_foo.js     # Test file (t_ prefix)
│   └── t_bar.js
└── e2e/
    ├── meta.js
    └── t_login.js

meta.js Options

Each test folder can have a meta.js file:

// tests/e2e/meta.js
export const folders = ['login', 'checkout']; // Nested test folders
export const services = ['db', 'ws']; // Services to start
export const servicer = 'docker'; // Service manager: 'docker' | 'kubernetes'
export const webdriver = true; // Enable browser testing
export const enabled = process.env.FEATURE_ON; // Optional: true/false, 'true'/'false', or a function returning one
export const init = async () => {
  /* setup */
};
export const uninit = async () => {
  /* teardown */
};

enabled may be:

  • a boolean
  • the string 'true' or 'false'
  • a synchronous function returning one of those values

Skipped suites are omitted from --deps and --grid metadata, and their services are not started.

Configuration

Project Configuration File

Create .watestrc.js in your project root (not in watest):

export default {
  // Test run identifiers (from env or auto-generated)
  run: process.env.WATEST_RUN,
  invocation: process.env.WATEST_INVOCATION,

  // Directories
  log_dir: process.env.WATEST_LOG_DIR,
  tmp_dir: process.env.WATEST_TMP_DIR || '/tmp',

  // Test behavior
  timeout: process.env.WATEST_TIMEOUT || 30000,
  debunk_limit: process.env.WATEST_DEBUNK_LIMIT || 5,

  // WebDriver settings
  webdrivers: process.env.WATEST_WEBDRIVERS,
  webdriver_headless: process.env.WATEST_WEBDRIVER_HEADLESS,
  webdriver_loglevel: process.env.WATEST_WEBDRIVER_LOGLEVEL,
  webdriver_window_width: process.env.WATEST_WEBDRIVER_WINDOW_WIDTH,
  webdriver_window_height: process.env.WATEST_WEBDRIVER_WINDOW_HEIGHT,

  // Integration hooks (absolute paths to your project files)
  servicer: './tests/servicer.js', // Manages test services
  logger: './tests/logserver.js', // Remote test logging

  // Optional: ignore pattern
  ignore_pattern: process.env.WATEST_IGNORE_PATTERN,
};

Note: This file should be created in your project root (where you run watest), not inside the watest directory itself.

Environment Variables

Watest reads configuration from environment variables. Create .env in your project root or export them:

# Test execution
WATEST_RUN=run-123                           # Optional: Group multiple test invocations
WATEST_INVOCATION=inv-456                    # Optional: Unique invocation identifier
WATEST_TIMEOUT=30000                         # Test timeout in milliseconds
WATEST_DEBUNK_LIMIT=5                        # Max retry attempts for flaky tests

# Directories
WATEST_LOG_DIR=/tmp/watest                   # Test logs directory
WATEST_TMP_DIR=/tmp                          # Temporary files directory

# WebDriver
WATEST_WEBDRIVERS='["chrome","firefox"]'     # Browser list (JSON array)
WATEST_WEBDRIVER_HEADLESS=true               # Run browsers headless
WATEST_WEBDRIVER_LOGLEVEL=info               # WebDriver log level
WATEST_WEBDRIVER_WINDOW_WIDTH=1280           # Browser window width
WATEST_WEBDRIVER_WINDOW_HEIGHT=1024          # Browser window height

# Integration
WATEST_LOGGER_MODULE=./tests/logserver.js    # Path to logger module
WATEST_SERVICER_MODULE=./tests/servicer.js   # Path to servicer module
WATEST_IGNORE_PATTERN=_browser\.js$          # Regex for files to skip

Webdrivers

Built-in webdriver configurations:

  • chrome - Chrome browser
  • chrome-mobile - Chrome with iPhone emulation
  • firefox - Firefox browser
  • safari - Safari browser

CLI Options

watest [options] [patterns...]

Options:
  --skip-on-fail  Skip remaining tests in folder after first failure
  --timeout       Set webdriver condition timeout (ms)
  --debunk        Re-run passing test until it fails (flakiness detection)
  -v, --verify    Re-run failing tests
  --deps          Output metadata (servicers, services) as JSON
  --grid          Output grid metadata for distributed testing
  -h, --help      Show help

Examples

watest                           # Run all tests
watest tests/unit                # Run specific folder
watest tests/e2e/t_login.js      # Run specific file
watest chrome firefox            # Run with multiple browsers
watest --debunk tests/e2e        # Find flaky tests

Test API

Assertions

import { ok, is, contains, throws, no_throws } from '@camperaid/watest';

ok(value, 'value is truthy');
is(got, expected, 'values match');
contains(array, expected, 'array contains values');
throws(() => fn(), 'throws error');
no_throws(() => fn(), 'does not throw');

Reporting

import { success, fail, info, warn, todo, group } from '@camperaid/watest';

group('User authentication');
success('login completed');
fail('validation failed');
info('processing 100 items');
warn('deprecated API used');
todo('implement logout');

Utilities

import { assert, not_reached, inspect } from '@camperaid/watest';

assert(condition, 'condition must be true'); // Fails with stack trace
not_reached('should not get here'); // Always fails with stack trace
inspect(object); // Pretty-print object

Test Helpers

import { test_is, test_contains } from '@camperaid/watest';

// Silent checks (no success/fail logging)
if (test_is(got, expected)) {
  /* ... */
}
if (test_contains(array, subset)) {
  /* ... */
}

Integration Testing

Configure a servicer in .watestrc.js to manage services. The servicer interface (interfaces/servicer.js) must implement:

  • start(services) - Start services
  • stop() - Stop services

When watest encounters services in meta.js, it calls the servicer to start/stop services.

E2E Testing

Driver

Chainable wrapper around Selenium WebDriver:

import { scope } from '@camperaid/watest';

export const test = scope('https://example.com', async session => {
  await session.driver
    .get('/')
    .findElement('#login')
    .click()
    .findElement('#email')
    .sendKeys('[email protected]');
});

AppDriver

Base class for page object patterns:

import { AppDriver } from '@camperaid/watest';

class LoginPage extends AppDriver {
  login({ email, password }) {
    return this.chain(() =>
      this.action('Login')
        .sendKeys(this.Email, email)
        .sendKeys(this.Password, password)
        .click(this.Submit),
    );
  }

  getSelectors() {
    return {
      Self: '#login-page',
      Email: '#email',
      Password: '#password',
      Submit: 'button[type=submit]',
    };
  }
}

ControlDriver

Base class for reusable UI component drivers (dropdowns, modals, etc.).

Expected Failures

Handle known intermittent or permanent failures in meta.js:

export const expected_failures = [
  [
    'test_file.js', // or '*' for all files
    [[platform, type, group, failures, description]],
  ],
];
  • platform: 'all', 'darwin', 'linux', 'darwin-chrome', etc.
  • type: 'perma' or 'intermittent'
  • group: Test group name or '*'
  • failures: Array of failure message patterns
  • description: Human-readable description

Example:

export const expected_failures = [
  [
    '*',
    [
      ['all', 'intermittent', '*', ['socket hang up'], 'Network flakiness'],
      ['darwin-safari', 'perma', '*', ['WebDriver timeout'], 'Safari bug'],
    ],
  ],
];

ES Module Mocking

Enable custom module resolution in meta.js:

export const loader = true;

export async function resolve(specifier, context, defaultResolve) {
  if (specifier === './api.js') {
    specifier = './api_mock.js';
  }
  return defaultResolve(specifier, context, defaultResolve);
}

Grid Metadata for Distributed Testing

Watest provides metadata helpers for external orchestrators to distribute tests across multiple workers. Define grid splits in meta.js:

// tests/meta.js
export const grid = {
  'e2e+': ['tests/e2e'], // '+' = split per browser
  'www+': ['tests/www'],
  'services': ['tests/services', 'tests/integration'],
  'misc': ['tests/lib', 'tests/ops'],
};

Query metadata for orchestration:

# Get grid metadata as JSON
watest --grid
watest --grid chrome firefox
watest --grid tests/e2e tests/www

# Get dependency metadata (servicers, services)
watest --deps tests/e2e

Note: Watest doesn't implement distributed test execution. These flags output metadata (JSON) that orchestration tools use to spawn workers and split test workload.

System Commands

import {
  runCommand,
  execCommand,
  spawn,
  runBashScript,
} from '@camperaid/watest';

// Run command, log output
await runCommand('npm', ['install']);

// Run command, capture output
const { stdout, stderr, code } = await execCommand('git', ['status']);

// Spawn with custom handling
const proc = spawn('node', ['server.js']);

// Run bash script
await runBashScript('setup.sh');

License

MPL-2.0