Skip to main content
Use Happy DOM to write browser tests with Bun’s test runner. Happy DOM implements mocked versions of browser APIs like document and location.
Install @happy-dom/global-registrator.
terminal
bun add -d @happy-dom/global-registrator

This module exports a “registrator” that injects the mocked browser APIs into the global scope.
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bhappydom.ts
import { GlobalRegistrator } from "@happy-dom/global-registrator";

GlobalRegistrator.register();

This file needs to run before any of your test files. That’s a job for Bun’s built-in preload option. Create a bunfig.toml file in the root of your project (if it doesn’t already exist) and add the following lines. The ./happydom.ts file should contain the registration code from the previous step.
bunfig.toml
[test]
preload = "./happydom.ts"

Now bun test executes happydom.ts before your test files, so you can write tests that use browser APIs.
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bdom.test.ts
import { test, expect } from "bun:test";

test("set button text", () => {
  document.body.innerHTML = `<button>My button</button>`;
  const button = document.querySelector("button");
  expect(button?.innerText).toEqual("My button");
});

With Happy DOM registered, the test passes.
terminal
bun test

dom.test.ts:
✓ set button text [0.82ms]

 1 pass
 0 fail
 1 expect() calls
Ran 1 tests across 1 files. 1 total [125.00ms]

See the Happy DOM repo and DOM testing.