963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
4.3 KiB
4.3 KiB
name, description
| name | description |
|---|---|
| test-environments | Configure environments like jsdom, happy-dom for browser APIs |
Test Environments
Available Environments
node(default) - Node.js environmentjsdom- Browser-like with DOM APIshappy-dom- Faster alternative to jsdomedge-runtime- Vercel Edge Runtime
Configuration
// vitest.config.ts
defineConfig({
test: {
environment: 'jsdom',
// Environment-specific options
environmentOptions: {
jsdom: {
url: 'http://localhost',
},
},
},
});
Installing Environment Packages
# jsdom
npm i -D jsdom
# happy-dom (faster, fewer APIs)
npm i -D happy-dom
Per-File Environment
Use magic comment at top of file:
// @vitest-environment jsdom
import { expect, test } from 'vitest';
test('DOM test', () => {
const div = document.createElement('div');
expect(div).toBeInstanceOf(HTMLDivElement);
});
jsdom Environment
Full browser environment simulation:
// @vitest-environment jsdom
test('DOM manipulation', () => {
document.body.innerHTML = '<div id="app"></div>';
const app = document.getElementById('app');
app.textContent = 'Hello';
expect(app.textContent).toBe('Hello');
});
test('window APIs', () => {
expect(window.location.href).toBeDefined();
expect(localStorage).toBeDefined();
});
jsdom Options
defineConfig({
test: {
environmentOptions: {
jsdom: {
url: 'http://localhost:3000',
html: '<!DOCTYPE html><html><body></body></html>',
userAgent: 'custom-agent',
resources: 'usable',
},
},
},
});
happy-dom Environment
Faster but fewer APIs:
// @vitest-environment happy-dom
test('basic DOM', () => {
const el = document.createElement('div');
el.className = 'test';
expect(el.className).toBe('test');
});
Multiple Environments per Project
Use projects for different environments:
defineConfig({
test: {
projects: [
{
test: {
name: 'unit',
include: ['tests/unit/**/*.test.ts'],
environment: 'node',
},
},
{
test: {
name: 'dom',
include: ['tests/dom/**/*.test.ts'],
environment: 'jsdom',
},
},
],
},
});
Custom Environment
Create custom environment package:
// vitest-environment-custom/index.ts
import type { Environment } from 'vitest/runtime';
export default <Environment>{
name: 'custom',
viteEnvironment: 'ssr', // or 'client'
setup() {
// Setup global state
globalThis.myGlobal = 'value';
return {
teardown() {
delete globalThis.myGlobal;
},
};
},
};
Use with:
defineConfig({
test: {
environment: 'custom',
},
});
Environment with VM
For full isolation:
export default <Environment>{
name: 'isolated',
viteEnvironment: 'ssr',
async setupVM() {
const vm = await import('node:vm');
const context = vm.createContext();
return {
getVmContext() {
return context;
},
teardown() {},
};
},
setup() {
return { teardown() {} };
},
};
Browser Mode (Separate from Environments)
For real browser testing, use Vitest Browser Mode:
defineConfig({
test: {
browser: {
enabled: true,
name: 'chromium', // or 'firefox', 'webkit'
provider: 'playwright',
},
},
});
CSS and Assets
In jsdom/happy-dom, configure CSS handling:
defineConfig({
test: {
css: true, // Process CSS
// Or with options
css: {
include: /\.module\.css$/,
modules: {
classNameStrategy: 'non-scoped',
},
},
},
});
Fixing External Dependencies
If external deps fail with CSS/asset errors:
defineConfig({
test: {
server: {
deps: {
inline: ['problematic-package'],
},
},
},
});
Key Points
- Default is
node- no browser APIs - Use
jsdomfor full browser simulation - Use
happy-domfor faster tests with basic DOM - Per-file environment via
// @vitest-environmentcomment - Use projects for multiple environment configurations
- Browser Mode is for real browser testing, not environment