1.16.2 Bug fix: fail-once no longer leaks its stop sentinel into asPromise tests. Under the parallel runner with fail-once (--flags FO), a failing assert inside an asPromise async callback threw the internal StopTest sentinel out of the callback as an unhandled rejection: the worker died, the sentinel was recorded as a phantom second failure (operator: error with the serialized sentinel on Node, an opaque [object ErrorEvent] on Bun and Deno), tallies inflated, the final summary line vanished, and Deno sprayed worker-channel noise. (1.15.0 swallowed the same scenario silently with exit 0; 1.16.0's counting fix turned it noisy-but-honest; this release completes the arc.) The asPromise wrapper now forwards an async callback's rejection into the test's own promise, so the sentinel unwinds through the runner's normal stop path β one real failure, correct summary, clean exit, quiet worker channel on Node, Bun, and Deno alike. Side benefit: a plain throw in an async callback before resolve() now reports as an unexpected exception instead of hanging the test. Regression-tested end-to-end against the parallel runner (tests/cli/test-fail-once-as-promise.js). Bug fix: the web application handles fail-once. The in-browser runner (tape6-server's web app) hung on every fail-once run: an unguarded reporter in its report chain let the sentinel escape and break the completion sequence (now guarded like its siblings), and its test iframes received a stale flag string ('F' instead of the run's actual flags), so fail-once never armed in-page. The web app now passes the run's full flags through; its dashboard totals match the CLI runner's for the same suite. Internal: the web app adopted the shared driver/bootstrap module (shipped in 1.15.0), retiring the last hand-rolled copy of the in-page bootstrap; the browser defer now bounds requestIdleCallback starvation ({timeout: 50} β hidden or headless iframes may never go idle, which could stall next-file scheduling); the error-chain tests split into browser-safe and CLI-only halves so their browser coverage returned; the EventServer queue tests await the deferred start instead of racing a fixed sleep against requestIdleCallback; tape-six's own browser suite is 100% green again (284 asserts, verified headless).
1.16.1 Failure diagnostics unchain Error.cause and AggregateError. Serialized events now carry cause chains and AggregateErrorerrors members (cycle-safe β a cyclic cause chain becomes a Circular marker), and both reporters render them with failures: causes: labels the chain outermost-to-root, causeStack: shows the deepest cause's stack frames, and errors: lists aggregate members collected from every link β all YAMLish-safe in TAP output. Wrapped root causes stay visible: a fast-check counterexample now shows the predicate's own failing line, and a Node fetch failed shows the ECONNREFUSED underneath. The chain walker getErrorChain ships in tape-six/State.js (typed) for the sister reporters. Docs: the wiki property-based-testing page gained race-condition (fc.scheduler) and model-based testing sections with examples verified against fast-check 4.9, and documents the cause-chain payoff for property failures. Internal: a fast-check failure-shape recognition (named property failures parsed from fc's message text) was implemented and deliberately reverted β free-text parsing is brittle and per-library event fields would break the uniform event protocol; the generic cause-unchaining delivers the same visibility structurally. The vendored deep6 1.4.0 now carries upstream @ts-self-types directives, closing that half of the release-digest sidecar findings.
1.16.0 Bug fix: parallel fail-once no longer masks failures. The default parallel runner (tape6) with fail-once (--flags FO β the documented default) could intermittently report green β failed: 0, exit 0 β on a suite containing a real failure, with likelihood growing with suite size (near-certain at a few hundred tests). The cause was an event-ordering race in the aggregating reporter, not the abort machinery: fail-once aborts sibling workers the moment the failing event arrives (keyed off the raw event, by design), but that event is often still buffered behind the pass-through worker's output; a terminated sibling's stop-marked event, delivered first, marked the hub reporter's state chain skip, so the failure β when its buffer finally flushed β was re-stamped as skipped and never counted. State.preprocess now stamps every event it touches (processed: true) and counts pre-stamped worker events by their own flags: the hub chain is never skip-poisoned by forwarded events (it still arms stopTest, which stops file scheduling), so a buffered failure counts as failed regardless of delivery order. tape6-seq semantics are unchanged, and aborted parallel runs no longer inflate skipped β their totals now match the sequential runner's. Covered by a deterministic regression test (tests/test-event-aggregation.js) that replays the exact delivery order; the counting rule is documented in ARCHITECTURE.md and dev-docs/worker-control-channel.md. Vendored deep6 1.4.0 β assertions compare by value. The vendored deep6 moved from 1.2.0 to 1.4.0 (headline changes: shared-reference equality fixed, circular is now a semantics enum, EnvMap default). tape-six pins its comparison semantics explicitly: t.deepEqual and friends pass circular: true β the cheapest value-preserving mode (bisimulation) β making value equality the stated contract ('graph', strict pointer-structure comparison, is deliberately not used). Object-pattern matchers (t.throws/t.rejects/t.resolves patterns, t.match/t.doesNotMatch) now use open-mode unify() directly instead of match(): plain patterns match class instances by their own properties β an Error's code, its own non-enumerable message, and nested cause chains all work β while a pattern key the target does not own constrains nothing, prototype getters are not read, and registered types (Date, RegExp, typed arrays, URL) never match plain patterns. Semantics documented in TESTING.md and the AI docs; matcher tests extended to pin them. Internal: the code-transformation moonshot design note moved out of the repo to continue as its own project; retired .windsurf skill copies removed; prettier refreshed to ^3.9.6.
1.15.0 Request recorder.record(handler?) joins the HTTP test harness (tape-six/server.js): it wraps (or replaces) a request listener and eagerly buffers every request it serves as a plain {method, url, headers, body} object onto its requests array β assert with t.match + t.any, reset with requests.length = 0; without a handler it answers 204, with one it delegates after the body is drained (the delegate reads entry.body, its third argument). The harness also gained its first wiki page: tape-six/server. Browser-driver kit. New src/driver/ subsystem hosting everything the Puppeteer/Playwright companion packages used to hand-mirror (~650 near-identical lines each): bootstrap.js (the in-page harness text β srcdoc/importmap injection, __tape6_* wiring), TestWorker.js (the shared per-task BrowserContext+Page lifecycle on top of EventServer, cooperative drain + grace-timeout force-kill), and cli.js (runDriverCli β the whole driver-bin flow, including --start-server self-launch). A driver package now supplies only a four-member adapter (supportedBrowsers, launchBrowser, newContext, pageErrorEvent) and a one-call bin; tape-six-puppeteer and tape-six-playwright adopt it at their next releases. Design note: dev-docs/browser-driver-kit.md. Bug fix: failing todo assertions no longer crash the run. A failing assert inside test.todo() hit a missing stack trace and threw inside the reporter β killing the process mid-run under the default reporter and truncating TAP output. Stacks are now collected for all displayed failures and both reporters tolerate their absence. TAP conformance. The TAP stream was audited against tap-parser (strict) and Perl's prove/TAP::Harness across both output variants and all event shapes, and fixed: test-point ids are now sequential 1..N (nested tests and multi-file runs previously emitted duplicates β the TAP reporter renumbers by default), monochrome (NO_COLOR) output is no longer corrupted by internal style names, YAML diagnostics quote hostile strings/keys/dates correctly, an internal marker key no longer leaks into expected/actual, and stack frames are emitted as a quoted YAML list so Perl's YAMLish parser reads them (it has no block scalars). Typings.EventServerReporter.state declares failed; Tape6Config declares the core-owned server section (Tape6ServerConfig); TestEvent declares its protocol spine (type, test). Internal: cross-runtime conformance, recorder, and fake-driver test suites; a real-Playwright end-to-end validation of the kit; the console-interception demo moved to tests/manual/ so npm test output is fully silent (a spawn-based capture test keeps the coverage); ARCHITECTURE.md/AGENTS.md layout updates.
1.14.1 Bare-run keep-alive. A test file executed directly (node tests/test-foo.js β no runner) could exit with code 0 mid-suite, silently truncating output: when a test awaited only unref'd timers (AbortSignal.timeout() is unref'd on Node and Bun), the event loop drained and the process exited before the test queue was done. testRunner now holds a ref'd keep-alive interval from entry to completion, so bare runs always finish; runner-managed runs were never affected (their IPC channels already pin the event loop). Covered by a cross-runtime spawn regression test. Sidecar typings fixes.EventServerReporter.state dropped its index signature β class types have no implicit index signature, so class-typed states (like State) were unassignable under checked JS. The pass-through option bags in the .d.ts sidecars (EventServerOptions, Tape6Config, RunnerFlags, parsed CLI flags) switched their index signatures from unknown to any, so driver siblings and checked-JS consumers read pass-through keys without casts β the keys belong to the runners that pass them, not to the base contract. New type-assignability tests cover both. Internal: two research notes added under dev-docs/ (testing landscape & directions, code-transformation moonshot); dev dependencies refreshed β typescript 6.0 β 7.0, with the suite and ts-check clean under the native TS 7 compiler.
1.14.0 Shared control-plane client.src/utils/controlFetch.js is hoisted from the browser providers into core, importable as tape-six/utils/controlFetch.js (with a .d.ts sidecar). createControlFetch(rootFolder?) builds the client the driver siblings use to call the test server's control endpoints (/--tests, /--patterns, /--importmap): every request carries a 3s hard deadline (a dying listener can accept and never answer); https: requests walk a TLS trust ladder scoped to control requests only β TAPE6_CERT pinned as CA, else the cached self-signed cert under node_modules/.cache/tape6/cert.pem, else relaxed verification; timeouts surface as code: 'ETIMEDOUT' and are never retried on a lower rung. isProtocolMismatch(error) names the TLS-against-plaintext case (an h1 server behind an https: URL). The endpoints and the cert-cache location are core's contract β tape-six-puppeteer and tape-six-playwright previously hand-mirrored this module byte-for-byte and will import it from core at their next release. Type declarations for more modules. New .d.ts sidecars (adjacency + // @ts-self-types, like EventServer.js before them) for State.js, test.js, utils/config.js, utils/makeDeferred.js, and utils/timer.js β the full sister-imported surface is now typed, so driver siblings type-check against real declarations instead of any. Deno realpath shim removed. Deno 2.9.1 shipped the fix for denoland/deno#35551 (fix(npm): realpath npm bin main module), so the 1.11.0 workaround is retired: bin/tape6-deno-main.js is folded back into bin/tape6-deno.js with its original static imports. Deno 2.8.x and β₯ 2.9.1 work; only the buggy 2.9.0 needs an upgrade. Internal: fleet-conventions delta pass (retired AI-rules mirror files removed, .github/copilot-instructions.md lowercased, llms/llmsFull package fields dropped, HTTPS clone instructions in CONTRIBUTING.md); the wiki gained a curated _Sidebar.md, a # Documentation hub on Home, and a wiki-search index.
1.13.0 EventServer type declarations. New .d.ts sidecar for tape-six/utils/EventServer.js (resolved by adjacency plus the // @ts-self-types directive, like server.js / response.js / test-server.js before it). It types the constructor (reporter, numberOfTasks?, options?), the DATA-plane machinery (report / close / createTask / execute), and the CONTROL-plane transport hooks makeTask / destroyTask with the DestroyReason contract (done | failOnce | timeout, per dev-docs/worker-control-channel.md); plus the structural EventServerReporter interface (any tape-six reporter qualifies), EventServerOptions (graceTimeout / workerTimeout and runner-specific passthrough keys), and the runner-assigned done completion hook. Task ids are typed as strings, matching every runner. This lets the driver siblings (tape-six-proc, tape-six-puppeteer, tape-six-playwright) drop their /** @type {*} */ casts on extends EventServer and adopt .d.ts sidecars themselves. Internal: an explicit least-privilege permissions block on the manual Windows CI workflow; a comment-convention cleanup pass.
1.12.0 Pluggable test server (tape6-server v2). The browser-test server now hosts fixture plugins for real-wire testing (chunked streaming with controlled timing, SSE, stateful ETag resources, upload sinks). A plugin claims a URL prefix and handles requests with a WHATWG fetch(request) β Response | (async) iterable | undefined contract behind a small adapter that owns streamed bodies (duplex: 'half' request streams, unbuffered response streaming) and wires client disconnects to request.signal; a bare (async) generator function is enough for a trivial data fixture (Uint8Array chunks pass through, strings are UTF-8, other values become JSONL lines; the content type is inferred from the first chunk). Routing: reserved control endpoints (/--tests, /--patterns, /--importmap, new /--plugins) β plugins by longest prefix β statics β the GET/HEAD method gate moved into statics, so plugins see all verbs. Registration is static (tape6.server.plugins config + repeatable --plugin) and dynamic (GET/PUT/DELETE /--plugins: one namespace, PUT replaces by name after closing the old instance and re-imports the module β pleasant for watch-mode iteration; wire-mounted specifiers are contained to the server root; --no-remote-plugins disables mutations). A tiny reference plugin ships in-tree and mounts /--echo. Embeddable core. New tape-six/test-server.js exports createTestServer() and the scoped withTestServer(); the default port: 0 gives parallel test files collision-free servers by construction, and inline plugins (factories, records, generator functions) are accepted. bin/tape6-server.js is now a thin CLI shell over it. HTTP/2 mode.--h2 / TAPE6_PROTOCOL=h2 / tape6.server.protocol serves HTTPS with ALPN h2 + HTTP/1.1 on one port via the node:http2 compat API β plugins are untouched; HTTP/1.1 cleartext stays the default (self-signed TLS taxes manual debugging and service workers). Node-only server mode. Certificates: TAPE6_CERT/TAPE6_KEY (mkcert route) or an auto-generated openssl self-signed cert cached under node_modules/.cache/tape6/ and reused until expiry/host mismatch. Chief motivation: browser fetch() upload streaming is Chromium + h2/h3-only. Platform note: Bun doesn't emit 'close' on the server response when a client disconnects β the adapter also watches the request/socket, so abort propagation works on Node, Bun, and Deno alike. Bugfix: the per-test timeout option no longer keeps the process alive after the suite finishes β the timeout race left its losing setTimeout uncleared, so sequential (tape6-seq) and direct runs lingered until the largest pending per-test timeout expired (up to 30 s once the new test-server tests started using the option); the timer is now cleared when a test completes in time, and the uncancellable src/utils/timeout.js helper was removed. Docs: new dev-docs/pluggable-test-server.md design note; the wiki tape6-server page rewritten (plugins, embedding, HTTP/2); TESTING.md + AI docs updated. Internal: fleet-conventions compliance pass β internal default-export modules gained named export mirrors (TestWorker Γ4, EventServer, defer, yamlFormatter, timeout, echo), legacy per-project .claude/commands / .windsurf/workflows copies removed in favor of the global skills; prettier pinned as a devDependency (^3.9.4); @types/node bumped to ^26.1.0.
1.11.0 Invariant host hooks. Three small additions let an external library route assertions into a running tape6 test. index.js installs an invariant host at globalThis[Symbol.for('tape6.invariant.host.v1')] ({version, report(assertion)}) at module load (not init(), so a consumer's hasHost snapshot is reliable). getTester() returns the innermost running Tester (top of the active test stack), or null outside a test. Tester.reportAssertion({ok, message?, marker?, operator?, expected?, actual?}) reports an assertion with an externally captured marker so the reported source location points at the caller, not the adapter; with no operator/expected/actual it behaves like assert/ok. These are the coordination point for the new zero-dependency tape-six-invariant companion package, whose check() calls materialize as real assertions on the current test under a tape6 run and are inert/configurable otherwise β they are integration primitives, not user-facing assertions. Full design: dev-docs/sister-assert-library.md. Deno 2.9.0 workaround. Deno 2.9.0 stopped realpath-ing a symlinked node_modules/.bin entry when a package.json is present (node-compat mode), so tape6-deno's relative ../src/β¦ imports resolved one directory wrong and test:deno broke (Deno 2.8.x and Node/Bun are unaffected). bin/tape6-deno.js is now a thin realpath shim that loads the actual runner bin/tape6-deno-main.js (original clean static imports, untouched) β chosen over inlining dynamic imports into the runner so the working code stays pristine. Restores the Deno runner on 2.9.0 while staying correct on 2.8.x; confirmed a clean regression with faithful and minimal repros and filed denoland/deno#35551. Internal: fleet-conventions conformance pass (AI-docs sync for the new exports, a ~90-comment narrating-comment sweep, .gitmodules SSHβHTTPS); @types/node bumped to ^26.0.1.
1.10.1 Bun stdout workaround. Bun's native console.log to a subprocess-piped stdout silently drops data and stalls the reader under concurrent load (a Bun defect; Node and Deno are unaffected) β the root cause of the tape-six-proctest:proc:bun hang that surfaced after 1.10.0. The bug is in the child write side, not the parent read: a probe confirmed Bun's console.log bypasses process.stdout entirely via a separate native fd path, while process.stdout.write and Bun.write stay reliable. The base Reporter gains a writeOut(...) helper that routes through process.stdout.write on Bun and keeps the proven console.log path on Node/Deno; the three plain-text reporters that emit records β JSONLReporter (the proc data plane), MinReporter, and TapReporter's no-color sink β now write through it. TTYReporter already wrote via process.stdout and is unchanged. Validated: tape-six's own suite passes on Node and Bun, and the full tape-six-proctest:proc:bun suite (previously a deterministic hang) passes. The fix is a workaround β the underlying defect is Bun's; the upstream filing is deferred until after Bun's in-progress ZigβRust rewrite ships.
1.10.0 Worker control channel β a one-command control plane (runner β worker terminate) that closes the loop the runner/reporter previously lacked. failOnce / bail-out now stop in-flight workers, not just stop scheduling new files: EventServer.destroyTask(id, reason) (reason β done | failOnce | timeout) delivers terminate per transport, and the abort-all trigger keys off the raw incoming stopTest / bail-out so a buffered worker's failure aborts the rest immediately. Child-side Reporter.terminate() arms stopTest + fires the abort signal and is remembered, so a test starting after the terminate also stops at its first assertion (closes the startup race). Optional per-worker deadlineTAPE6_WORKER_TIMEOUT (ms, default 0 = off) β the enforcement the per-test timeout option lacks: it stops a worker whose test ignores t.signal and never settles. Termination drains cooperatively (cleanup hooks run, output flushes) then force-kills after TAPE6_GRACE_TIMEOUT ms (default 5000) where the transport allows β par β worker.terminate(), proc β process kill, driver-backed browser β driver closes the page/context. Verified firing identically across par (node/bun/deno), seq, and proc; the standalone-browser iframe gets cooperative drain via postMessage but no in-page force-kill (a DOM-free Web-Worker worker is the future backstop). As a side effect this closes the Bun stdout-flush race (parent-driven child exit reads end before requesting exit). Provider halves shipped alongside in tape-six-proc, tape-six-puppeteer, and tape-six-playwright; each provider's cooperative-drain goes live once it depends on this release. Docs: new dev-docs/worker-control-channel.md design note; wiki Supported flags (O flag) and tape6 utility (env vars) updated; AI docs (AGENTS.md, llms.txt, llms-full.txt, ARCHITECTURE.md) carry the channel + env vars. Internal:@types/node bumped to ^25.9.1.
1.9.0 New features around tester behavior and extensibility. t.plan(n) records the expected direct-assertion count and emits a # plan != count: expected N, ran M TAP comment at test end on mismatch β diagnostic only, doesn't fail the test. Subtest assertions don't count toward the parent's plan (a new internal State.localAsserts counter tracks direct-only). Validates input (non-negative integer, throws TypeError otherwise). registerTesterMethod(name, fn) is the new public registrar for plugins: idempotent for the same function (so per-file plugin imports don't fail), throws on collision with a different function (so plugin name conflicts surface loudly at registration time). Tester is now declared as an interface in index.d.ts precisely so plugin packages can use TS module augmentation without restating the full class shape. The built-in t.OK() evaluator (src/OK.js) was refactored to use the new registrar and stands as the in-tree worked example. 3rd-party library catalog β three new wiki pages cover BYO patterns: assertion libraries (node:assert, chai, expect) with browser-test importmap snippets, mock libraries (node:test mock + sinon), and property-based testing (fast-check). All examples were verified in throwaway projects off-repo. Writing plugins β new wiki page with a t.spawnBin() worked example and a per-file installation table covering the runner-isolation models (tape6-seq shared / tape6 workers / tape6-proc from sister package tape-six-proc subprocesses / browser iframes); plugins must be imported in every test file that uses them. Internal: chai and @types/chai removed from devDependencies (CI smoke-test of the AssertionError path now lives in tests/cli/test-assert.js using node:assert); new tests/node/test-mock.js exercises node:test mock pinned via a new tape6.node config section in package.json; tests/test-describe.js migrated off chai to native t.*; tests/manual/test-chai.js kept as a hand-runnable visual demo. jsconfig.json updated to drop the deprecated baseUrl (TS 7.0 ready); paths now resolves relative to the config file's directory β Bun's path resolution still works.
1.8.0 Added two subpath modules for HTTP-shaped test fixtures. tape-six/server ships withServer(serverHandler, clientHandler, opts?) for per-test scoped servers, startServer(server, opts?) as a procedural primitive that races 'listening' vs 'error' (port-busy rejects rather than hangs), and setupServer(serverHandler, opts?) which registers beforeAll/afterAll and returns a live-getter handle for suite-shared servers. Cross-runtime via node:http (Node, Bun, Deno; not for browsers). tape-six/response ships asText/asJson/asBytes/header/headers reading helpers that work uniformly with both W3C Response (fetch results) and Node http.IncomingMessage. Internal: bin/tape6-server.js migrated to use startServer and process.exitCode. Added types: ["node"] to tsconfig.json (required by module: "Node16" to load @types/node). node: protocol prefix now consistently used for all Node built-in imports.
1.7.14 Updated vendored deep6 from 1.1.x to 1.2.0. Notable upstream changes: added URL object support (new unifier, walker, cloner, and processors), added named exports alongside default exports, added a fast path for naked objects, performance optimizations across the unifier, improved TypeScript typings, expanded test reorganization, and removed the CommonJS build (deep6 is now ESM-only). All tape-six consumer-facing APIs are unchanged β this release only refreshes the vendored copy under src/deep6/.
1.7.13 Replaced process.exit() / Deno.exit() with process.exitCode in all test runners (tape6-node, tape6-bun, tape6-deno, tape6-seq) and index.js to allow graceful stdout flushing before exit. Added isCli helper in index.js. Updated dev dependencies (typescript 5.9β6.0). Updated GitHub Actions (actions/checkout 4β6, actions/setup-node 4β6, github/codeql-action 3β4). Added CI workflow.
1.7.12 Added --help/-h and --version/-v options to all CLI utilities. Added printFlagOptions() to display flag documentation in help output. Updated CLI documentation.
1.7.11 Documentation consistency: added missing sequential test commands (test:seq:bun, test:seq:deno) to AGENTS.md, ARCHITECTURE.md, and agent rule files. Fixed stale ts-test glob reference in prompts/write-test.md. Added test-writing clarifications.
1.7.10 Switched shipped consumer artifacts from Windsurf workflows (workflows/) to vendor-neutral Agent Skills (skills/) following the agentskills.io open standard. Improved CommonJS import documentation: named import const {test} = require('tape-six') is now explicitly recommended.
1.7.9 Merged ts-tests/ into tests/. Fixed .d.ts typing errors exposed by skipLibCheck: false. Added ts-check to CI. Removed standalone ts-test scripts.
1.7.8 Bug fix: flush stdout before exit in Deno runners to prevent truncated output caused by async process.stdout.write() in Deno's Node compat layer.
1.7.7 Bug fix: tape6-server now normalizes paths to Posix format for web clients on Windows. Documented --flags=FO option form.
1.7.6 Bug fix: processArgs now stores option values under canonical names instead of alias names. Removed dead code in processArgs. Added missing TAPE6_MIN to TESTING.md.
1.7.5 Refactored CLI runners to use shared initialization from config.js. Added --info option to print current configuration without running tests. Renamed dontCaptureConsole to noConsoleCapture. Flags are now written back to the environment for worker processes.
1.7.4 Bug fixes: uncaught exception handlers now terminate the process immediately, added suppressStopTest to reporter report() methods, EventServer suppresses StopTest when replaying retained events, removed dead code in TestWorkers.
1.7.3 Bug fixes: corrected bail-out event mapping in reporters, fixed Deno worker env var name, fixed BypassReporter abort delegation, added missing type: 'assert' to exception reports, corrected default messages for deep loose equality asserts. Documentation: corrected and expanded wiki, README, and LLM docs. Removed dead code in MinReporter.
1.7.2 Minor internal refactoring and fixes.
1.7.1 Added AI support, added timeout to start test runners, fixed some bugs in the sequential test runner.
1.7.0 New features: after/before hooks for tests, aliases for suite(), describe(), it(), tape6-seq β an in-process sequential test runner. Improvements: stricter monochrome detection, refactoring, bugfixes, updated dev dependencies and the documentation.
1.6.0 New features: support for AssertionError and 3rd-party assertion libraries based on it like node:assert and chai, support for console.assert(), support for signal to cancel asynchronous operations, tests wait for embedded tests, improved reporting of errors, updated dev dependencies.
1.5.1 Better support for stopping parallel tests, better support for "failed to load" errors.
1.5.0 Internal refactoring (moved state to reporters), added type identification of values in the DOM and TTY reporters, multiple minor fixes.
1.4.5 Internal: added flags support for custom test runners.
1.4.4 Refreshed the lock file.
1.4.3 Updated dev dependencies + a minor bugfix.
1.4.2 Improved documentation.
1.4.1 Added browser automation support.
1.4.0 Added a high-level helper OK() for evaluating simple expressions.
1.3.5 Minor improvements, better docs.
1.3.4 Minor bugfixes and improvements.
1.3.3 Added a way to hide console/streams output, better support for file tests, better TTY formatting.