Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Vitest 3.x reference skill covering configuration, test/describe APIs, mocking, coverage, snapshots, and concurrency.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/advanced-environments.md
1---2name: test-environments3description: Configure environments like jsdom, happy-dom for browser APIs4---56# Test Environments78## Available Environments910- `node` (default) - Node.js environment11- `jsdom` - Browser-like with DOM APIs12- `happy-dom` - Faster alternative to jsdom13- `edge-runtime` - Vercel Edge Runtime1415## Configuration1617```ts18// vitest.config.ts19defineConfig({20test: {21environment: 'jsdom',2223// Environment-specific options24environmentOptions: {25jsdom: {26url: 'http://localhost',27},28},29},30})31```3233## Installing Environment Packages3435```bash36# jsdom37npm i -D jsdom3839# happy-dom (faster, fewer APIs)40npm i -D happy-dom41```4243## Per-File Environment4445Use magic comment at top of file:4647```ts48// @vitest-environment jsdom4950import { expect, test } from 'vitest'5152test('DOM test', () => {53const div = document.createElement('div')54expect(div).toBeInstanceOf(HTMLDivElement)55})56```5758## jsdom Environment5960Full browser environment simulation:6162```ts63// @vitest-environment jsdom6465test('DOM manipulation', () => {66document.body.innerHTML = '<div id="app"></div>'6768const app = document.getElementById('app')69app.textContent = 'Hello'7071expect(app.textContent).toBe('Hello')72})7374test('window APIs', () => {75expect(window.location.href).toBeDefined()76expect(localStorage).toBeDefined()77})78```7980### jsdom Options8182```ts83defineConfig({84test: {85environmentOptions: {86jsdom: {87url: 'http://localhost:3000',88html: '<!DOCTYPE html><html><body></body></html>',89userAgent: 'custom-agent',90resources: 'usable',91},92},93},94})95```9697## happy-dom Environment9899Faster but fewer APIs:100101```ts102// @vitest-environment happy-dom103104test('basic DOM', () => {105const el = document.createElement('div')106el.className = 'test'107expect(el.className).toBe('test')108})109```110111## Multiple Environments per Project112113Use projects for different environments:114115```ts116defineConfig({117test: {118projects: [119{120test: {121name: 'unit',122include: ['tests/unit/**/*.test.ts'],123environment: 'node',124},125},126{127test: {128name: 'dom',129include: ['tests/dom/**/*.test.ts'],130environment: 'jsdom',131},132},133],134},135})136```137138## Custom Environment139140Create custom environment package:141142```ts143// vitest-environment-custom/index.ts144import type { Environment } from 'vitest/runtime'145146export default <Environment>{147name: 'custom',148viteEnvironment: 'ssr', // or 'client'149150setup() {151// Setup global state152globalThis.myGlobal = 'value'153154return {155teardown() {156delete globalThis.myGlobal157},158}159},160}161```162163Use with:164165```ts166defineConfig({167test: {168environment: 'custom',169},170})171```172173## Environment with VM174175For full isolation:176177```ts178export default <Environment>{179name: 'isolated',180viteEnvironment: 'ssr',181182async setupVM() {183const vm = await import('node:vm')184const context = vm.createContext()185186return {187getVmContext() {188return context189},190teardown() {},191}192},193194setup() {195return { teardown() {} }196},197}198```199200## Browser Mode (Separate from Environments)201202For real browser testing, use Vitest Browser Mode. In **v4 the provider is an object** (not a string), and the context imports from `vitest/browser`:203204```ts205import { playwright } from '@vitest/browser-playwright'206207defineConfig({208test: {209browser: {210enabled: true,211provider: playwright({ launchOptions: { slowMo: 100 } }),212instances: [{ browser: 'chromium' }], // or 'firefox', 'webkit'213},214},215})216```217218```ts219import { page } from 'vitest/browser' // v4: was '@vitest/browser/context'220```221222> v5: DOM-environment global assignments (e.g. `window.innerWidth`) now propagate to the underlying jsdom/happy-dom implementation. Locators are also exact/strict by default.223224## CSS and Assets225226In jsdom/happy-dom, configure CSS handling:227228```ts229defineConfig({230test: {231css: true, // Process CSS232233// Or with options234css: {235include: /\.module\.css$/,236modules: {237classNameStrategy: 'non-scoped',238},239},240},241})242```243244## Fixing External Dependencies245246If external deps fail with CSS/asset errors:247248```ts249defineConfig({250test: {251server: {252deps: {253inline: ['problematic-package'],254},255},256},257})258```259260## Key Points261262- Default is `node` - no browser APIs263- Use `jsdom` for full browser simulation264- Use `happy-dom` for faster tests with basic DOM265- Per-file environment via `// @vitest-environment` comment266- Use projects for multiple environment configurations267- Browser Mode is for real browser testing, not environment268269<!--270Source references:271- https://vitest.dev/guide/environment.html272-->273