From f58d69dc5f77a5454f0684c37edd6eb74e2d1a22 Mon Sep 17 00:00:00 2001 From: Aaron Klinker Date: Mon, 2 Oct 2023 15:05:47 -0500 Subject: [PATCH] docs: Add docs for development and testing --- docs/.vitepress/config.ts | 1 + docs/guide/development.md | 53 +++++++++++++++++++++++ docs/guide/testing.md | 89 ++++++++++++++++++++++++++++++++++++++- docs/index.md | 2 +- 4 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 docs/guide/development.md diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 106ba671..da4cac76 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -77,6 +77,7 @@ export default defineConfig({ { text: 'Manifest.json', link: '/guide/manifest.md' }, { text: 'Extension APIs', link: '/guide/extension-apis.md' }, { text: 'Remote Code', link: '/guide/remote-code.md' }, + { text: 'Development', link: '/guide/development.md' }, { text: 'Testing', link: '/guide/testing.md' }, { text: 'Vite', link: '/guide/vite.md' }, { text: 'Compare', link: '/guide/compare.md' }, diff --git a/docs/guide/development.md b/docs/guide/development.md new file mode 100644 index 00000000..10b6e27b --- /dev/null +++ b/docs/guide/development.md @@ -0,0 +1,53 @@ +# Development + +WXT's main goal is providing the best DX it possibly can. When running your extension in dev mode, each part of your extension is reloaded separately when possible. + +| | HMR | Reloaded individually | Reload extension | Restart browser | +| ------------------- | :-: | :-------------------: | :--------------: | :----------------------------------------------------: | +| HTML File | | ✅ | +| HTML Dependency | ✅ | +| MV3 Content Script | | ✅ | +| MV2 Content Script | | | ✅ | +| Background | | | ✅ | +| manifest.json | | | | 🟡 See [#16](https://github.com/wxt-dev/wxt/issues/16) | +| `wxt.config.ts` | | | | 🟡 See [#10](https://github.com/wxt-dev/wxt/issues/10) | +| `web-ext.config.ts` | | | | 🟡 See [#10](https://github.com/wxt-dev/wxt/issues/10) | + +## Configure Browser Startup + +WXT uses [`web-ext` by Mozilla](https://github.com/mozilla/web-ext) to automatically open a browser with the extension installed. You can configure the runner's behavior via the [`runner`](/api/config#runner.disabled) option, or in a separate gitignored file, `web-ext.config.ts`. + +:::code-group + +```ts [wxt.config.ts] +import { defineConfig } from 'wxt'; + +export default defineConfig({ + runner: { + // Runner config + }, +}); +``` + +```ts [web-ext.config.ts] +import { defineRunnerConfig } from 'wxt'; + +export default defineRunnerConfig({ + // Runner config +}); +``` + +::: + +You may also setup default for your entire computer by creating a `web-ext.config.ts` file in your home directory. This is useful if you want to specify config for all project on your computer, like that you want to use Chrome Beta instead of Chrome. + +```ts +// ~/web-ext.config.ts +import { defineRunnerConfig } from 'wxt'; + +export default defineRunnerConfig({ + binaries: { + chrome: '/path/to/chrome-beta', + }, +}); +``` diff --git a/docs/guide/testing.md b/docs/guide/testing.md index d0c9eaad..13172199 100644 --- a/docs/guide/testing.md +++ b/docs/guide/testing.md @@ -1,5 +1,92 @@ # Testing +WXT provides a couple of utils for unit testing your extension. + +[[toc]] + +## Fake Browser + +The `wxt/fake-browser` package includes an in-memory implementation of the `browser` variable you can use for testing. WXT simply re-exports the `fakeBrowser` variable from [`@webext-core/fake-browser`](https://webext-core.aklinker1.io/guide/fake-browser/). + +Here's an example test using Vitest: + +```ts +import { describe, it, expect, vi } from 'vitest'; +import { browser } from 'wxt/browser'; +import { fakeBrowser } from 'wxt'; + +// Function we're testing +function onHelloMessage(cb: () => void) { + browser.runtime.onMessage.addEventListener((message) => { + if (message.type === 'hello') return 'world'; + }); +} + +// Mock the real `browser` object with a fake one +vi.mock('wxt/browser', () => import('wxt/fake-browser')); + +describe('onHelloMessage', () => { + it("should call the callback when the message type is 'hello'", () => { + const cb = vi.fn(); + const expected = 'world'; + + onHelloMessage(cb); + const actual = await fakeBrowser.runtime.sendMessage({ type: 'hello' }); + + expect(cb).toBeCalledTimes(1); + expect(actual).toBe(expected); + }); + + it("should ignore the message when the message type is not 'hello'", () => { + const cb = vi.fn(); + + onHelloMessage(cb); + await fakeBrowser.runtime.sendMessage({ type: 'not-hello' }).catch(); + + expect(cb).not.toBeCalled(); + }); +}); +``` + +See [`@webext-core/fake-browser`](https://webext-core.aklinker1.io/guide/fake-browser/) for setup, implemented APIs, and example tests. + +## Handling Auto-imports + +By default, WXT uses auto-imports. For tests, this can cause issues if your test environment is not setup to handle them correctly. + :::warning 🚧 Testing utils are not implemented yet! -Eventually, the plan is to have an integration with Vitest. +Eventually, WXT will provide utilities for setting up these auto-imports. For now, you'll need to set them up manually. ::: + +Not all testing frameworks can handle auto-imports. If your framework or setup is not listed below, it may be easiest to disable auto-imports. + +To setup auto-imports manually, use [`unplugin-auto-import`](https://www.npmjs.com/package/unplugin-auto-import). It uses the same tool, `unimport`, as WXT and will result in compatiple auto-imports. `unplugin-auto-import` supports lots of different tools (vite, webpage, esbuild, rollup, etc). You can try and integrate it into your build process. + +### Vitest (Recommended) + +Vitest is easy, simply add `uplugin-auto-import` to your project. + +```ts +// vitest.config.ts +import autoImports from 'unplugin-auto-import/vite'; + +export default defineConfig({ + plugins: [ + autoImports({ + imports: [{ name: 'defineConfig', from: 'wxt' }], + presets: [{ package: 'wxt/client' }, { package: 'wxt/browser' }], + dirs: ['components', 'composables', 'hooks', 'utils'], + }), + ], +}); +``` + +### Jest + +Don't use jest and auto-imports. You could try and configure jest to be transpiled by one of `unplugin-auto-import`'s supported built tools, but I don't know of a way to configure this. See [unplugin/unplugin-auto-import#33](https://github.com/unplugin/unplugin-auto-import/issues/33) if you want to try and set it up. + +I would recommend disabling auto-imports or migrating to Vitest if you want to use auto-imports. + +### Mocha + +TODO: Is this possible? Maybe with `esbuild-mocha`? I would recommend moving to Vitest. diff --git a/docs/index.md b/docs/index.md index ed716fe9..150e2beb 100644 --- a/docs/index.md +++ b/docs/index.md @@ -32,7 +32,7 @@ features: - icon: ⚡ title: Fast Dev Mode details: Lighting fast HMR for UI development and fast reloads for content/background scripts enables faster iterations. - link: /guide/introduction.html#development + link: /guide/development.html linkText: Learn more - icon: 📂 title: File Based Entrypoints