4.9 KiB
Testing
WXT provides several utils for writing tests.
Unit tests
If you're using auto-imports (enabled by default), Vitest is the only testing framework that supports them.
If you want to use a different testing library/framework (like Jest, mocha, node:test, etc), you can keep using it, but you have two options:
- Switch to Vitest (recommended)
- Configure the testing library manually
- Disable auto-imports by setting
imports: falsein yourwxt.config.tsfile - Manually add globals normally provided by WXT (like
__BROWSER__) that you consume to the global scope before accessing them (globalThis.__BROWSER__ = "chrome")
- Disable auto-imports by setting
Vitest Setup
Install vitest and add the WxtVitest plugin to your vitest.config.ts file.
pnpm i -D vitest
// <root>/vitest.config.ts
import { defineConfig } from 'vitest/config';
import { WxtVitest } from 'wxt/testing';
export default defineConfig({
plugins: [WxtVitest()],
});
And that's it. You're ready to start writing tests.
Writing Tests
Here's a very basic test, written with a few different testing libraries, with a few different approaches for mocking the browser global.
:::code-group
import { describe, it, expect, vi } from 'vitest';
function logRuntimeId() {
// Vitest automatically mocks "browser" with "fakeBrowser"
console.log(browser.runtime.id);
}
describe('logRuntimeId', () => {
it("should log the extension's runtime ID", () => {
// Set a known ID on fakeBrowser for the test
const id = 'some-runtime-id';
fakeBrowser.runtime.id = id;
const logSpy = vi.spyOn(console, 'log');
logRuntimeId();
expect(logSpy).toBeCalledWith(id);
});
});
import { fakeBrowser } from 'wxt/testing';
import { browser } from 'wxt/browser';
function logRuntimeId() {
console.log(browser.runtime.id);
}
// Manually mock
jest.mock('wxt/browser', () => {
const { fakeBrowser } = require('wxt/testing');
return { browser: fakeBrowser };
});
describe('logRuntimeId', () => {
it("should log the extension's runtime ID", () => {
// Set a known ID on fakeBrowser for the test
const id = 'some-runtime-id';
fakeBrowser.runtime.id = id;
const logSpy = jest.spyOn(console, 'log');
logRuntimeId();
expect(logSpy).toBeCalledWith(id);
});
});
import { describe, it, mock } from 'node:test';
import { assert } from 'node:assert';
import { fakeBrowser } from 'wxt/testing';
import { browser } from 'wxt/browser';
// Add browser as a parameter so fakeBrowser can be passed instead of browser
function logRuntimeId(browser = browser) {
console.log(browser.runtime.id);
}
describe('logRuntimeId', () => {
it("should log the extension's runtime ID", () => {
// Set a known ID on fakeBrowser for the test
const id = 'some-runtime-id';
fakeBrowser.runtime.id = id;
console.log = mock.fn();
// pass in fakeBrowser during tests
logRuntimeId(fakeBrowser);
assert.deepStrictEqual(console.log.mock.calls[0].arguments, [id]);
});
});
:::
:::warning
Without mocking the browser variable, you'll see errors like this:
This script should only be loaded in a browser extension.
:::
WXT provides an in-memory, partial implementation of browser, fakeBrowser, from the @webext-core/fake-browser package. fakeBrowser works with all testing frameworks/libraries. See their docs for a list of implemented APIs and more example tests.
E2E Tests
WXT does not provide any utils for running E2E tests. There are two libraries you can use to run E2E tests for any chrome extension.
playwright(recommended) - "A high-level API to automate web browsers"puppeteer- "A high-level API to control headless Chrome over the DevTools Protocol"
:::info Note that both only support running tests on Chrome. :::
Before running tests with either of these tools, you must build the extension with wxt build and then load the extension from the output directory in a new tab.
To test an extension's UI, like the popup or options page, you'll need to know the extension's ID to open the URL directly.
chrome-extension://
browser.runtime.id/popup.html
- Playwright provides an API to get your extension ID after it has been installed. See their docs.
- Puppeteer requires you know the ID before installing the extension, so you can hard code it into the URLs you open. Follow Chrome's guide to setup a consistent runtime id.
:::info You cannot test popups in their normal popup window, you have to open them in a tab. :::