ブラウザーモード 実験的
このページでは、Vitest API の実験的なブラウザーモード機能について説明します。この機能により、テストをブラウザー上で直接実行し、window や document といったブラウザーのグローバルオブジェクトにアクセスできるようになります。本機能は現在開発中であり、将来的に API が変更される可能性があります。
TIP
expect、vi、またはテストプロジェクトや型テストといった一般的な API のドキュメントをお探しの場合には、「はじめに」ガイドをご参照ください。


インストール
セットアップを簡素化するために、vitest init browser コマンドを使用すると、必要な依存関係のインストールとブラウザー設定の作成を自動で行うことができます。
npx vitest init browseryarn exec vitest init browserpnpx vitest init browserbunx vitest init browser手動インストール
パッケージを手動でインストールすることも可能です。デフォルトでは、ブラウザーモードは既存のブラウザーを再利用するため、ローカルでテストを実行する際に別途 E2E プロバイダーは必要ありません。
npm install -D vitest @vitest/browseryarn add -D vitest @vitest/browserpnpm add -D vitest @vitest/browserbun add -D vitest @vitest/browserWARNING
ただし、CI でテストを実行するには、playwright または webdriverio のいずれかをインストールする必要があります。また、デフォルトの preview プロバイダーは Chrome DevTools Protocol を使用する代わりにイベントシミュレーションに依存しているため、ローカルでのテストにおいても、どちらかのプロバイダーに切り替えることを推奨します。
これらのツールのいずれかをまだ使用していない場合は、Playwright から始めることをお勧めします。Playwright は並列実行をサポートしているため、テストの実行が高速です。さらに、Playwright は Chrome DevTools Protocol を使用しており、これは一般的に WebDriver よりも高速です。
::: tabs key:provider == Playwright Playwright は、Web テストおよび自動化のためのフレームワークです。
npm install -D vitest @vitest/browser playwrightyarn add -D vitest @vitest/browser playwrightpnpm add -D vitest @vitest/browser playwrightbun add -D vitest @vitest/browser playwright== WebdriverIO
WebdriverIO を使用すると、WebDriver プロトコルを介してローカルでテストを実行できます。
npm install -D vitest @vitest/browser webdriverioyarn add -D vitest @vitest/browser webdriveriopnpm add -D vitest @vitest/browser webdriveriobun add -D vitest @vitest/browser webdriverio設定
Vitest の設定でブラウザーモードを有効にするには、Vitest 設定ファイルで browser.enabled フィールドを true に設定します。以下は、browser フィールドを使用した設定例です。
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
provider: 'playwright', // または 'webdriverio'
enabled: true,
// 少なくとも1つのインスタンスが必要
instances: [{ browser: 'chromium' }],
},
},
});INFO
Vitest は開発サーバーとの競合を避けるためにポート 63315 を割り当て、両方を並行して実行できるようにします。これは browser.api オプションで変更できます。
Vitest 2.1.5 以降、CLI は Vite URL を自動的に出力しなくなりました。ウォッチモードで実行中に「b」を押すと URL を出力できます。
Vite を使用したことがない場合は、フレームワークのプラグインがインストールされ、設定で指定されていることを確認してください。一部のフレームワークでは、動作するために追加の設定が必要な場合があります。それらの Vite 関連のドキュメントで確認してください。
import { defineConfig } from 'vitest/config';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
plugins: [vue()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import { svelte } from '@sveltejs/vite-plugin-svelte';
export default defineConfig({
plugins: [svelte()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import solidPlugin from 'vite-plugin-solid';
export default defineConfig({
plugins: [solidPlugin()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});import { defineConfig } from 'vitest/config';
import marko from '@marko/vite';
export default defineConfig({
plugins: [marko()],
test: {
browser: {
enabled: true,
provider: 'playwright',
instances: [{ browser: 'chromium' }],
},
},
});Node ベースのランナーを使用して一部のテストを実行する必要がある場合は、異なるテスト戦略に対して個別の設定を持つ projects オプションを定義できます。
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
projects: [
{
test: {
// ファイルベースの規約の例
// 必須ではありません
include: [
'tests/unit/**/*.{test,spec}.ts',
'tests/**/*.unit.{test,spec}.ts',
],
name: 'unit',
environment: 'node',
},
},
{
test: {
// ファイルベースの規約の例
// 必須ではありません
include: [
'tests/browser/**/*.{test,spec}.ts',
'tests/**/*.browser.{test,spec}.ts',
],
name: 'browser',
browser: {
enabled: true,
instances: [{ browser: 'chromium' }],
},
},
},
],
},
});ブラウザーオプションの型
Vitest のブラウザーオプションはプロバイダーに依存します。--browser を渡し、設定ファイルでその名前を指定しない場合、Vitest はエラーとなります。利用可能なオプションは以下の通りです。
webdriverioは以下のブラウザーをサポートしています:firefoxchromeedgesafari
playwrightは以下のブラウザーをサポートしています:firefoxwebkitchromium
TypeScript
デフォルトでは、TypeScript はプロバイダーオプションと expect の追加プロパティを認識しません。プロバイダーを使用しない場合は、@vitest/browser/matchers がテスト、セットアップファイル、または設定ファイルのどこかで参照されていることを確認し、expect の追加定義が認識されるようにしてください。カスタムプロバイダーを使用している場合は、TypeScript がカスタムオプションの定義を認識できるように、同じファイルに @vitest/browser/providers/playwright または @vitest/browser/providers/webdriverio を追加してください。
/// <reference types="@vitest/browser/matchers" />/// <reference types="@vitest/browser/providers/playwright" />/// <reference types="@vitest/browser/providers/webdriverio" />または、tsconfig.json ファイルの compilerOptions.types フィールドに追加することもできます。このフィールドに値を指定すると、@types/* パッケージの自動読み込みが無効になることに注意してください。
{
"compilerOptions": {
"types": ["@vitest/browser/matchers"]
}
}{
"compilerOptions": {
"types": ["@vitest/browser/providers/playwright"]
}
}{
"compilerOptions": {
"types": ["@vitest/browser/providers/webdriverio"]
}
}ブラウザーの互換性
Vitest は Vite 開発サーバーを使用してテストを実行するため、esbuild.target オプション(デフォルトでは esnext)で指定された機能のみをサポートします。
デフォルトでは、Vite はネイティブの ES Modules、ネイティブの ESM dynamic import、および import.meta をサポートするブラウザーをターゲットとしています。それに加えて、iframe 間の通信に BroadcastChannel を利用しています。
- Chrome >=87
- Firefox >=78
- Safari >=15.4
- Edge >=88
テストの実行
ブラウザーオプションでブラウザー名を指定すると、Vitest はデフォルトで preview を使用して指定されたブラウザーを起動し、そこでテストを実行します。preview を使用したくない場合は、browser.provider オプションを使用してカスタムブラウザープロバイダーを設定できます。
CLI を使用してブラウザーを指定するには、--browser フラグの後にブラウザー名を指定します。
npx vitest --browser=chromiumまたは、ドット記法でブラウザーオプションを CLI に指定することもできます。
npx vitest --browser.headlessWARNING
Vitest 3.2 以降、設定に browser オプションがないにもかかわらず --browser フラグを指定した場合、Vitest はエラーとなります。これは、設定がブラウザー用なのか Node.js テスト用なのかを Vitest が判断できないためです。
デフォルトでは、Vitest は開発用にブラウザー UI を自動的に開きます。テストは中央の iframe 内で実行されます。ビューポートは、推奨される寸法を選択するか、テスト内で page.viewport を呼び出すか、設定でデフォルト値を設定することで設定できます。
ヘッドレス
ヘッドレスモードは、ブラウザーモードで利用できるもう1つのオプションです。ヘッドレスモードでは、ブラウザーはユーザーインターフェースなしでバックグラウンドで実行されるため、自動テストの実行に役立ちます。Vitest のヘッドレスオプションは、ヘッドレスモードを有効または無効にするブール値で設定できます。
ヘッドレスモードを使用する場合、Vitest は UI を自動的に開きません。UI を引き続き使用しながらテストをヘッドレスで実行したい場合は、@vitest/ui パッケージをインストールし、Vitest の実行時に --ui フラグを渡すことができます。
ヘッドレスモードを有効にする設定例を次に示します。
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
browser: {
provider: 'playwright',
enabled: true,
headless: true,
},
},
});CLI で --browser.headless フラグを使用してヘッドレスモードを設定することもできます。
npx vitest --browser.headlessこの場合、Vitest は Chrome ブラウザーを使用してヘッドレスモードで実行されます。
WARNING
ヘッドレスモードはデフォルトでは利用できません。この機能を有効にするには、playwright または webdriverio プロバイダーのいずれかを使用する必要があります。
例
デフォルトでは、ブラウザーモードを使用するのに外部パッケージは必要ありません。
import { expect, test } from 'vitest';
import { page } from '@vitest/browser/context';
import { render } from './my-render-function.js';
test('properly handles form inputs', async () => {
render(); // DOM要素をマウントする
// 初期状態を確認
await expect
.element(page.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// 関連するラベルをクエリして入力DOMノードを取得
const usernameInput = page.getByLabelText(/username/i);
// 入力に名前を入力。これにより、入力が正しく入力されていることが検証されるため、
// 値を手動でチェックする必要はありません
await usernameInput.fill('Bob');
await expect
.element(page.getByText('Hi, my name is Bob'))
.toBeInTheDocument();
});ただし、Vitest はいくつかの人気のあるフレームワーク向けに、コンポーネントをすぐにレンダリングするためのパッケージも提供しています。
vitest-browser-vueで Vue コンポーネントをレンダリングvitest-browser-svelteで Svelte コンポーネントをレンダリングvitest-browser-reactで React コンポーネントをレンダリング
他のフレームワーク向けにはコミュニティパッケージが利用可能です。
vitest-browser-litで Lit コンポーネントをレンダリングvitest-browser-preactで Preact コンポーネントをレンダリング
あなたのフレームワークがリストにない場合は、独自のパッケージを作成してください。これはフレームワークのレンダラーと page.elementLocator API をラップするシンプルなものです。このページにリンクを追加します。名前が vitest-browser- で始まることを確認してください。
コンポーネントのレンダリングと要素の特定に加えて、アサーションも行う必要があります。Vitest は @testing-library/jest-dom ライブラリをフォークして、幅広い DOM アサーションを標準で提供します。Assertions API で詳細をご覧ください。
import { expect } from 'vitest';
import { page } from '@vitest/browser/context';
// 要素が正しくレンダリングされていることを確認
await expect.element(page.getByText('Hello World')).toBeInTheDocument();Vitest は、テストに有用な少数のユーティリティを含む Context API を公開しています。たとえば、要素のクリックや入力へのテキスト入力などの操作が必要な場合は、@vitest/browser/context から userEvent を使用できます。Interactivity API で詳細をご覧ください。
import { page, userEvent } from '@vitest/browser/context';
await userEvent.fill(page.getByLabelText(/username/i), 'Alice');
// または単に locator.fill
await page.getByLabelText(/username/i).fill('Alice');import { render } from 'vitest-browser-vue';
import Component from './Component.vue';
test('properly handles v-model', async () => {
const screen = render(Component);
// 初期状態を確認
await expect
.element(screen.getByText('Hi, my name is Alice'))
.toBeInTheDocument();
// 関連するラベルをクエリして入力DOMノードを取得
const usernameInput = screen.getByLabelText(/username/i);
// 入力に名前を入力。これにより、入力が正しく入力されていることが検証されるため、
// 値を手動でチェックする必要はありません
await usernameInput.fill('Bob');
await expect
.element(screen.getByText('Hi, my name is Bob'))
.toBeInTheDocument();
});import { render } from 'vitest-browser-svelte';
import { expect, test } from 'vitest';
import Greeter from './greeter.svelte';
test('greeting appears on click', async () => {
const screen = render(Greeter, { name: 'World' });
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/hello world/iu);
await expect.element(greeting).toBeInTheDocument();
});import { render } from 'vitest-browser-react';
import Fetch from './fetch';
test('loads and displays greeting', async () => {
// React要素をDOMにレンダリング
const screen = render(<Fetch url="/greeting" />);
await screen.getByText('Load Greeting').click();
// 要素が見つからない場合にエラーをスローする前に待機する
const heading = screen.getByRole('heading');
// アラートメッセージが正しいことをアサート
await expect.element(heading).toHaveTextContent('hello there');
await expect.element(screen.getByRole('button')).toBeDisabled();
});import { render } from 'vitest-browser-lit';
import { html } from 'lit';
import './greeter-button';
test('greeting appears on click', async () => {
const screen = render(html`<greeter-button name="World"></greeter-button>`);
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/hello world/iu);
await expect.element(greeting).toBeInTheDocument();
});import { render } from 'vitest-browser-preact';
import { createElement } from 'preact';
import Greeting from './Greeting';
test('greeting appears on click', async () => {
const screen = render(<Greeting />);
const button = screen.getByRole('button');
await button.click();
const greeting = screen.getByText(/hello world/iu);
await expect.element(greeting).toBeInTheDocument();
});Vitest はすべてのフレームワークを標準でサポートしているわけではありませんが、外部ツールを使用してこれらのフレームワークでテストを実行できます。また、コミュニティが独自の vitest-browser ラッパーを作成することを奨励しています。もし作成された場合は、上記の例に追加してください。
サポートされていないフレームワークについては、testing-library パッケージの使用をお勧めします。
@solidjs/testing-libraryで Solid コンポーネントをレンダリング@marko/testing-libraryで Marko コンポーネントをレンダリング
browser-examples リポジトリでさらに多くの例を見ることができます。
WARNING
testing-library は @testing-library/user-event パッケージを提供しています。これはイベントを実際にトリガーするのではなくシミュレートするため、直接使用することはお勧めしません。代わりに、内部で Chrome DevTools Protocol または Webdriver (プロバイダーによる) を使用する @vitest/browser/context からインポートされた userEvent を使用してください。
// @testing-library/solid API に基づく
// https://testing-library.com/docs/solid-testing-library/api
import { render } from '@testing-library/solid';
it('uses params', async () => {
const App = () => (
<>
<Route
path="/ids/:id"
component={() => (
<p>
Id:
{useParams()?.id}
</p>
)}
/>
<Route path="/" component={() => <p>Start</p>} />
</>
);
const { baseElement } = render(() => <App />, { location: 'ids/1234' });
const screen = page.elementLocator(baseElement);
await expect.screen(screen.getByText('Id: 1234')).toBeInTheDocument();
});// @testing-library/marko API に基づく
// https://testing-library.com/docs/marko-testing-library/api
import { render, screen } from '@marko/testing-library';
import Greeting from './greeting.marko';
test('renders a message', async () => {
const { baseElement } = await render(Greeting, { name: 'Marko' });
const screen = page.elementLocator(baseElement);
await expect.element(screen.getByText(/Marko/)).toBeInTheDocument();
expect(container.firstChild).toMatchInlineSnapshot(`
<h1>Hello, Marko!</h1>
`);
});制限事項
スレッドブロッキングダイアログ
Vitest Browser を使用する場合、alert や confirm のようなスレッドブロッキングダイアログはネイティブでは使用できないことに注意することが重要です。これは、これらのダイアログがウェブページをブロックし、Vitest がページとの通信を継続できなくなるため、実行が停止する原因となるためです。
このような状況では、Vitest はこれらの API のデフォルトの戻り値を持つデフォルトのモックを提供します。これにより、ユーザーが誤って同期ポップアップ Web API を使用した場合でも、実行がハングアップするのを防ぎます。ただし、より良い使用体験のためには、これらの Web API をモックすることをお勧めします。モックで詳細をご覧ください。