close

browser (experimental)

  • Type:
type BrowserModeConfig = {
  enabled?: boolean;
  provider: 'playwright';
  browser?: 'chromium' | 'firefox' | 'webkit';
  headless?: boolean;
  port?: number;
  strictPort?: boolean;
  providerOptions?: Record<string, unknown>;
};
  • Default:
const defaultBrowser = {
  enabled: false,
  provider: 'playwright',
  browser: 'chromium',
  headless: true, // CI environment; false for local development
  port: undefined, // Random available port
  strictPort: false,
  providerOptions: {},
};

Browser Mode configuration. When enabled, tests run in a real browser instead of the Node.js environment.

Options

enabled

  • Type: boolean
  • Default: false
  • CLI: --browser, --browser.enabled

Enable Browser Mode.

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
  },
});
Tip

Enabling Browser Mode requires installing the @rstest/browser package and Playwright browsers.

npm add @rstest/browser -D
npx playwright install chromium

provider

  • Type: 'playwright'
  • Default: 'playwright'

Browser driver provider. Currently only Playwright is supported.

Mixing multiple providers in the same test run is currently not supported.

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
  },
});

browser

  • Type: 'chromium' | 'firefox' | 'webkit'
  • Default: 'chromium'
  • CLI: --browser.name <name>

The browser type to use for testing.

  • chromium - Google Chrome, Microsoft Edge
  • firefox - Mozilla Firefox
  • webkit - Safari
rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
    browser: 'firefox',
  },
});

You need to install the corresponding browser before use:

# Install chromium
npx playwright install chromium

# Install Firefox
npx playwright install firefox

# Install WebKit
npx playwright install webkit

# Install all browsers
npx playwright install

headless

  • Type: boolean
  • Default: true in CI environments, false for local development
  • CLI: --browser.headless

Whether to run the browser in headless mode (without UI).

rstest.config.ts
CI (GitHub Actions)
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
    headless: true,
  },
});

During local development, setting headless: false shows the browser window for easier debugging.

Dynamic Configuration Based on Environment

If you want headed mode for local debugging and headless in CI, control it with environment variables:

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
    headless: process.env.CI === 'true',
  },
});

port

  • Type: number
  • Default: undefined (automatically selects an available port)
  • CLI: --browser.port <port>

The port number for the Browser Mode Dev Server.

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
    port: 5173,
  },
});

If you set port and the port is already in use, the behavior is controlled by strictPort: when strictPort: true, Rstest throws an error and exits; when strictPort: false, it falls back to another available port. If port is not specified, an available port is always selected automatically.

strictPort

  • Type: boolean
  • Default: false
  • CLI: --browser.strictPort

When port is specified, whether the port must be available:

  • true: throw an error and exit if the port is in use
  • false: fall back to another available port if the port is in use
rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
    port: 5173,
    strictPort: true,
  },
});

providerOptions

  • Type: Record<string, unknown>
  • Default: {}

Provider-specific options passed through to the selected browser provider. Rstest does not validate or interpret the contents of this object — it is forwarded as-is to the provider at both browser launch and context creation time.

The structure of providerOptions is defined by each provider. See the Provider options section below for details.

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
    providerOptions: {
      launch: {
        timeout: 60_000,
      },
    },
  },
});

Current limitation: browser launch options must match in one run

In one rstest process, all Browser Mode projects must share the same browser launch options:

  • provider
  • browser
  • headless
  • port
  • strictPort
  • providerOptions

This means mixing multiple providers, or running Chromium/Firefox/WebKit together in the same run, is not supported yet.

For cross-browser coverage, run tests in separate executions (for example, in a CI matrix):

npx rstest --browser.name chromium
npx rstest --browser.name firefox
npx rstest --browser.name webkit

Multi-project config isolation

When using projects in Browser Mode, each project still compiles and executes with its own build config (for example plugins, include, and framework-specific setup).

Browser launch options still need to stay aligned across browser projects: provider, browser, headless, port, strictPort, and providerOptions.

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  projects: ['./project-b/rstest.config.ts', './project-a/rstest.config.ts'],
});
project-a/rstest.config.ts
import { pluginReact } from '@rsbuild/plugin-react';
import { defineConfig } from '@rstest/core';

export default defineConfig({
  name: 'project-a',
  plugins: [pluginReact()],
  include: ['tests/**/*.test.tsx'],
  browser: {
    enabled: true,
    provider: 'playwright',
  },
});

Mixing with node tests

You can configure both browser tests and Node.js tests together:

rstest.config.ts
import { defineConfig } from '@rstest/core';

export default defineConfig({
  projects: [
    {
      name: 'browser',
      include: ['src/**/*.browser.test.ts'],
      browser: {
        enabled: true,
        provider: 'playwright',
      },
    },
    {
      name: 'node',
      include: ['src/**/*.node.test.ts'],
      testEnvironment: 'node',
    },
    {
      name: 'jsdom',
      include: ['src/**/*.test.ts'],
      exclude: ['src/**/*.browser.test.ts', 'src/**/*.node.test.ts'],
      testEnvironment: 'jsdom',
    },
  ],
});

Provider options

Playwright

When using provider: 'playwright', the Playwright provider recognizes the following fields in providerOptions:

  1. launch — Passed to Playwright's browserType.launch(). Controls how the browser process is started.
  2. context — Passed to Playwright's browser.newContext(). Controls the browser context created for each test file.

Since providerOptions is typed as Record<string, unknown>, you won't get IntelliSense out of the box. To get type checking and autocompletion, import types directly from the playwright package and use TypeScript's satisfies operator:

rstest.config.ts
import type { LaunchOptions, BrowserContextOptions } from 'playwright';
import { defineConfig } from '@rstest/core';

type PlaywrightProviderOptions = {
  launch?: LaunchOptions;
  context?: BrowserContextOptions;
};

export default defineConfig({
  browser: {
    enabled: true,
    provider: 'playwright',
    providerOptions: {
      launch: {
        timeout: 60_000,
      },
      context: {
        locale: 'en-US',
        colorScheme: 'dark',
      },
    } satisfies PlaywrightProviderOptions,
  },
});