Test your code with Vitest
Configure Vitest so that your tests use the browser runtime and the transform of the library.
Tests in a browser
Vitest browser mode uses the Vite configuration. Add the Vite plugin to the test configuration, and the tests and the code under test get the transform:
// vitest.config.ts
import { defineConfig } from "vitest/config";
import { asyncContext } from "async-browser-context/vite";
import { playwright } from "@vitest/browser-playwright";
export default defineConfig({
plugins : [asyncContext()],
test : {
browser : {
enabled : true,
provider : playwright(),
instances : [{ browser : "chromium" }, { browser : "firefox" }, { browser : "webkit" }],
},
},
});Tests in the Node.js environment
In the Node.js environment, the node export condition selects the Node.js entry, and the native AsyncLocalStorage keeps the context. A transform is not necessary for the rules C1 to C4. In this environment, Vitest uses the SSR transform of Vite. If your tests need rule C5 for generators, set the ssr option of the plugin to true:
export default defineConfig({
plugins : [asyncContext({ ssr : true })],
test : { environment : "node" },
});The browser runtime in the Node.js environment
Browser mode is the best test of the browser runtime. For fast tests without a browser, you can also use the browser runtime in Node.js:
- Map the package to its browser entry with an alias.
- Set the
runtimeoption of the plugin to the browser runtime. - Set the
ssroption of the plugin totrue.
export default defineConfig({
plugins : [asyncContext({ ssr : true, runtime : "async-browser-context/browser/runtime" })],
resolve : { alias : [{ find : /^async-browser-context$/, replacement : "async-browser-context/browser" }] },
test : { environment : "node" },
});This repository uses this configuration in its rules (browser runtime, Node.js) test project.
Write a test that can find a leak
A test with one context at a time cannot find a context leak: the leaked value is the same as the correct value. Use two contexts, and let the other context continue first:
it("keeps the context after await, while another request continues", async () => {
const requestId = new AsyncContext.Variable<string>();
const other = requestId.run("other", async () => {
await null;
await null;
});
const seen = await requestId.run("mine", async () => {
const value = { first : await null, id : requestId.get() };
return value.id;
});
await other;
expect(seen).toBe("mine");
});The testing section tells how the library tests itself.