Bumps all 47 packages, the root manifest and the VS Code extension to 0.8.6, and rebuilds the editor compiler, language server and extension bundles that embed the version. The release carries the output delivery fix: camelCase outputs now reach parent bindings, and 18 components emit through output.* instead of hand-built CustomEvents. See the 0.8.6 migration entry for what changes for consumers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@wrnexus/test
Testing utilities for WrNexus apps — component rendering, reactive-DOM mounting, route handler calls, and a full in-process app harness, plus a one-import re-export of
bun:test.
Part of the WrNexus framework — an SSR-first, Bun-native full-stack web framework.
Overview
@wrnexus/test is the server-side test toolkit you reach for when writing tests
for a WrNexus app. It runs under bun test (invoked via wrnexus test) and gives
you a single import surface: the bun:test primitives (test, expect, mock,
…) re-exported alongside WrNexus-aware helpers that compile .wrn components,
hydrate server HTML in a DOM, invoke API route handlers, and boot the real app on
an ephemeral port for integration tests.
Installation
bun add @wrnexus/test
Private package — the machine must be authenticated to the
wrnexusnpm org (a read token in~/.npmrc). Requires Bun (Node is not supported).
API
Re-exported test primitives
For one-import DX, the following are re-exported straight from bun:test:
test, expect, describe, it, beforeEach, afterEach, beforeAll,
afterAll, mock, spyOn.
createContext is also re-exported from @wrnexus/core.
renderComponent(source, props?)
function renderComponent(source: string, props?: Record<string, unknown>): Promise<string>;
Compiles a .wrn component source string (via @wrnexus/compiler) and renders
it to an HTML string with the given props. Throws if the compiled module has no
render export.
mountHtml(html)
function mountHtml(html: string): {
document: Document;
window: unknown;
querySelector: (sel: string) => Element | null;
querySelectorAll: (sel: string) => Element[];
};
Mounts server-rendered html in a happy-dom window with the reactive runtime
hydrated, so you can test data-scope / data-text / data-for / data-show
behaviour. Returns the window plus document and query helpers; assert on those.
happy-domis loaded lazily (viarequire), so importing this package never requires it unless you actually callmountHtml.
callRoute(handler, request)
function callRoute(
handler: (ctx: Context) => Response | Promise<Response>,
request: Request,
): Promise<Response>;
Calls an API route handler with a Context built from a Request (using
createContext). Returns the handler's Response.
createHarness(projectRoot, options?)
function createHarness(projectRoot: string, options?: HarnessOptions): Promise<Harness>;
interface HarnessOptions {
/** Config/env profile. Default "test". */
profile?: string;
}
interface Harness {
/** Base URL of the ephemeral test server. */
url: string;
/** Fetch a path on the app (relative to `url`). */
fetch(path: string, init?: RequestInit): Promise<Response>;
/** The scanned router (pages/api/realtime/components). */
router: unknown;
/** Stop the server. */
close(): void;
}
Boots the app at projectRoot on an ephemeral port (port: 0) for integration
tests covering pages, API routes, middleware, and the full request pipeline. Loads
env and app config for the given profile (default "test") so it picks up your
test database/env. The server runs in development mode with HMR disabled.
Remember to await app.close() when done.
Usage
The CLI supports focused suites by file or directory convention:
wrnexus test unit # *.unit.test.ts or test/unit/**
wrnexus test component # *.component.test.ts or test/component/**
wrnexus test api # *.api.test.ts or test/api/**
wrnexus test accessibility # *.a11y.test.ts / *.accessibility.test.ts
wrnexus test performance # *.performance.test.ts / *.benchmark.test.ts
wrnexus test browser # Playwright project when configured
wrnexus test visual # Playwright tests tagged @visual
Pass the application directory after the level, for example
wrnexus test component examples/basic-app. A focused command fails clearly when no matching
suite exists instead of silently running unrelated tests.
import { test, expect, renderComponent, mountHtml, createHarness } from "@wrnexus/test";
test("counter renders its label", async () => {
const html = await renderComponent(SRC, { start: 3, label: "Hits" });
expect(html).toContain("Hits");
});
test("reactive scope hydrates", () => {
const { querySelector } = mountHtml(serverHtml);
expect(querySelector("[data-text]")?.textContent).toBe("3");
});
test("home page responds", async () => {
const app = await createHarness("examples/basic-app");
const res = await app.fetch("/");
expect(res.status).toBe(200);
await app.close();
});
Calling an API route handler directly:
import { test, expect, callRoute } from "@wrnexus/test";
import { GET } from "../app/api/health.ts";
test("health endpoint", async () => {
const res = await callRoute(GET, new Request("http://test/api/health"));
expect(res.status).toBe(200);
});
Requirements / Notes
- Bun-only. Runs under
bun test(viawrnexus test); uses Bun's module loading and thebun:testruntime. mountHtmlrequireshappy-domto be available in the workspace (loaded lazily; it's a dev dependency, not a runtime dependency of this package).- Works with the rest of the WrNexus toolchain:
@wrnexus/compiler(compiles.wrnsources),@wrnexus/core(Context/createContext),@wrnexus/csr(reactive runtime formountHtml),@wrnexus/dev-server(startServerbehindcreateHarness), and@wrnexus/styles(config/env/profile loading for the harness).