Testify is a test execution engine for real browsers and Node.js. It gives you a simple path from install to running specs, then layers on smart features like watch mode, HMR, coverage, and a live browser Playground when you need them.
Jasmine is the test language Testify currently hosts. Testify owns discovery, planning, runtime control, and execution. Jasmine owns describe and it. That split is what lets the same specs run in Node.js for speed or in a real browser when the DOM starts making demands.
- Real browser testing in Chrome, Firefox, and WebKit. No simulated DOM pretending to be brave.
- Fast Node.js execution for specs that do not need a browser at all.
- Watch mode with HMR so source and spec edits show up quickly without full-page drama.
- TypeScript and source maps out of the box for readable stacks and reliable breakpoints.
- Code coverage in HTML, LCOV, and text formats.
- Single-spec debugging when one stubborn test needs a private conversation.
- A live Playground in DevTools for inspecting tests, shaping plans, rerunning failures, and exploring the session interactively.
npm install --save-dev @epikodelabs/testify
npx playwright installnpm install does not run a Testify postinstall script or quietly reshape your project. Browser binaries are installed only when you ask for them.
npx testifyTestify is meant to be useful immediately. Install it, point it at your specs, and run.
Write ordinary Jasmine specs:
// tests/calculator.spec.ts
import { Calculator } from '@contoso/calculator';
describe('Calculator', () => {
it('should add', () => {
expect(new Calculator().add(2, 3)).toBe(5);
});
});Run them in the mode that fits the moment:
npx testify
npx testify --headless
npx testify --browser node
npx testify --coverage
npx testify --watch| Mode | Command | Best For |
|---|---|---|
| Browser (headed) | npx testify |
Development, debugging |
| Headless browser | npx testify --headless [--browser firefox|webkit] |
CI/CD |
| Node.js | npx testify --browser node |
Fast unit tests |
| Watch | npx testify --watch |
Rapid iteration |
Notes:
--watchrequires headed browser mode and is incompatible with--headless,--coverage, and--browser node.--coverageis incompatible with--watch.- If Node mode gets chatty, use
--silentor--quiet.
In headed watch mode, DevTools gets a live session object. The console stops being a dump of log lines and becomes a control surface.
Start by seeing what exists:
session.tests()
session.suites()
session.files()Build a plan:
const plan = session
.plan()
.filter(test => /validation/i.test(test.fullName));Run it:
await session.execute(plan);Inspect what happened:
session.last()
session.failures()Repeat the whole thing or just the failures:
await session.rerun()
await session.retry()Need the live reference:
session.help()Done for now:
await session.exit()npx testify --coverageThis produces coverage/index.html, coverage/lcov.info, and a console summary.
Run npx jasmine init once to prepare single-spec debugging and editor support. After that, the path from failing test to breakpoint is short and predictable.
The Jasmine CLI uses tsx and the nearest TypeScript project settings automatically. Testify also resolves extensionless relative files and directory indexes the same way the browser runner does, so imports like ../lib, ../lib/forms, and ./helper behave consistently across runners.
To run one spec directly:
node --enable-source-maps \
./node_modules/@epikodelabs/testify/bin/jasmine \
--spec ./tests/example.spec.tsThen you can debug exactly that spec in VS Code instead of marching the whole suite into the room.
| Flag | Description |
|---|---|
--headless |
Run headless |
--browser <name> |
chrome, firefox, webkit, node |
--watch |
Watch mode |
--coverage |
Generate coverage reports |
--seed <n> |
Randomization seed |
--silent / --quiet |
Suppress console logs (Node) |
--preserve |
Skip regenerating outputs |
--help |
Show help |
Exit codes: 0 success, 1 failures, 2 invalid usage, 3 config error, 4 internal error, 130 SIGINT, 143 SIGTERM.
A typical pipeline runs the fast Node.js suite first, then follows it with a slower headless browser pass plus coverage:
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npx playwright install --with-deps
- run: npx testify --browser node
- run: npx testify --headless --browser chrome --coverage| Issue | Fix |
|---|---|
| Browser not found | npx playwright install |
| Port in use | Pick a different port with --port |
| No tests found | Check your spec locations, .spec.ts extension, and excludes |
| TS errors | Make sure your TypeScript project resolves imports correctly |
| Watch not working | Requires headed mode; incompatible with --headless, --coverage, node |
| Coverage missing | Use --coverage; incompatible with --watch |
MIT (c) 2026