enigmare/v2-crawler
1904
1{"id":"doc-getting_started_guide_vitest-09d2f001","source":"documentation","title":"Getting Started | Guide | Vitest","url":"https://vitest.dev/guide/","text":"Example:\n```text\nnpm install -D vitest\n```\n\nExample:\n```text\nyarn add -D vitest\n```\n\nExample:\n```text\npnpm add -D vitest\n```\n\nExample:\n```text\nbun add -D vitest\n```\n\nExample:\n```text\nexport function sum(a, b) {\n return a + b\n}\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\nimport { sum } from './sum.js'\n\ntest('adds 1 + 2 to equal 3', () => {\n expect(sum(1, 2)).toBe(3)\n})\n```\n\nExample:\n```text\n{\n \"scripts\": {\n \"test\": \"vitest\"\n }\n}\n```\n\nExample:\n```text\n✓ sum.test.js (1)\n ✓ adds 1 + 2 to equal 3\n\nTest Files 1 passed (1)\n Tests 1 passed (1)\n Start at 02:15:44\n Duration 311ms\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.911Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":58,"estimatedTokens":157}}2{"id":"doc-multiple_setups_vitest-bb72b1f2","source":"documentation","title":"Multiple Setups | Vitest","url":"https://vitest.dev/guide/browser/multiple-setups","text":"Example:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n headless: true,\n instances: [\n { browser: 'chromium' },\n { browser: 'firefox' },\n { browser: 'webkit' },\n ],\n },\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n headless: true,\n instances: [\n {\n browser: 'chromium',\n name: 'chromium-1',\n setupFiles: ['./ratio-setup.ts'],\n provide: {\n ratio: 1,\n },\n },\n {\n browser: 'chromium',\n name: 'chromium-2',\n provide: {\n ratio: 2,\n },\n },\n ],\n },\n },\n})\n```\n\nExample:\n```text\nimport { expect, inject, test } from 'vitest'\nimport { globalSetupModifier } from './example.js'\n\ntest('ratio works', () => {\n expect(inject('ratio') * globalSetupModifier).toBe(14)\n})\n```\n\nExample:\n```text\n$ vitest --project=chromium\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n browser: {\n instances: [\n // name: chromium\n { browser: 'chromium' },\n // name: custom\n { browser: 'firefox', name: 'custom' },\n ]\n }\n }\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n name: 'custom',\n browser: {\n instances: [\n // name: custom (chromium)\n { browser: 'chromium' },\n // name: manual\n { browser: 'firefox', name: 'manual' },\n ]\n }\n }\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.911Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":103,"estimatedTokens":451}}3{"id":"doc-debugging_failing_tests_guide_vitest-5eab577c","source":"documentation","title":"Debugging Failing Tests | Guide | Vitest","url":"https://vitest.dev/guide/learn/debugging-tests","text":"Example:\n```text\nFAIL src/user.test.js > createUser > sets the default role\nAssertionError: expected { name: 'Alice', role: 'viewer' } to deeply equal { name: 'Alice', role: 'member' }\n\n- Expected\n+ Received\n\n {\n \"name\": \"Alice\",\n- \"role\": \"member\",\n+ \"role\": \"viewer\",\n }\n\n ❯ src/user.test.js:8:22\n 6| test('sets the default role', () => {\n 7| const user = createUser('Alice')\n 8| expect(user).toEqual({ name: 'Alice', role: 'member' })\n ^\n 9| })\n 10| })\n```\n\nExample:\n```text\n# Run only the failing test file\nvitest src/user.test.js\n\n# Run only tests matching a name pattern\nvitest -t \"sets the default role\"\n\n# Combine both for maximum precision\nvitest src/user.test.js -t \"sets the default role\"\n```\n\nExample:\n```text\ntest.only('sets the default role', () => {\n // only this test runs in the file\n})\n```\n\nExample:\n```text\nvitest --bail 1\n```\n\nExample:\n```text\n// This is a problem: `users` is shared between tests\nconst users = []\n\ntest('adds a user', () => {\n users.push('Alice')\n expect(users).toEqual(['Alice'])\n})\n\ntest('starts empty', () => {\n // This fails because 'Alice' is still in the array!\n expect(users).toEqual([])\n})\n```\n\nExample:\n```text\nconst test = baseTest.extend('users', () => [])\n\ntest('adds a user', ({ users }) => {\n users.push('Alice')\n expect(users).toEqual(['Alice'])\n})\n\ntest('starts empty', ({ users }) => {\n // Passes: each test gets its own array\n expect(users).toEqual([])\n})\n```\n\nExample:\n```text\n// This test always passes, even if fetchUser rejects!\ntest('fetches user', () => {\n // Missing await: the test finishes before the promise settles\n expect(fetchUser(1)).resolves.toMatchObject({ name: 'Alice' })\n})\n```\n\nExample:\n```text\ntest('fetches user', async () => {\n await expect(fetchUser(1)).resolves.toMatchObject({ name: 'Alice' })\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n restoreMocks: true,\n },\n})\n```\n\nExample:\n```text\ntest('transforms data correctly', () => {\n const input = getData()\n console.log('input:', input)\n\n const result = transform(input)\n console.log('result:', result)\n\n expect(result).toMatchObject({ status: 'ok' })\n})\n```\n\nExample:\n```text\nvitest --ui\n```\n\nExample:\n```text\nvitest --reporter=verbose\n```\n\nExample:\n```text\nvitest --inspect-brk --no-file-parallelism\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.912Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":134,"estimatedTokens":602}}4{"id":"doc-using_matchers_guide_vitest-e2a10797","source":"documentation","title":"Using Matchers | Guide | Vitest","url":"https://vitest.dev/guide/learn/matchers","text":"Example:\n```text\nimport { expect, test } from 'vitest'\n\ntest('two plus two is four', () => {\n expect(2 + 2).toBe(4)\n})\n```\n\nExample:\n```text\ntest('object assignment', () => {\n const data = { one: 1 }\n data.two = 2\n\n expect(data).toEqual({ one: 1, two: 2 })\n})\n```\n\nExample:\n```text\ntest('toBe vs toEqual', () => {\n const a = { name: 'Alice' }\n const b = { name: 'Alice' }\n\n // These are different objects in memory\n expect(a).not.toBe(b)\n\n // But they have the same structure\n expect(a).toEqual(b)\n})\n```\n\nExample:\n```text\ntest('toEqual vs toStrictEqual', () => {\n // toEqual ignores undefined properties\n expect({ a: 1 }).toEqual({ a: 1, b: undefined })\n\n // toStrictEqual catches them\n expect({ a: 1 }).not.toStrictEqual({ a: 1, b: undefined })\n\n // toEqual doesn't check object types\n class User {\n constructor(name) {\n this.name = name\n }\n }\n expect(new User('Alice')).toEqual({ name: 'Alice' })\n expect(new User('Alice')).not.toStrictEqual({ name: 'Alice' })\n})\n```\n\nExample:\n```text\ntest('adding positive numbers is not zero', () => {\n expect(1 + 2).not.toBe(0)\n})\n```\n\nExample:\n```text\ntest('null checks', () => {\n const n = null\n\n expect(n).toBeNull()\n expect(n).toBeDefined()\n expect(n).toBeFalsy()\n expect(n).not.toBeTruthy()\n expect(n).not.toBeUndefined()\n})\n\ntest('zero', () => {\n const z = 0\n\n expect(z).toBeDefined() // passes: 0 is defined\n expect(z).toBeFalsy() // passes: 0 is falsy\n expect(z).not.toBeNull() // passes: 0 is not null\n})\n```\n\nExample:\n```text\ntest('number comparisons', () => {\n const value = 2 + 2\n\n expect(value).toBeGreaterThan(3)\n expect(value).toBeGreaterThanOrEqual(3.5)\n expect(value).toBeLessThan(5)\n expect(value).toBeLessThanOrEqual(4.5)\n\n // For exact equality, both toBe and toEqual work the same for numbers\n expect(value).toBe(4)\n expect(value).toEqual(4)\n})\n```\n\nExample:\n```text\ntest('adding floating point numbers', () => {\n const value = 0.1 + 0.2\n\n // This won't work because of floating point rounding\n // expect(value).toBe(0.3)\n\n // This works\n expect(value).toBeCloseTo(0.3)\n})\n```\n\nExample:\n```text\ntest('there is no I in team', () => {\n expect('team').not.toMatch(/I/)\n})\n\ntest('version string matches semver format', () => {\n expect('vitest@1.0.0').toMatch(/vitest@\\d+\\.\\d+\\.\\d+/)\n})\n```\n\nExample:\n```text\ntest('the shopping list has milk in it', () => {\n const shoppingList = ['milk', 'bread', 'eggs', 'butter']\n\n expect(shoppingList).toContain('milk')\n expect(new Set(shoppingList)).toContain('milk')\n})\n```\n\nExample:\n```text\ntest('user has expected fields', () => {\n const user = {\n id: 1,\n name: 'Alice',\n email: 'alice@example.com',\n createdAt: '2024-01-01'\n }\n\n // We only care about name and email here\n expect(user).toMatchObject({\n name: 'Alice',\n email: 'alice@example.com',\n })\n})\n```\n\nExample:\n```text\ntest('object has property', () => {\n const user = {\n name: 'Alice',\n address: { city: 'Paris', zip: '75001' }\n }\n\n expect(user).toHaveProperty('name')\n expect(user).toHaveProperty('name', 'Alice')\n expect(user).toHaveProperty('address.city', 'Paris')\n expect(user).toHaveProperty('address.zip')\n})\n```\n\nExample:\n```text\ntest('user has the right shape', () => {\n const user = createUser('Alice')\n\n expect(user).toEqual({\n id: expect.any(Number),\n name: 'Alice',\n email: expect.stringContaining('@'),\n roles: expect.arrayContaining(['viewer']),\n })\n})\n```\n\nExample:\n```text\nfunction compileCode(code) {\n if (code === '') {\n throw new Error('Cannot compile empty string')\n }\n return code\n}\n\ntest('compiling an empty string throws', () => {\n // Check that it throws at all\n expect(() => compileCode('')).toThrow()\n\n // Check the error message\n expect(() => compileCode('')).toThrow('Cannot compile empty string')\n\n // Check the message with a regex\n expect(() => compileCode('')).toThrow(/empty string/)\n})\n```\n\nExample:\n```text\ntest('check multiple fields', () => {\n const user = { name: 'Alice', age: 30, role: 'admin' }\n\n expect.soft(user.name).toBe('Alice')\n expect.soft(user.age).toBe(25) // this fails but execution continues\n expect.soft(user.role).toBe('admin')\n // the test report will show that age didn't match\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.912Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":15,"totalLines":212,"estimatedTokens":1060}}5{"id":"doc-writing_tests_with_ai_guide_vitest-83105e7d","source":"documentation","title":"Writing Tests with AI | Guide | Vitest","url":"https://vitest.dev/guide/learn/writing-tests-with-ai","text":"Example:\n```text\ntest('creates a user', () => {\n const user = createUser('Alice', 'alice@example.com')\n expect(user).toBeDefined() // this passes for almost anything\n})\n```\n\nExample:\n```text\ntest('creates a user with the correct fields', () => {\n const user = createUser('Alice', 'alice@example.com')\n expect(user).toMatchObject({\n name: 'Alice',\n email: 'alice@example.com',\n })\n expect(user.id).toBeTypeOf('string')\n})\n```\n\nExample:\n```text\nvitest run src/userService.test.js\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.913Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":26,"estimatedTokens":127}}6{"id":"doc-snapshot_testing_guide_vitest-460700f9","source":"documentation","title":"Snapshot Testing | Guide | Vitest","url":"https://vitest.dev/guide/learn/snapshots","text":"Example:\n```text\nimport { expect, test } from 'vitest'\n\nfunction generateGreeting(name) {\n return {\n message: `Hello, ${name}!`,\n timestamp: null,\n version: 2,\n }\n}\n\ntest('generates a greeting', () => {\n expect(generateGreeting('Alice')).toMatchSnapshot()\n})\n```\n\nExample:\n```text\n__snapshots__/\n example.test.js.snap\n```\n\nExample:\n```text\nexports['generates a greeting 1'] = `\n{\n \"message\": \"Hello, Alice!\",\n \"timestamp\": null,\n \"version\": 2,\n}\n`\n```\n\nExample:\n```text\ntest('generates a greeting', () => {\n expect(generateGreeting('Alice')).toMatchInlineSnapshot()\n})\n```\n\nExample:\n```text\ntest('generates a greeting', () => {\n expect(generateGreeting('Alice')).toMatchInlineSnapshot(`\n {\n \"message\": \"Hello, Alice!\",\n \"timestamp\": null,\n \"version\": 2,\n }\n `)\n})\n```\n\nExample:\n```text\nvitest -u\n```\n\nExample:\n```text\ntest('renders the component', async () => {\n const html = renderComponent()\n await expect(html).toMatchFileSnapshot('./fixtures/component.html')\n})\n```\n\nExample:\n```text\ntest('user snapshot with dynamic fields', () => {\n const user = createUser('Alice')\n\n expect(user).toMatchSnapshot({\n id: expect.any(Number),\n createdAt: expect.any(Date),\n })\n})\n```\n\nExample:\n```text\ntest('throws on invalid input', () => {\n expect(() => parse('')).toThrowErrorMatchingInlineSnapshot(\n `[Error: Unexpected end of input at position 0]`\n )\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.913Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":89,"estimatedTokens":355}}7{"id":"doc-writing_tests_guide_vitest-a29949c5","source":"documentation","title":"Writing Tests | Guide | Vitest","url":"https://vitest.dev/guide/learn/writing-tests","text":"Example:\n```text\nimport { expect, test } from 'vitest'\n\ntest('Math.sqrt works for perfect squares', () => {\n expect(Math.sqrt(4)).toBe(2)\n expect(Math.sqrt(144)).toBe(12)\n expect(Math.sqrt(0)).toBe(0)\n})\n```\n\nExample:\n```text\nimport { expect, it } from 'vitest'\n\nit('should compute square roots', () => {\n expect(Math.sqrt(4)).toBe(2)\n})\n```\n\nExample:\n```text\nimport { describe, expect, test } from 'vitest'\n\ndescribe('Math.sqrt', () => {\n test('returns the square root of perfect squares', () => {\n expect(Math.sqrt(4)).toBe(2)\n expect(Math.sqrt(9)).toBe(3)\n })\n\n test('returns NaN for negative numbers', () => {\n expect(Math.sqrt(-1)).toBeNaN()\n })\n\n test('returns 0 for 0', () => {\n expect(Math.sqrt(0)).toBe(0)\n })\n})\n```\n\nExample:\n```text\nsrc/\n utils.js\n utils.test.js # co-located with the source\n __tests__/\n utils.test.js # in a test directory\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\n\ninterface User {\n name: string\n age: number\n}\n\nfunction createUser(name: string, age: number): User {\n return { name, age }\n}\n\ntest('creates a user with the correct fields', () => {\n const user = createUser('Alice', 30)\n\n expect(user).toEqual({ name: 'Alice', age: 30 })\n expect(user.name).toBe('Alice')\n})\n```\n\nExample:\n```text\n✓ src/utils.test.js (3 tests) 5ms\n ✓ Math.sqrt 4ms\n ✓ returns the square root of perfect squares 2ms\n ✓ returns NaN for negative numbers 1ms\n ✓ returns 0 for 0 1ms\n\n Test Files 1 passed (1)\n Tests 3 passed (3)\n```\n\nExample:\n```text\n✓ src/utils.test.js (3 tests) 5ms\n ✓ src/math.test.js (2 tests) 3ms\n ✓ src/strings.test.js (4 tests) 7ms\n\n Test Files 3 passed (3)\n Tests 9 passed (9)\n```\n\nExample:\n```text\nFAIL src/utils.test.js > Math.sqrt > returns the square root of perfect squares\nAssertionError: expected 3 to be 2\n\n- Expected\n+ Received\n\n 2\n 3\n\n ❯ src/utils.test.js:5:28\n 3| test('returns the square root of perfect squares', () => {\n 4| expect(Math.sqrt(4)).toBe(2)\n 5| expect(Math.sqrt(9)).toBe(2)\n ^\n 6| })\n 7|\n```\n\nExample:\n```text\ntest.only('focus on this test', () => {\n // only this test runs in the file\n})\n```\n\nExample:\n```text\ntest.skip('not ready yet', () => {\n // this test is skipped\n})\n```\n\nExample:\n```text\ntest.todo('implement validation later')\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\n\ntest.for([\n [1, 1, 2],\n [1, 2, 3],\n [2, 1, 3],\n])('add(%i, %i) -> %i', ([a, b, expected]) => {\n expect(a + b).toBe(expected)\n})\n```\n\nExample:\n```text\ntest.for([\n { a: 1, b: 1, expected: 2 },\n { a: 1, b: 2, expected: 3 },\n { a: 2, b: 1, expected: 3 },\n])('add($a, $b) -> $expected', ({ a, b, expected }) => {\n expect(a + b).toBe(expected)\n})\n```\n\nExample:\n```text\ntest.concurrent.for([\n [1, 1],\n [1, 2],\n [2, 1],\n])('add(%i, %i)', ([a, b], { expect }) => {\n expect(a + b).toMatchSnapshot()\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n globals: true,\n },\n})\n```\n\nExample:\n```text\ntest('no import needed', () => {\n expect(1 + 1).toBe(2)\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.914Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":16,"totalLines":185,"estimatedTokens":789}}8{"id":"doc-testing_asynchronous_code_guide_vitest-86b9892b","source":"documentation","title":"Testing Asynchronous Code | Guide | Vitest","url":"https://vitest.dev/guide/learn/async","text":"Example:\n```text\nimport { expect, test } from 'vitest'\n\nfunction fetchUser(id) {\n return Promise.resolve({ id, name: 'Alice' })\n}\n\ntest('fetches user by id', async () => {\n const user = await fetchUser(1)\n expect(user.name).toBe('Alice')\n})\n```\n\nExample:\n```text\ntest('resolves to Alice', async () => {\n await expect(fetchUser(1)).resolves.toMatchObject({ name: 'Alice' })\n})\n\ntest('rejects with an error', async () => {\n await expect(fetchInvalidUser()).rejects.toThrow('User not found')\n})\n```\n\nExample:\n```text\ntest('callback is invoked', async () => {\n expect.hasAssertions()\n\n const data = await fetchData()\n data.items.forEach((item) => {\n expect(item.id).toBeDefined()\n })\n // if data.items is empty, the test fails instead of silently passing\n})\n```\n\nExample:\n```text\ntest('both callbacks are called', async () => {\n expect.assertions(2)\n\n await Promise.all([\n fetchUser(1).then(user => expect(user.name).toBe('Alice')),\n fetchUser(2).then(user => expect(user.name).toBe('Bob')),\n ])\n})\n```\n\nExample:\n```text\nfunction fetchData(callback) {\n setTimeout(() => callback('peanut butter'), 100)\n}\n\ntest('the data is peanut butter', async () => {\n const data = await new Promise((resolve) => {\n fetchData(resolve)\n })\n expect(data).toBe('peanut butter')\n})\n```\n\nExample:\n```text\ntest('long-running operation', async () => {\n await someSlowOperation()\n}, 10_000) // 10 seconds\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n testTimeout: 10_000,\n },\n})\n```\n\nExample:\n```text\ntest('this causes an unhandled rejection error', () => {\n // This promise rejects but is never awaited or caught\n Promise.reject(new Error('oops'))\n})\n```\n\nExample:\n```text\ntest('handle the rejection', async () => {\n // Either await the promise\n await expect(Promise.reject(new Error('oops'))).rejects.toThrow('oops')\n\n // Or catch it explicitly if you don't need to assert on it\n Promise.reject(new Error('expected')).catch(() => {})\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.914Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":102,"estimatedTokens":508}}9{"id":"doc-setup_and_teardown_guide_vitest-9c30da27","source":"documentation","title":"Setup and Teardown | Guide | Vitest","url":"https://vitest.dev/guide/learn/setup-teardown","text":"Example:\n```text\nimport { afterEach, beforeEach, expect, test } from 'vitest'\n\nlet items\n\nbeforeEach(() => {\n items = ['apple', 'banana', 'cherry']\n})\n\nafterEach(() => {\n items = []\n})\n\ntest('items starts with 3 fruits', () => {\n expect(items).toHaveLength(3)\n})\n\ntest('can add an item', () => {\n items.push('date')\n expect(items).toHaveLength(4)\n // afterEach will reset items for the next test,\n // so this mutation won't leak into other tests\n})\n```\n\nExample:\n```text\nimport { afterAll, beforeAll, expect, test } from 'vitest'\n\nlet db\n\nbeforeAll(async () => {\n db = await connectToDatabase()\n})\n\nafterAll(async () => {\n await db.close()\n})\n\ntest('can query users', async () => {\n const users = await db.query('SELECT * FROM users')\n expect(users.length).toBeGreaterThan(0)\n})\n\ntest('can query products', async () => {\n const products = await db.query('SELECT * FROM products')\n expect(products.length).toBeGreaterThan(0)\n})\n```\n\nExample:\n```text\nimport { beforeEach, describe, expect, test } from 'vitest'\n\ndescribe('math operations', () => {\n let value\n\n beforeEach(() => {\n value = 0\n })\n\n test('can add', () => {\n value += 5\n expect(value).toBe(5)\n })\n\n test('can subtract', () => {\n value -= 3\n expect(value).toBe(-3) // value was reset to 0 by beforeEach\n })\n})\n\ndescribe('string operations', () => {\n let text\n\n beforeEach(() => {\n text = 'hello'\n })\n\n test('can uppercase', () => {\n expect(text.toUpperCase()).toBe('HELLO')\n })\n})\n```\n\nExample:\n```text\nimport { afterAll, afterEach, beforeAll, beforeEach, describe, test } from 'vitest'\n\nbeforeAll(() => console.log('1 - beforeAll'))\nafterAll(() => console.log('8 - afterAll'))\nbeforeEach(() => console.log('2 - beforeEach'))\nafterEach(() => console.log('5 - afterEach'))\n\ndescribe('suite', () => {\n beforeEach(() => console.log('3 - inner beforeEach'))\n afterEach(() => console.log('4 - inner afterEach'))\n\n test('first test', () => {\n console.log(' first test')\n })\n\n test('second test', () => {\n console.log(' second test')\n })\n})\n```\n\nExample:\n```text\n1 - beforeAll\n2 - beforeEach\n3 - inner beforeEach\n first test\n4 - inner afterEach\n5 - afterEach\n2 - beforeEach\n3 - inner beforeEach\n second test\n4 - inner afterEach\n5 - afterEach\n8 - afterAll\n```\n\nExample:\n```text\nimport { expect, onTestFinished, test } from 'vitest'\n\ntest('creates a temporary file', () => {\n const file = createTempFile()\n onTestFinished(() => {\n deleteTempFile(file)\n })\n\n expect(file.exists()).toBe(true)\n})\n```\n\nExample:\n```text\nimport { beforeEach } from 'vitest'\n\nbeforeEach(() => {\n const server = startServer()\n return () => {\n server.close()\n }\n})\n```\n\nExample:\n```text\nimport { test as baseTest } from 'vitest'\n\nexport const test = baseTest\n .extend('db', async ({}, { onCleanup }) => {\n const db = await createDatabase()\n onCleanup(() => db.close())\n return db\n })\n .extend('user', async ({ db }) => {\n return await db.createUser({ name: 'Alice' })\n })\n```\n\nExample:\n```text\nimport { expect } from 'vitest'\nimport { test } from './my-test.js'\n\ntest('user is created', ({ db, user }) => {\n expect(user.name).toBe('Alice')\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n setupFiles: ['./test/setup.js'],\n },\n})\n```\n\nExample:\n```text\n// This runs before every test file\nimport { expect } from 'vitest'\nimport { customMatchers } from './custom-matchers.js'\n\nexpect.extend(customMatchers)\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.915Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":197,"estimatedTokens":877}}10{"id":"doc-mock_functions_guide_vitest-9f14e657","source":"documentation","title":"Mock Functions | Guide | Vitest","url":"https://vitest.dev/guide/learn/mock-functions","text":"Example:\n```text\nimport { expect, test, vi } from 'vitest'\n\ntest('mock function basics', () => {\n const getApples = vi.fn()\n\n // Call it\n getApples()\n\n // Check it was called\n expect(getApples).toHaveBeenCalled()\n expect(getApples).toHaveBeenCalledTimes(1)\n\n // By default, a mock returns undefined\n expect(getApples()).toBeUndefined()\n})\n```\n\nExample:\n```text\nimport { expect, test, vi } from 'vitest'\n\ntest('mock return values', () => {\n const getApples = vi.fn()\n\n // Always return this value\n getApples.mockReturnValue(10)\n expect(getApples()).toBe(10)\n\n // Return this value only once, then fall back to the default\n getApples.mockReturnValueOnce(20)\n expect(getApples()).toBe(20) // 20 (one-time)\n expect(getApples()).toBe(10) // back to default\n})\n```\n\nExample:\n```text\ntest('mock async return values', async () => {\n const fetchUser = vi.fn()\n\n fetchUser.mockResolvedValue({ name: 'Alice' })\n const user = await fetchUser()\n expect(user.name).toBe('Alice')\n\n fetchUser.mockRejectedValue(new Error('Not found'))\n await expect(fetchUser()).rejects.toThrow('Not found')\n})\n```\n\nExample:\n```text\nimport { expect, test, vi } from 'vitest'\n\ntest('mock with custom implementation', () => {\n const add = vi.fn()\n add.mockImplementation((a, b) => a + b)\n\n expect(add(1, 2)).toBe(3)\n expect(add(10, 20)).toBe(30)\n})\n```\n\nExample:\n```text\nconst add = vi.fn((a, b) => a + b)\n```\n\nExample:\n```text\nimport { expect, test, vi } from 'vitest'\n\ntest('inspecting mock calls', () => {\n const greet = vi.fn()\n\n greet('Alice')\n greet('Bob', 'Charlie')\n\n // Number of calls\n expect(greet).toHaveBeenCalledTimes(2)\n\n // Check specific arguments\n expect(greet).toHaveBeenCalledWith('Alice')\n expect(greet).toHaveBeenCalledWith('Bob', 'Charlie')\n\n // Check the arguments of a specific call by position\n expect(greet).toHaveBeenNthCalledWith(1, 'Alice')\n expect(greet).toHaveBeenLastCalledWith('Bob', 'Charlie')\n\n // Access the raw call data\n expect(greet.mock.calls).toEqual([\n ['Alice'],\n ['Bob', 'Charlie'],\n ])\n})\n```\n\nExample:\n```text\nconst double = vi.fn(x => x * 2)\n\ndouble(5)\ndouble(10)\n\nexpect(double.mock.results).toEqual([\n { type: 'return', value: 10 },\n { type: 'return', value: 20 },\n])\n```\n\nExample:\n```text\nconst fn = vi.fn()\nconst obj = { count: 1 }\n\nfn(obj)\nobj.count = 2\n\n// ❌ This fails! mock.calls[0][0].count is now 2, not 1\nexpect(fn).toHaveBeenCalledWith({ count: 1 })\n```\n\nExample:\n```text\nconst calls = []\nconst fn = vi.fn((obj) => {\n calls.push(structuredClone(obj))\n})\n\nconst obj = { count: 1 }\nfn(obj)\nobj.count = 2\n\nexpect(calls[0]).toEqual({ count: 1 }) // ✅ passes\n```\n\nExample:\n```text\nimport { expect, test, vi } from 'vitest'\n\nconst calculator = {\n add(a, b) {\n return a + b\n },\n}\n\ntest('spy on a method', () => {\n const spy = vi.spyOn(calculator, 'add')\n\n // The original implementation still works\n expect(calculator.add(1, 2)).toBe(3)\n\n // But we can observe calls\n expect(spy).toHaveBeenCalledWith(1, 2)\n expect(spy).toHaveBeenCalledTimes(1)\n})\n\ntest('spy can override implementation', () => {\n const spy = vi.spyOn(calculator, 'add')\n spy.mockReturnValue(42)\n\n expect(calculator.add(1, 2)).toBe(42)\n})\n```\n\nExample:\n```text\nimport { afterEach, expect, test, vi } from 'vitest'\n\nconst calculator = {\n add: (a, b) => a + b,\n}\n\nafterEach(() => {\n vi.restoreAllMocks()\n})\n\ntest('spy is restored after the test', () => {\n const spy = vi.spyOn(calculator, 'add').mockReturnValue(42)\n expect(calculator.add(1, 2)).toBe(42)\n // afterEach will restore calculator.add to the original implementation\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n restoreMocks: true,\n },\n})\n```\n\nExample:\n```text\nimport { expect, test, vi } from 'vitest'\nimport { getUser } from './db.js'\n\nvi.mock(import('./db.js'), () => ({\n getUser: vi.fn(),\n}))\n\ntest('mock a module', () => {\n vi.mocked(getUser).mockReturnValue({ name: 'Alice' })\n\n const user = getUser(1)\n expect(user.name).toBe('Alice')\n expect(getUser).toHaveBeenCalledWith(1)\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.915Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":215,"estimatedTokens":1023}}11{"id":"doc-component_testing_guide_vitest-34fd0d41","source":"documentation","title":"Component Testing | Guide | Vitest","url":"https://vitest.dev/guide/browser/component-testing","text":"Example:\n```text\n1. Critical User Paths → Always test these\n2. Error Handling → Test failure scenarios\n3. Edge Cases → Empty data, extreme values\n4. Accessibility → Screen readers, keyboard nav\n5. Performance → Large datasets, animations\n```\n\nExample:\n```text\n// For API requests, we recommend MSW (Mock Service Worker)\n// See: https://vitest.dev/guide/mocking/requests\n//\n// vi.mock(import('../api/userService'), () => ({\n// fetchUser: vi.fn().mockResolvedValue({ name: 'John' })\n// }))\n\n// Mock child components to focus on parent logic\nvi.mock(import('../components/UserCard'), () => ({\n default: vi.fn(({ user }) => `<div>User: ${user.name}</div>`)\n}))\n\ntest('UserProfile handles loading and data states', async () => {\n const { getByText } = render(<UserProfile userId=\"123\" />)\n\n // Test loading state\n await expect.element(getByText('Loading...')).toBeInTheDocument()\n\n // Test for data to load (expect.element auto-retries)\n await expect.element(getByText('User: John')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\ntest('ProductList filters and displays products correctly', async () => {\n const mockProducts = [\n { id: 1, name: 'Laptop', category: 'Electronics', price: 999 },\n { id: 2, name: 'Book', category: 'Education', price: 29 }\n ]\n\n const { getByLabelText, getByText } = render(\n <ProductList products={mockProducts} />\n )\n\n // Initially shows all products\n await expect.element(getByText('Laptop')).toBeInTheDocument()\n await expect.element(getByText('Book')).toBeInTheDocument()\n\n // Filter by category\n await userEvent.selectOptions(\n getByLabelText(/category/i),\n 'Electronics'\n )\n\n // Only electronics should remain\n await expect.element(getByText('Laptop')).toBeInTheDocument()\n await expect.element(queryByText('Book')).not.toBeInTheDocument()\n})\n```\n\nExample:\n```text\n// For Solid.js components\nimport { render } from '@testing-library/solid'\nimport { page } from 'vitest/browser'\n\ntest('Solid component handles user interaction', async () => {\n // Use Testing Library to render the component\n const { baseElement, getByRole } = render(() =>\n <Counter initialValue={0} />\n )\n\n // Bridge to Vitest's browser mode for interactions and assertions\n const screen = page.elementLocator(baseElement)\n\n // Use Vitest's page queries for finding elements\n const incrementButton = screen.getByRole('button', { name: /increment/i })\n\n // Use Vitest's assertions and interactions\n await expect.element(screen.getByText('Count: 0')).toBeInTheDocument()\n\n // Trigger user interaction using Vitest's page API\n await incrementButton.click()\n\n await expect.element(screen.getByText('Count: 1')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\n// Good: Test actual user interactions\nawait page.getByRole('button', { name: /submit/i }).click()\nawait page.getByLabelText(/email/i).fill('user@example.com')\n\n// Avoid: Testing implementation details\n// component.setState({ email: 'user@example.com' })\n```\n\nExample:\n```text\n// Test keyboard navigation\nawait userEvent.keyboard('{Tab}')\nawait expect.element(document.activeElement).toHaveFocus()\n\n// Test ARIA attributes\nawait expect.element(modal).toHaveAttribute('aria-modal', 'true')\n```\n\nExample:\n```text\n// For API requests, we recommend using MSW (Mock Service Worker)\n// See: https://vitest.dev/guide/mocking/requests\n// This provides more realistic request/response mocking\n\n// For module mocking, use the import() syntax\nvi.mock(import('../components/UserCard'), () => ({\n default: vi.fn(() => <div>Mocked UserCard</div>)\n}))\n```\n\nExample:\n```text\n// Good: Describes user-facing behavior\ntest('shows error message when email format is invalid')\ntest('disables submit button while form is submitting')\n\n// Avoid: Implementation-focused descriptions\ntest('calls validateEmail function')\ntest('sets isSubmitting state to true')\n```\n\nExample:\n```text\n// Testing stateful components and state transitions\ntest('ShoppingCart manages items correctly', async () => {\n const { getByText, getByTestId } = render(<ShoppingCart />)\n\n // Initially empty\n await expect.element(getByText('Your cart is empty')).toBeInTheDocument()\n\n // Add item\n await page.getByRole('button', { name: /add laptop/i }).click()\n\n // Verify state change\n await expect.element(getByText('1 item')).toBeInTheDocument()\n await expect.element(getByText('Laptop - $999')).toBeInTheDocument()\n\n // Test quantity updates\n await page.getByRole('button', { name: /increase quantity/i }).click()\n await expect.element(getByText('2 items')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\n// Option 1: Recommended - Use MSW (Mock Service Worker) for API mocking\nimport { http, HttpResponse } from 'msw'\nimport { setupWorker } from 'msw/browser'\n\n// Set up MSW worker with API handlers\nconst worker = setupWorker(\n http.get('/api/users/:id', ({ params }) => {\n // Describe the happy path\n return HttpResponse.json({ id: params.id, name: 'John Doe', email: 'john@example.com' })\n })\n)\n\n// Start the worker before all tests\nbeforeAll(() => worker.start())\nafterEach(() => worker.resetHandlers())\nafterAll(() => worker.stop())\n\ntest('UserProfile handles loading, success, and error states', async () => {\n // Test success state\n const { getByText } = render(<UserProfile userId=\"123\" />)\n // expect.element auto-retries until elements are found\n await expect.element(getByText('John Doe')).toBeInTheDocument()\n await expect.element(getByText('john@example.com')).toBeInTheDocument()\n\n // Test error state by overriding the handler for this test\n worker.use(\n http.get('/api/users/:id', () => {\n return HttpResponse.json({ error: 'User not found' }, { status: 404 })\n })\n )\n\n const { getByText: getErrorText } = render(<UserProfile userId=\"999\" />)\n await expect.element(getErrorText('Error: User not found')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\n// Test parent-child component interaction\ntest('parent and child components communicate correctly', async () => {\n const mockOnSelectionChange = vi.fn()\n\n const { getByText } = render(\n <ProductCatalog onSelectionChange={mockOnSelectionChange}>\n <ProductFilter />\n <ProductGrid />\n </ProductCatalog>\n )\n\n // Interact with child component\n await page.getByRole('checkbox', { name: /electronics/i }).click()\n\n // Verify parent receives the communication\n expect(mockOnSelectionChange).toHaveBeenCalledWith({\n category: 'electronics',\n filters: ['electronics']\n })\n\n // Verify other child component updates (expect.element auto-retries)\n await expect.element(getByText('Showing Electronics products')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\ntest('ContactForm handles complex validation scenarios', async () => {\n const mockSubmit = vi.fn()\n const { getByLabelText, getByText } = render(\n <ContactForm onSubmit={mockSubmit} />\n )\n\n const nameInput = page.getByLabelText(/full name/i)\n const emailInput = page.getByLabelText(/email/i)\n const messageInput = page.getByLabelText(/message/i)\n const submitButton = page.getByRole('button', { name: /send message/i })\n\n // Test validation triggers\n await submitButton.click()\n\n await expect.element(getByText('Name is required')).toBeInTheDocument()\n await expect.element(getByText('Email is required')).toBeInTheDocument()\n await expect.element(getByText('Message is required')).toBeInTheDocument()\n\n // Test partial validation\n await nameInput.fill('John Doe')\n await submitButton.click()\n\n await expect.element(getByText('Name is required')).not.toBeInTheDocument()\n await expect.element(getByText('Email is required')).toBeInTheDocument()\n\n // Test email format validation\n await emailInput.fill('invalid-email')\n await submitButton.click()\n\n await expect.element(getByText('Please enter a valid email')).toBeInTheDocument()\n\n // Test successful submission\n await emailInput.fill('john@example.com')\n await messageInput.fill('Hello, this is a test message.')\n await submitButton.click()\n\n expect(mockSubmit).toHaveBeenCalledWith({\n name: 'John Doe',\n email: 'john@example.com',\n message: 'Hello, this is a test message.'\n })\n})\n```\n\nExample:\n```text\n// Test how components handle and recover from errors\nfunction ThrowError({ shouldThrow }: { shouldThrow: boolean }) {\n if (shouldThrow) {\n throw new Error('Component error!')\n }\n return <div>Component working fine</div>\n}\n\ntest('ErrorBoundary catches and displays errors gracefully', async () => {\n const { getByText, rerender } = render(\n <ErrorBoundary fallback={<div>Something went wrong</div>}>\n <ThrowError shouldThrow={false} />\n </ErrorBoundary>\n )\n\n // Initially working\n await expect.element(getByText('Component working fine')).toBeInTheDocument()\n\n // Trigger error\n rerender(\n <ErrorBoundary fallback={<div>Something went wrong</div>}>\n <ThrowError shouldThrow={true} />\n </ErrorBoundary>\n )\n\n // Error boundary should catch it\n await expect.element(getByText('Something went wrong')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\ntest('Modal component is accessible', async () => {\n const { getByRole, getByLabelText } = render(\n <Modal isOpen={true} title=\"Settings\">\n <SettingsForm />\n </Modal>\n )\n\n // Test focus management - modal should receive focus when opened\n // This is crucial for screen reader users to know a modal opened\n const modal = getByRole('dialog')\n await expect.element(modal).toHaveFocus()\n\n // Test ARIA attributes - these provide semantic information to screen readers\n await expect.element(modal).toHaveAttribute('aria-labelledby') // Links to title element\n await expect.element(modal).toHaveAttribute('aria-modal', 'true') // Indicates modal behavior\n\n // Test keyboard navigation - Escape key should close modal\n // This is required by ARIA authoring practices\n await userEvent.keyboard('{Escape}')\n // expect.element auto-retries until modal is removed\n await expect.element(modal).not.toBeInTheDocument()\n\n // Test focus trap - tab navigation should cycle within modal\n // This prevents users from tabbing to content behind the modal\n const firstInput = getByLabelText(/username/i)\n const lastButton = getByRole('button', { name: /save/i })\n\n // Use click to focus on the first input, then test tab navigation\n await firstInput.click()\n await userEvent.keyboard('{Shift>}{Tab}{/Shift}') // Shift+Tab goes backwards\n await expect.element(lastButton).toHaveFocus() // Should wrap to last element\n})\n```\n\nExample:\n```text\ntest('debug form validation', async () => {\n render(<ContactForm />)\n\n const submitButton = page.getByRole('button', { name: /submit/i })\n await submitButton.click()\n\n // Debug: Check if element exists with different query\n const errorElement = page.getByText('Email is required')\n console.log('Error element found:', errorElement.length)\n\n await expect.element(errorElement).toBeInTheDocument()\n})\n```\n\nExample:\n```text\n// Debug why elements can't be found\nconst button = page.getByRole('button', { name: /submit/i })\nconsole.log('Button count:', button.length) // Should be 1\n\n// Try alternative queries if the first one fails\nif (button.length === 0) {\n console.log('All buttons:', page.getByRole('button').length)\n console.log('By test ID:', page.getByTestId('submit-btn').length)\n}\n```\n\nExample:\n```text\n// If getByRole fails, check what roles/names are available\nconst buttons = page.getByRole('button').all()\nfor (const button of buttons) {\n // Use element() to get the DOM element and access native properties\n const element = button.element()\n const accessibleName = element.getAttribute('aria-label') || element.textContent\n console.log(`Button: \"${accessibleName}\"`)\n}\n```\n\nExample:\n```text\n// Multiple ways to find the same element using .or for auto-retrying\nconst submitButton = page.getByRole('button', { name: /submit/i }) // By accessible name\n .or(page.getByTestId('submit-button')) // By test ID\n .or(page.getByText('Submit')) // By exact text\n// Note: Vitest doesn't have page.locator(), use specific getBy* methods instead\n```\n\nExample:\n```text\ntest('debug element queries', async () => {\n render(<LoginForm />)\n\n // Check if element is visible and enabled\n const emailInput = page.getByLabelText(/email/i)\n await expect.element(emailInput).toBeVisible() // Will show if element is visible and print DOM if not\n})\n```\n\nExample:\n```text\ntest('debug async component behavior', async () => {\n render(<AsyncUserProfile userId=\"123\" />)\n\n // expect.element will automatically retry and show helpful error messages\n await expect.element(page.getByText('John Doe')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\n// Before (Jest)\nimport { render, screen } from '@testing-library/react'\n\n// After (Vitest)\nimport { render } from 'vitest-browser-react'\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.916Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":21,"totalLines":415,"estimatedTokens":3197}}12{"id":"doc-mocking_the_file_system_vitest-c3a8bbe4","source":"documentation","title":"Mocking the File System | Vitest","url":"https://vitest.dev/guide/mocking/file-system","text":"Example:\n```text\n// we can also use `import`, but then\n// every export should be explicitly defined\n\nconst { fs } = require('memfs')\nmodule.exports = fs\n```\n\nExample:\n```text\n// we can also use `import`, but then\n// every export should be explicitly defined\n\nconst { fs } = require('memfs')\nmodule.exports = fs.promises\n```\n\nExample:\n```text\nimport { readFileSync } from 'node:fs'\n\nexport function readHelloWorld(path) {\n return readFileSync(path, 'utf-8')\n}\n```\n\nExample:\n```text\nimport { beforeEach, expect, it, vi } from 'vitest'\nimport { fs, vol } from 'memfs'\nimport { readHelloWorld } from './read-hello-world.js'\n\n// tell vitest to use fs mock from __mocks__ folder\n// this can be done in a setup file if fs should always be mocked\nvi.mock('node:fs')\nvi.mock('node:fs/promises')\n\nbeforeEach(() => {\n // reset the state of in-memory fs\n vol.reset()\n})\n\nit('should return correct text', () => {\n const path = '/hello-world.txt'\n fs.writeFileSync(path, 'hello world')\n\n const text = readHelloWorld(path)\n expect(text).toBe('hello world')\n})\n\nit('can return a value multiple times', () => {\n // you can use vol.fromJSON to define several files\n vol.fromJSON(\n {\n './dir1/hw.txt': 'hello dir1',\n './dir2/hw.txt': 'hello dir2',\n },\n // default cwd\n '/tmp',\n )\n\n expect(readHelloWorld('/tmp/dir1/hw.txt')).toBe('hello dir1')\n expect(readHelloWorld('/tmp/dir2/hw.txt')).toBe('hello dir2')\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.916Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":68,"estimatedTokens":361}}13{"id":"doc-mocking_guide_vitest-0d04dc7c","source":"documentation","title":"Mocking | Guide | Vitest","url":"https://vitest.dev/guide/mocking","text":"Example:\n```text\nexport const getter = 'variable'\n```\n\nExample:\n```text\nimport * as exports from './example.js'\n\nvi.spyOn(exports, 'getter', 'get').mockReturnValue('mocked')\n```\n\nExample:\n```text\nexport function method() {}\n```\n\nExample:\n```text\nimport { method } from './example.js'\n\nvi.mock('./example.js', () => ({\n method: vi.fn()\n}))\n```\n\nExample:\n```text\nimport * as exports from './example.js'\n\nvi.spyOn(exports, 'method').mockImplementation(() => {})\n```\n\nExample:\n```text\nexport class SomeClass {}\n```\n\nExample:\n```text\nimport { SomeClass } from './example.js'\n\nvi.mock(import('./example.js'), () => {\n const SomeClass = vi.fn(class FakeClass {\n someMethod = vi.fn()\n })\n return { SomeClass }\n})\n```\n\nExample:\n```text\nimport * as mod from './example.js'\n\nvi.spyOn(mod, 'SomeClass').mockImplementation(class FakeClass {\n someMethod = vi.fn()\n})\n```\n\nExample:\n```text\nexport function useObject() {\n return { method: () => true }\n}\n```\n\nExample:\n```text\nimport { useObject } from './example.js'\n\nconst obj = useObject()\nobj.method()\n```\n\nExample:\n```text\nimport { useObject } from './example.js'\n\nvi.mock(import('./example.js'), () => {\n let _cache\n const useObject = () => {\n if (!_cache) {\n _cache = {\n method: vi.fn(),\n }\n }\n // now every time that useObject() is called it will\n // return the same object reference\n return _cache\n }\n return { useObject }\n})\n\nconst obj = useObject()\n// obj.method was called inside some-path\nexpect(obj.method).toHaveBeenCalled()\n```\n\nExample:\n```text\nimport { mocked, original } from './some-path.js'\n\nvi.mock(import('./some-path.js'), async (importOriginal) => {\n const mod = await importOriginal()\n return {\n ...mod,\n mocked: vi.fn()\n }\n})\noriginal() // has original behaviour\nmocked() // is a spy function\n```\n\nExample:\n```text\nconst mockDate = new Date(2022, 0, 1)\nvi.setSystemTime(mockDate)\nconst now = new Date()\nexpect(now.valueOf()).toBe(mockDate.valueOf())\n// reset mocked time\nvi.useRealTimers()\n```\n\nExample:\n```text\nvi.stubGlobal('__VERSION__', '1.0.0')\nexpect(__VERSION__).toBe('1.0.0')\n```\n\nExample:\n```text\nimport { beforeEach, expect, it } from 'vitest'\n\n// you can reset it in beforeEach hook manually\nconst originalViteEnv = import.meta.env.VITE_ENV\n\nbeforeEach(() => {\n import.meta.env.VITE_ENV = originalViteEnv\n})\n\nit('changes value', () => {\n import.meta.env.VITE_ENV = 'staging'\n expect(import.meta.env.VITE_ENV).toBe('staging')\n})\n```\n\nExample:\n```text\nimport { expect, it, vi } from 'vitest'\n\n// before running tests \"VITE_ENV\" is \"test\"\nimport.meta.env.VITE_ENV === 'test'\n\nit('changes value', () => {\n vi.stubEnv('VITE_ENV', 'staging')\n expect(import.meta.env.VITE_ENV).toBe('staging')\n})\n\nit('the value is restored before running an other test', () => {\n expect(import.meta.env.VITE_ENV).toBe('test')\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n unstubEnvs: true,\n },\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.917Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":173,"estimatedTokens":737}}14{"id":"doc-visual_regression_testing_vitest-b66df845","source":"documentation","title":"Visual Regression Testing | Vitest","url":"https://vitest.dev/guide/browser/visual-regression-testing","text":"Example:\n```text\nimport { expect, test } from 'vitest'\nimport { page } from 'vitest/browser'\n\ntest('hero section looks correct', async () => {\n // ...the rest of the test\n\n // capture and compare screenshot\n await expect(page.getByTestId('hero')).toMatchScreenshot('hero-section')\n})\n```\n\nExample:\n```text\nexpect(element).toMatchScreenshot()\n\nNo existing reference screenshot found; a new one was created. Review it before running tests again.\n\nReference screenshot:\n tests/__screenshots__/hero.test.ts/hero-section-chromium-darwin.png\n```\n\nExample:\n```text\n.\n├── __screenshots__\n│ └── test-file.test.ts\n│ ├── test-name-chromium-darwin.png\n│ ├── test-name-firefox-linux.png\n│ └── test-name-webkit-win32.png\n└── test-file.test.ts\n```\n\nExample:\n```text\n$ vitest --update\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n browser: {\n expect: {\n toMatchScreenshot: {\n comparatorName: 'pixelmatch',\n comparatorOptions: {\n // 0-1, how different can colors be?\n threshold: 0.2,\n // 1% of pixels can differ\n allowedMismatchedPixelRatio: 0.01,\n },\n },\n },\n },\n },\n})\n```\n\nExample:\n```text\nawait expect(element).toMatchScreenshot('button-hover', {\n comparatorName: 'pixelmatch',\n comparatorOptions: {\n // more lax comparison for text-heavy elements\n allowedMismatchedPixelRatio: 0.1,\n },\n})\n```\n\nExample:\n```text\n// ❌ Captures entire page; prone to unrelated changes\nawait expect(page).toMatchScreenshot()\n\n// ✅ Captures only the component under test\nawait expect(page.getByTestId('product-card')).toMatchScreenshot()\n```\n\nExample:\n```text\nawait expect(page.getByTestId('profile')).toMatchScreenshot({\n screenshotOptions: {\n mask: [page.getByTestId('last-seen')],\n },\n})\n```\n\nExample:\n```text\n*, *::before, *::after {\n animation-duration: 0s !important;\n animation-delay: 0s !important;\n transition-duration: 0s !important;\n transition-delay: 0s !important;\n}\n```\n\nExample:\n```text\nawait page.viewport(1280, 720)\n```\n\nExample:\n```text\nimport { playwright } from '@vitest/browser-playwright'\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n instances: [\n {\n browser: 'chromium',\n viewport: { width: 1280, height: 720 },\n },\n ],\n },\n },\n})\n```\n\nExample:\n```text\nexpect(element).toMatchScreenshot()\n\nScreenshot does not match the stored reference.\n245 pixels (ratio 0.03) differ.\n\nReference screenshot:\n tests/__screenshots__/button.test.ts/button-chromium-darwin.png\n\nActual screenshot:\n tests/.vitest-attachments/button.test.ts/button-chromium-darwin-actual.png\n\nDiff image:\n tests/.vitest-attachments/button.test.ts/button-chromium-darwin-diff.png\n```\n\nExample:\n```text\n// wait for fonts to load\nawait document.fonts.ready\n\n// continue with your tests\n```\n\nExample:\n```text\nawait expect(page.getByTestId('article-summary')).toMatchScreenshot({\n comparatorName: 'pixelmatch',\n comparatorOptions: {\n // 10% of the pixels are allowed to change\n allowedMismatchedPixelRatio: 0.1,\n },\n})\n```\n\nExample:\n```text\n{\n \"scripts\": {\n \"test:unit\": \"vitest --exclude tests/visual/*.test.ts\",\n \"test:visual\": \"vitest tests/visual/*.test.ts\"\n }\n}\n```\n\nExample:\n```text\n# ...the rest of the workflow\n- name: Install Playwright Browsers\n run: npx --no playwright install --with-deps --only-shell\n```\n\nExample:\n```text\n# ...the rest of the workflow\n# ...browser setup\n- name: Visual Regression Testing\n run: npm run test:visual\n```\n\nExample:\n```text\nname: Update Visual Regression Screenshots\n\non:\n workflow_dispatch: # manual trigger only\n\nenv:\n AUTHOR_NAME: 'github-actions[bot]'\n AUTHOR_EMAIL: '41898282+github-actions[bot]@users.noreply.github.com'\n COMMIT_MESSAGE: |\n test: update visual regression screenshots\n\n Co-authored-by: ${{ github.actor }} <${{ github.actor_id }}+${{ github.actor }}@users.noreply.github.com>\n\njobs:\n update-screenshots:\n runs-on: ubuntu-24.04\n\n # safety first: don't run on main\n if: github.ref_name != github.event.repository.default_branch\n\n # one at a time per branch\n concurrency:\n group: visual-regression-screenshots@${{ github.ref_name }}\n cancel-in-progress: true\n\n permissions:\n contents: write # needs to push changes\n\n steps:\n - name: Checkout selected branch\n uses: actions/checkout@v4\n with:\n ref: ${{ github.ref_name }}\n # use PAT if triggering other workflows\n # token: ${{ secrets.GITHUB_TOKEN }}\n\n - name: Configure Git\n run: |\n git config --global user.name \"${{ env.AUTHOR_NAME }}\"\n git config --global user.email \"${{ env.AUTHOR_EMAIL }}\"\n\n # your setup steps here (node, pnpm, whatever)\n - name: Setup Node.js\n uses: actions/setup-node@v4\n with:\n node-version: 24\n\n - name: Install dependencies\n run: npm ci\n\n - name: Install Playwright Browsers\n run: npx --no playwright install --with-deps --only-shell\n\n # the magic happens below 🪄\n - name: Update Visual Regression Screenshots\n run: npm run test:visual --update\n\n # check what changed\n - name: Check for changes\n id: check_changes\n run: |\n CHANGED_FILES=$(git status --porcelain | awk '{print $2}')\n if [ \"${CHANGED_FILES:+x}\" ]; then\n echo \"changes=true\" >> $GITHUB_OUTPUT\n echo \"Changes detected\"\n\n # save the list for the summary\n echo \"changed_files<<EOF\" >> $GITHUB_OUTPUT\n echo \"$CHANGED_FILES\" >> $GITHUB_OUTPUT\n echo \"EOF\" >> $GITHUB_OUTPUT\n echo \"changed_count=$(echo \"$CHANGED_FILES\" | wc -l)\" >> $GITHUB_OUTPUT\n else\n echo \"changes=false\" >> $GITHUB_OUTPUT\n echo \"No changes detected\"\n fi\n\n # commit if there are changes\n - name: Commit changes\n if: steps.check_changes.outputs.changes == 'true'\n run: |\n git add -A\n git commit -m \"${{ env.COMMIT_MESSAGE }}\"\n\n - name: Push changes\n if: steps.check_changes.outputs.changes == 'true'\n run: git push origin ${{ github.ref_name }}\n\n # pretty summary for humans\n - name: Summary\n run: |\n if [[ \"${{ steps.check_changes.outputs.changes }}\" == \"true\" ]]; then\n echo \"### 📸 Visual Regression Screenshots Updated\" >> $GITHUB_STEP_SUMMARY\n echo \"\" >> $GITHUB_STEP_SUMMARY\n echo \"Successfully updated **${{ steps.check_changes.outputs.changed_count }}** screenshot(s) on \\`${{ github.ref_name }}\\`\" >> $GITHUB_STEP_SUMMARY\n echo \"\" >> $GITHUB_STEP_SUMMARY\n echo \"#### Changed Files:\" >> $GITHUB_STEP_SUMMARY\n echo \"\\`\\`\\`\" >> $GITHUB_STEP_SUMMARY\n echo \"${{ steps.check_changes.outputs.changed_files }}\" >> $GITHUB_STEP_SUMMARY\n echo \"\\`\\`\\`\" >> $GITHUB_STEP_SUMMARY\n echo \"\" >> $GITHUB_STEP_SUMMARY\n echo \"✅ The updated screenshots have been committed and pushed. Your visual regression baseline is now up to date!\" >> $GITHUB_STEP_SUMMARY\n else\n echo \"### ℹ️ No Screenshot Updates Required\" >> $GITHUB_STEP_SUMMARY\n echo \"\" >> $GITHUB_STEP_SUMMARY\n echo \"The visual regression test command ran successfully but no screenshots needed updating.\" >> $GITHUB_STEP_SUMMARY\n echo \"\" >> $GITHUB_STEP_SUMMARY\n echo \"All screenshots are already up to date! 🎉\" >> $GITHUB_STEP_SUMMARY\n fi\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.918Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":18,"totalLines":301,"estimatedTokens":1933}}15{"id":"doc-features_guide_vitest-51b3f9ea","source":"documentation","title":"Features | Guide | Vitest","url":"https://vitest.dev/guide/features","text":"Example:\n```text\n$ vitest\n```\n\nExample:\n```text\nimport { describe, it } from 'vitest'\n\n// The two tests marked with concurrent will be started in parallel\ndescribe('suite', () => {\n it('serial test', async () => { /* ... */ })\n it.concurrent('concurrent test 1', async ({ expect }) => { /* ... */ })\n it.concurrent('concurrent test 2', async ({ expect }) => { /* ... */ })\n})\n```\n\nExample:\n```text\nimport { describe, it } from 'vitest'\n\n// All tests within this suite will be started in parallel\ndescribe.concurrent('suite', () => {\n it('concurrent test 1', async ({ expect }) => { /* ... */ })\n it('concurrent test 2', async ({ expect }) => { /* ... */ })\n it.concurrent('concurrent test 3', async ({ expect }) => { /* ... */ })\n})\n```\n\nExample:\n```text\nimport { expect, it } from 'vitest'\n\nit('renders correctly', () => {\n const result = render()\n expect(result).toMatchSnapshot()\n})\n```\n\nExample:\n```text\nimport { expect, vi } from 'vitest'\n\nconst fn = vi.fn()\n\nfn('hello', 1)\n\nexpect(vi.isMockFunction(fn)).toBe(true)\nexpect(fn.mock.calls[0]).toEqual(['hello', 1])\n\nfn.mockImplementation((arg: string) => arg)\n\nfn('world', 2)\n\nexpect(fn.mock.results[1].value).toBe('world')\n```\n\nExample:\n```text\n$ npm i -D happy-dom\n```\n\nExample:\n```text\n$ npm i -D jsdom\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n environment: 'happy-dom', // or 'jsdom', 'node'\n },\n})\n```\n\nExample:\n```text\n{\n \"scripts\": {\n \"test\": \"vitest\",\n \"coverage\": \"vitest run --coverage\"\n }\n}\n```\n\nExample:\n```text\n// the implementation\nexport function add(...args: number[]): number {\n return args.reduce((a, b) => a + b, 0)\n}\n\n// in-source test suites\nif (import.meta.vitest) {\n const { it, expect } = import.meta.vitest\n it('add', () => {\n expect(add()).toBe(0)\n expect(add(1)).toBe(1)\n expect(add(1, 2, 3)).toBe(6)\n })\n}\n```\n\nExample:\n```text\nimport { bench, describe } from 'vitest'\n\ndescribe('sort', () => {\n bench('normal', () => {\n const x = [1, 5, 4, 2, 3]\n x.sort((a, b) => {\n return a - b\n })\n })\n\n bench('reverse', () => {\n const x = [1, 5, 4, 2, 3]\n x.reverse().sort((a, b) => {\n return a - b\n })\n })\n})\n```\n\nExample:\n```text\nimport { assertType, expectTypeOf, test } from 'vitest'\nimport { mount } from './mount.js'\n\ntest('my types work properly', () => {\n expectTypeOf(mount).toBeFunction()\n expectTypeOf(mount).parameter(0).toExtend<{ name: string }>()\n\n // @ts-expect-error name is a string\n assertType(mount({ name: 42 }))\n})\n```\n\nExample:\n```text\nvitest --shard=1/2 --reporter=blob --coverage\nvitest --shard=2/2 --reporter=blob --coverage\nvitest --merge-reports --reporter=junit --coverage\n```\n\nExample:\n```text\nimport { loadEnv } from 'vite'\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig(({ mode }) => ({\n test: {\n // mode defines what \".env.{mode}\" file to choose if exists\n env: loadEnv(mode, process.cwd(), ''),\n },\n}))\n```\n\nExample:\n```text\n// in Node.js\nprocess.on('unhandledRejection', () => {\n // your own handler\n})\n\nprocess.on('uncaughtException', () => {\n // your own handler\n})\n```\n\nExample:\n```text\n// in the browser\nwindow.addEventListener('error', () => {\n // your own handler\n})\n\nwindow.addEventListener('unhandledrejection', () => {\n // your own handler\n})\n```\n\nExample:\n```text\ntest('my function throws uncaught error', async ({ onTestFinished }) => {\n const unhandledRejectionListener = vi.fn()\n process.on('unhandledRejection', unhandledRejectionListener)\n onTestFinished(() => {\n process.off('unhandledRejection', unhandledRejectionListener)\n })\n\n callMyFunctionThatRejectsError()\n\n await expect.poll(unhandledRejectionListener).toHaveBeenCalled()\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.918Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":17,"totalLines":201,"estimatedTokens":939}}16{"id":"doc-mocking_globals_vitest-e44dae65","source":"documentation","title":"Mocking Globals | Vitest","url":"https://vitest.dev/guide/mocking/globals","text":"Example:\n```text\nimport { vi } from 'vitest'\n\nconst IntersectionObserverMock = vi.fn(class {\n disconnect = vi.fn()\n observe = vi.fn()\n takeRecords = vi.fn()\n unobserve = vi.fn()\n})\n\nvi.stubGlobal('IntersectionObserver', IntersectionObserverMock)\n\n// now you can access it as `IntersectionObserver` or `window.IntersectionObserver`\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.918Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":17,"estimatedTokens":88}}17{"id":"doc-browser_mode_guide_vitest-801fc05f","source":"documentation","title":"Browser Mode | Guide | Vitest","url":"https://vitest.dev/guide/browser/","text":"Example:\n```text\nnpx vitest init browser\n```\n\nExample:\n```text\nyarn exec vitest init browser\n```\n\nExample:\n```text\npnpx vitest init browser\n```\n\nExample:\n```text\nbunx vitest init browser\n```\n\nExample:\n```text\nnpm install -D vitest @vitest/browser-preview\n```\n\nExample:\n```text\nyarn add -D vitest @vitest/browser-preview\n```\n\nExample:\n```text\npnpm add -D vitest @vitest/browser-preview\n```\n\nExample:\n```text\nbun add -D vitest @vitest/browser-preview\n```\n\nExample:\n```text\nnpm install -D vitest @vitest/browser-playwright\n```\n\nExample:\n```text\nyarn add -D vitest @vitest/browser-playwright\n```\n\nExample:\n```text\npnpm add -D vitest @vitest/browser-playwright\n```\n\nExample:\n```text\nbun add -D vitest @vitest/browser-playwright\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n browser: {\n provider: playwright(),\n enabled: true,\n // at least one instance is required\n instances: [\n { browser: 'chromium' },\n ],\n },\n }\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport react from '@vitejs/plugin-react'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n plugins: [react()],\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n instances: [\n { browser: 'chromium' },\n ],\n }\n }\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\nimport vue from '@vitejs/plugin-vue'\n\nexport default defineConfig({\n plugins: [vue()],\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n instances: [\n { browser: 'chromium' },\n ],\n }\n }\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { svelte } from '@sveltejs/vite-plugin-svelte'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n plugins: [svelte()],\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n instances: [\n { browser: 'chromium' },\n ],\n }\n }\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport solidPlugin from 'vite-plugin-solid'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n plugins: [solidPlugin()],\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n instances: [\n { browser: 'chromium' },\n ],\n }\n }\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport marko from '@marko/vite'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n plugins: [marko()],\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n instances: [\n { browser: 'chromium' },\n ],\n }\n }\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { qwikVite } from '@builder.io/qwik/optimizer'\nimport { playwright } from '@vitest/browser-playwright'\n\n// optional, run the tests in SSR mode\nimport { testSSR } from 'vitest-browser-qwik/ssr-plugin'\n\nexport default defineConfig({\n plugins: [testSSR(), qwikVite()],\n test: {\n browser: {\n enabled: true,\n provider: playwright(),\n instances: [{ browser: 'chromium' }]\n },\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n test: {\n // an example of file based convention,\n // you don't have to follow it\n include: [\n 'tests/unit/**/*.{test,spec}.ts',\n 'tests/**/*.unit.{test,spec}.ts',\n ],\n name: 'unit',\n environment: 'node',\n },\n },\n {\n test: {\n // an example of file based convention,\n // you don't have to follow it\n include: [\n 'tests/browser/**/*.{test,spec}.ts',\n 'tests/**/*.browser.{test,spec}.ts',\n ],\n name: 'browser',\n browser: {\n enabled: true,\n provider: playwright(),\n instances: [\n { browser: 'chromium' },\n ],\n },\n },\n },\n ],\n },\n})\n```\n\nExample:\n```text\nnpx vitest --browser=chromium\n```\n\nExample:\n```text\nnpx vitest --browser.headless\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n browser: {\n provider: playwright(),\n enabled: true,\n headless: true,\n },\n }\n})\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\nimport { page } from 'vitest/browser'\nimport { render } from './my-render-function.js'\n\ntest('properly handles form inputs', async () => {\n render() // mount DOM elements\n\n // Asserts initial state.\n await expect.element(page.getByText('Hi, my name is Alice')).toBeInTheDocument()\n\n // Get the input DOM node by querying the associated label.\n const usernameInput = page.getByLabelText(/username/i)\n\n // Type the name into the input. This already validates that the input\n // is filled correctly, no need to check the value manually.\n await usernameInput.fill('Bob')\n\n await expect.element(page.getByText('Hi, my name is Bob')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\nimport { expect } from 'vitest'\nimport { page } from 'vitest/browser'\n// element is rendered correctly\nawait expect.element(page.getByText('Hello World')).toBeInTheDocument()\n```\n\nExample:\n```text\nimport { page, userEvent } from 'vitest/browser'\nawait userEvent.fill(page.getByLabelText(/username/i), 'Alice')\n// or just locator.fill\nawait page.getByLabelText(/username/i).fill('Alice')\n```\n\nExample:\n```text\nimport { render } from 'vitest-browser-vue'\nimport Component from './Component.vue'\n\ntest('properly handles v-model', async () => {\n const screen = render(Component)\n\n // Asserts initial state.\n await expect.element(screen.getByText('Hi, my name is Alice')).toBeInTheDocument()\n\n // Get the input DOM node by querying the associated label.\n const usernameInput = screen.getByLabelText(/username/i)\n\n // Type the name into the input. This already validates that the input\n // is filled correctly, no need to check the value manually.\n await usernameInput.fill('Bob')\n\n await expect.element(screen.getByText('Hi, my name is Bob')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\nimport { render } from 'vitest-browser-svelte'\nimport { expect, test } from 'vitest'\n\nimport Greeter from './greeter.svelte'\n\ntest('greeting appears on click', async () => {\n const screen = render(Greeter, { name: 'World' })\n\n const button = screen.getByRole('button')\n await button.click()\n const greeting = screen.getByText(/hello world/iu)\n\n await expect.element(greeting).toBeInTheDocument()\n})\n```\n\nExample:\n```text\nimport { render } from 'vitest-browser-react'\nimport Fetch from './fetch'\n\ntest('loads and displays greeting', async () => {\n // Render a React element into the DOM\n const screen = render(<Fetch url=\"/greeting\" />)\n\n await screen.getByText('Load Greeting').click()\n // wait before throwing an error if it cannot find an element\n const heading = screen.getByRole('heading')\n\n // assert that the alert message is correct\n await expect.element(heading).toHaveTextContent('hello there')\n await expect.element(screen.getByRole('button')).toBeDisabled()\n})\n```\n\nExample:\n```text\nimport { render } from 'vitest-browser-lit'\nimport { html } from 'lit'\nimport './greeter-button'\n\ntest('greeting appears on click', async () => {\n const screen = render(html`<greeter-button name=\"World\"></greeter-button>`)\n\n const button = screen.getByRole('button')\n await button.click()\n const greeting = screen.getByText(/hello world/iu)\n\n await expect.element(greeting).toBeInTheDocument()\n})\n```\n\nExample:\n```text\nimport { render } from 'vitest-browser-preact'\nimport { createElement } from 'preact'\nimport Greeting from '.Greeting'\n\ntest('greeting appears on click', async () => {\n const screen = render(<Greeting />)\n\n const button = screen.getByRole('button')\n await button.click()\n const greeting = screen.getByText(/hello world/iu)\n\n await expect.element(greeting).toBeInTheDocument()\n})\n```\n\nExample:\n```text\nimport { render } from 'vitest-browser-qwik'\nimport Greeting from './greeting'\n\ntest('greeting appears on click', async () => {\n // renderSSR and renderHook are also available\n const screen = render(<Greeting />)\n\n const button = screen.getByRole('button')\n await button.click()\n const greeting = screen.getByText(/hello world/iu)\n\n await expect.element(greeting).toBeInTheDocument()\n})\n```\n\nExample:\n```text\n// based on @testing-library/solid API\n// https://testing-library.com/docs/solid-testing-library/api\n\nimport { render } from '@testing-library/solid'\n\nit('uses params', async () => {\n const App = () => (\n <>\n <Route\n path=\"/ids/:id\"\n component={() => (\n <p>\n Id:\n {useParams()?.id}\n </p>\n )}\n />\n <Route path=\"/\" component={() => <p>Start</p>} />\n </>\n )\n const { baseElement } = render(() => <App />, { location: 'ids/1234' })\n const screen = page.elementLocator(baseElement)\n\n await expect.screen(screen.getByText('Id: 1234')).toBeInTheDocument()\n})\n```\n\nExample:\n```text\n// based on @testing-library/marko API\n// https://testing-library.com/docs/marko-testing-library/api\n\nimport { render, screen } from '@marko/testing-library'\nimport Greeting from './greeting.marko'\n\ntest('renders a message', async () => {\n const { baseElement } = await render(Greeting, { name: 'Marko' })\n const screen = page.elementLocator(baseElement)\n await expect.element(screen.getByText(/Marko/)).toBeInTheDocument()\n expect(container.firstChild).toMatchInlineSnapshot(`\n <h1>Hello, Marko!</h1>\n `)\n})\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\nimport * as module from './module.js'\n\nvi.spyOn(module, 'method') // ❌ throws an error\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\nimport * as module from './module.js'\n\nvi.mock('./module.js', { spy: true })\n\nvi.mocked(module.method).mockImplementation(() => {\n // ...\n})\n```\n\nExample:\n```text\nexport let MODE = 'test'\nexport function changeMode(newMode) {\n MODE = newMode\n}\n```\n\nExample:\n```text\nimport { expect } from 'vitest'\nimport { changeMode, MODE } from './module.js'\n\nchangeMode('production')\nexpect(MODE).toBe('production')\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.918Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":38,"totalLines":503,"estimatedTokens":2654}}18{"id":"doc-trace_view_vitest-b7c19d21","source":"documentation","title":"Trace View | Vitest","url":"https://vitest.dev/guide/browser/trace-view","text":"Example:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n browser: {\n provider: playwright(),\n trace: 'on',\n },\n },\n})\n```\n\nExample:\n```text\nvitest --browser.trace=on\n```\n\nExample:\n```text\nchromium-my-test-0-0.trace.zip\n^^^^^^^^ project name\n ^^^^^^ test name\n ^ repeat count\n ^ retry count\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n browser: {\n provider: playwright(),\n trace: {\n mode: 'on',\n // the path is relative to the root of the project\n tracesDir: './playwright-traces',\n },\n },\n },\n})\n```\n\nExample:\n```text\nimport { page } from 'vitest/browser'\n\ndocument.body.innerHTML = `\n <button type=\"button\">Sign in</button>\n`\n\nawait page.getByRole('button', { name: 'Sign in' }).mark('sign in button rendered')\n```\n\nExample:\n```text\nawait page.mark('sign in flow', async () => {\n await page.getByRole('textbox', { name: 'Email' }).fill('john@example.com')\n await page.getByRole('textbox', { name: 'Password' }).fill('secret')\n await page.getByRole('button', { name: 'Sign in' }).click()\n})\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\nimport { page } from 'vitest/browser'\n\nconst myRender = vi.defineHelper(async (content: string) => {\n document.body.innerHTML = content\n await page.elementLocator(document.body).mark('render helper')\n})\n\ntest('renders content', async () => {\n await myRender('<button>Hello</button>') // trace points to this line\n})\n```\n\nExample:\n```text\nnpx playwright show-trace \"path-to-trace-file\"\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.919Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":8,"totalLines":89,"estimatedTokens":444}}19{"id":"doc-mocking_requests_vitest-120ed0e7","source":"documentation","title":"Mocking Requests | Vitest","url":"https://vitest.dev/guide/mocking/requests","text":"Example:\n```text\nimport { afterAll, afterEach, beforeAll } from 'vitest'\nimport { setupServer } from 'msw/node'\nimport { http, HttpResponse } from 'msw'\n\nconst posts = [\n {\n userId: 1,\n id: 1,\n title: 'first post title',\n body: 'first post body',\n },\n // ...\n]\n\nexport const restHandlers = [\n http.get('https://rest-endpoint.example/path/to/posts', () => {\n return HttpResponse.json(posts)\n }),\n]\n\nconst server = setupServer(...restHandlers)\n\n// Start server before all tests\nbeforeAll(() => server.listen({ onUnhandledRequest: 'error' }))\n\n// Close server after all tests\nafterAll(() => server.close())\n\n// Reset handlers after each test for test isolation\nafterEach(() => server.resetHandlers())\n```\n\nExample:\n```text\nimport { afterAll, afterEach, beforeAll } from 'vitest'\nimport { setupServer } from 'msw/node'\nimport { graphql, HttpResponse } from 'msw'\n\nconst posts = [\n {\n userId: 1,\n id: 1,\n title: 'first post title',\n body: 'first post body',\n },\n // ...\n]\n\nconst graphqlHandlers = [\n graphql.query('ListPosts', () => {\n return HttpResponse.json({\n data: { posts },\n })\n }),\n]\n\nconst server = setupServer(...graphqlHandlers)\n\n// Start server before all tests\nbeforeAll(() => server.listen({ onUnhandledRequest: 'error' }))\n\n// Close server after all tests\nafterAll(() => server.close())\n\n// Reset handlers after each test for test isolation\nafterEach(() => server.resetHandlers())\n```\n\nExample:\n```text\nimport { afterAll, afterEach, beforeAll } from 'vitest'\nimport { setupServer } from 'msw/node'\nimport { ws } from 'msw'\n\nconst chat = ws.link('wss://chat.example.com')\n\nconst wsHandlers = [\n chat.addEventListener('connection', ({ client }) => {\n client.addEventListener('message', (event) => {\n console.log('Received message from client:', event.data)\n // Echo the received message back to the client\n client.send(`Server received: ${event.data}`)\n })\n }),\n]\n\nconst server = setupServer(...wsHandlers)\n\n// Start server before all tests\nbeforeAll(() => server.listen({ onUnhandledRequest: 'error' }))\n\n// Close server after all tests\nafterAll(() => server.close())\n\n// Reset handlers after each test for test isolation\nafterEach(() => server.resetHandlers())\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.919Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":101,"estimatedTokens":565}}20{"id":"doc-testing_in_practice_guide_vitest-faa931e2","source":"documentation","title":"Testing in Practice | Guide | Vitest","url":"https://vitest.dev/guide/learn/testing-in-practice","text":"Example:\n```text\nexport function formatPrice(amount, currency) {\n return new Intl.NumberFormat('en-US', {\n style: 'currency',\n currency,\n }).format(amount)\n}\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\nimport { formatPrice } from './formatPrice.js'\n\ntest('formats USD prices', () => {\n expect(formatPrice(10, 'USD')).toBe('$10.00')\n})\n\ntest('formats EUR prices', () => {\n expect(formatPrice(10, 'EUR')).toBe('€10.00')\n})\n\ntest('handles zero', () => {\n expect(formatPrice(0, 'USD')).toBe('$0.00')\n})\n\ntest('handles negative amounts', () => {\n expect(formatPrice(-5.5, 'USD')).toBe('-$5.50')\n})\n\ntest('rounds to two decimal places', () => {\n expect(formatPrice(10.999, 'USD')).toBe('$11.00')\n})\n```\n\nExample:\n```text\ntest('removes an item from the list', () => {\n // Set up\n const list = new ShoppingList()\n list.add('milk')\n list.add('bread')\n\n // Act\n list.remove('milk')\n\n // Check\n expect(list.getItems()).toEqual(['bread'])\n})\n```\n\nExample:\n```text\nexport function parseAge(input) {\n const age = Number(input)\n if (Number.isNaN(age) || age < 0 || age > 150) {\n throw new Error(`Invalid age: ${input}`)\n }\n return Math.floor(age)\n}\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\nimport { parseAge } from './parseAge.js'\n\ntest('parses a valid age', () => {\n expect(parseAge('25')).toBe(25)\n})\n\ntest('rounds down decimal ages', () => {\n expect(parseAge('25.9')).toBe(25)\n})\n\ntest('handles zero', () => {\n expect(parseAge('0')).toBe(0)\n})\n\ntest('handles the upper boundary', () => {\n expect(parseAge('150')).toBe(150)\n})\n\ntest('throws for negative numbers', () => {\n expect(() => parseAge('-1')).toThrow('Invalid age: -1')\n})\n\ntest('throws for numbers above 150', () => {\n expect(() => parseAge('151')).toThrow('Invalid age: 151')\n})\n\ntest('throws for non-numeric strings', () => {\n expect(() => parseAge('abc')).toThrow('Invalid age: abc')\n})\n\ntest('throws for empty string', () => {\n expect(() => parseAge('')).toThrow('Invalid age: ')\n})\n```\n\nExample:\n```text\ntest('handles leading spaces', () => {\n expect(parseAge(' 25')).toBe(25)\n})\n```\n\nExample:\n```text\nexport function parseAge(input) {\n const age = Number(input.trim())\n // ...\n}\n```\n\nExample:\n```text\nsrc/\n utils.js\n utils.test.js\n formatPrice.js\n formatPrice.test.js\n```\n\nExample:\n```text\ndescribe('formatPrice', () => {\n test('formats USD prices', () => { /* ... */ })\n test('handles zero', () => { /* ... */ })\n})\n\ndescribe('parseAmount', () => {\n test('parses valid amounts', () => { /* ... */ })\n test('throws for invalid input', () => { /* ... */ })\n})\n```\n\nExample:\n```text\nlet nextId = 1\n\nexport function createTodoList() {\n const items = []\n\n return {\n add(text) {\n if (!text.trim()) {\n throw new Error('Todo text cannot be empty')\n }\n const todo = { id: nextId++, text, completed: false }\n items.push(todo)\n return todo\n },\n\n remove(id) {\n const index = items.findIndex(item => item.id === id)\n if (index === -1) {\n throw new Error(`Todo with id ${id} not found`)\n }\n items.splice(index, 1)\n },\n\n toggle(id) {\n const todo = items.find(item => item.id === id)\n if (!todo) {\n throw new Error(`Todo with id ${id} not found`)\n }\n todo.completed = !todo.completed\n },\n\n getAll() {\n return items\n },\n\n getCompleted() {\n return items.filter(item => item.completed)\n },\n }\n}\n```\n\nExample:\n```text\nimport { describe, expect, test } from 'vitest'\nimport { createTodoList } from './todoList.js'\n\ndescribe('add', () => {\n test('adds a new todo', () => {\n const list = createTodoList()\n const todo = list.add('Buy groceries')\n\n expect(todo.text).toBe('Buy groceries')\n expect(todo.completed).toBe(false)\n expect(list.getAll()).toHaveLength(1)\n })\n\n test('assigns unique IDs to each todo', () => {\n const list = createTodoList()\n const first = list.add('First')\n const second = list.add('Second')\n\n expect(first.id).not.toBe(second.id)\n })\n\n test('throws when text is empty', () => {\n const list = createTodoList()\n expect(() => list.add('')).toThrow('Todo text cannot be empty')\n })\n\n test('throws when text is only whitespace', () => {\n const list = createTodoList()\n expect(() => list.add(' ')).toThrow('Todo text cannot be empty')\n })\n})\n\ndescribe('remove', () => {\n test('removes a todo by ID', () => {\n const list = createTodoList()\n const todo = list.add('Buy groceries')\n\n list.remove(todo.id)\n\n expect(list.getAll()).toHaveLength(0)\n })\n\n test('keeps other items when removing one', () => {\n const list = createTodoList()\n const first = list.add('First')\n list.add('Second')\n\n list.remove(first.id)\n\n expect(list.getAll()).toHaveLength(1)\n expect(list.getAll()[0].text).toBe('Second')\n })\n\n test('throws when ID does not exist', () => {\n const list = createTodoList()\n expect(() => list.remove(999)).toThrow('Todo with id 999 not found')\n })\n})\n\ndescribe('toggle', () => {\n test('marks a todo as completed', () => {\n const list = createTodoList()\n const todo = list.add('Buy groceries')\n\n list.toggle(todo.id)\n\n expect(list.getAll()[0].completed).toBe(true)\n })\n\n test('toggles back to incomplete', () => {\n const list = createTodoList()\n const todo = list.add('Buy groceries')\n\n list.toggle(todo.id)\n list.toggle(todo.id)\n\n expect(list.getAll()[0].completed).toBe(false)\n })\n\n test('throws when ID does not exist', () => {\n const list = createTodoList()\n expect(() => list.toggle(999)).toThrow('Todo with id 999 not found')\n })\n})\n\ndescribe('getCompleted', () => {\n test('returns only completed todos', () => {\n const list = createTodoList()\n const buy = list.add('Buy groceries')\n list.add('Clean house')\n list.toggle(buy.id)\n\n const completed = list.getCompleted()\n\n expect(completed).toHaveLength(1)\n expect(completed[0].text).toBe('Buy groceries')\n })\n\n test('returns empty array when nothing is completed', () => {\n const list = createTodoList()\n list.add('Buy groceries')\n\n expect(list.getCompleted()).toHaveLength(0)\n })\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.922Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":292,"estimatedTokens":1546}}21{"id":"doc-mocking_dates_vitest-545ced19","source":"documentation","title":"Mocking Dates | Vitest","url":"https://vitest.dev/guide/mocking/dates","text":"Example:\n```text\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nconst businessHours = [9, 17]\n\nfunction purchase() {\n const currentHour = new Date().getHours()\n const [open, close] = businessHours\n\n if (currentHour > open && currentHour < close) {\n return { message: 'Success' }\n }\n\n return { message: 'Error' }\n}\n\ndescribe('purchasing flow', () => {\n beforeEach(() => {\n // tell vitest we use mocked time\n vi.useFakeTimers()\n })\n\n afterEach(() => {\n // restoring date after each test run\n vi.useRealTimers()\n })\n\n it('allows purchases within business hours', () => {\n // set hour within business hours\n const date = new Date(2000, 1, 1, 13)\n vi.setSystemTime(date)\n\n // access Date.now() will result in the date set above\n expect(purchase()).toEqual({ message: 'Success' })\n })\n\n it('disallows purchases outside of business hours', () => {\n // set hour outside business hours\n const date = new Date(2000, 1, 1, 19)\n vi.setSystemTime(date)\n\n // access Date.now() will result in the date set above\n expect(purchase()).toEqual({ message: 'Error' })\n })\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.922Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":49,"estimatedTokens":289}}22{"id":"doc-test_environment_guide_vitest-b78b4171","source":"documentation","title":"Test Environment | Guide | Vitest","url":"https://vitest.dev/guide/environment","text":"Example:\n```text\n// @vitest-environment jsdom\n\nimport { expect, test } from 'vitest'\n\ntest('test', () => {\n expect(typeof window).not.toBe('undefined')\n})\n```\n\nExample:\n```text\nimport type { Environment } from 'vitest/runtime'\n\nexport default <Environment>{\n name: 'custom',\n viteEnvironment: 'ssr',\n // optional - only if you support \"vmForks\" or \"vmThreads\" pools\n async setupVM() {\n const vm = await import('node:vm')\n const context = vm.createContext()\n return {\n getVmContext() {\n return context\n },\n teardown() {\n // called after all tests with this env have been run\n }\n }\n },\n setup() {\n // custom setup\n return {\n teardown() {\n // called after all tests with this env have been run\n }\n }\n }\n}\n```\n\nExample:\n```text\nimport { builtinEnvironments, populateGlobal } from 'vitest/runtime'\n\nconsole.log(builtinEnvironments) // { jsdom, happy-dom, node, edge-runtime }\n```\n\nExample:\n```text\ninterface PopulateOptions {\n // should non-class functions be bind to the global namespace\n bindFunctions?: boolean\n}\n\ninterface PopulateResult {\n // a list of all keys that were copied, even if value doesn't exist on original object\n keys: Set<string>\n // a map of original object that might have been overridden with keys\n // you can return these values inside `teardown` function\n originals: Map<string | symbol, any>\n}\n\nexport function populateGlobal(global: any, original: any, options: PopulateOptions): PopulateResult\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.922Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":68,"estimatedTokens":381}}23{"id":"doc-mocking_functions_vitest-0e248596","source":"documentation","title":"Mocking Functions | Vitest","url":"https://vitest.dev/guide/mocking/functions","text":"Example:\n```text\nimport { afterEach, describe, expect, it, vi } from 'vitest'\n\nconst messages = {\n items: [\n { message: 'Simple test message', from: 'Testman' },\n // ...\n ],\n addItem(item) {\n messages.items.push(item)\n messages.callbacks.forEach(callback => callback(item))\n },\n onItem(callback) {\n messages.callbacks.push(callback)\n },\n getLatest, // can also be a `getter or setter if supported`\n}\n\nfunction getLatest(index = messages.items.length - 1) {\n return messages.items[index]\n}\n\nit('should get the latest message with a spy', () => {\n const spy = vi.spyOn(messages, 'getLatest')\n expect(spy.getMockName()).toEqual('getLatest')\n\n expect(messages.getLatest()).toEqual(\n messages.items[messages.items.length - 1],\n )\n\n expect(spy).toHaveBeenCalledTimes(1)\n\n spy.mockImplementationOnce(() => 'access-restricted')\n expect(messages.getLatest()).toEqual('access-restricted')\n\n expect(spy).toHaveBeenCalledTimes(2)\n})\n\nit('passing down the mock', () => {\n const callback = vi.fn()\n messages.onItem(callback)\n\n messages.addItem({ message: 'Another test message', from: 'Testman' })\n expect(callback).toHaveBeenCalledWith({\n message: 'Another test message',\n from: 'Testman',\n })\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.922Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":52,"estimatedTokens":312}}24{"id":"doc-test_tags_guide_vitest-148cbcf9","source":"documentation","title":"Test Tags | Guide | Vitest","url":"https://vitest.dev/guide/test-tags","text":"Example:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n tags: [\n {\n name: 'frontend',\n description: 'Tests written for frontend.',\n },\n {\n name: 'backend',\n description: 'Tests written for backend.',\n },\n {\n name: 'db',\n description: 'Tests for database queries.',\n timeout: 60_000,\n },\n {\n name: 'flaky',\n description: 'Flaky CI tests.',\n retry: process.env.CI ? 3 : 0,\n timeout: 30_000,\n priority: 1,\n },\n ],\n },\n})\n```\n\nExample:\n```text\ntest('flaky database test', { tags: ['flaky', 'db'] })\n// { timeout: 30_000, retry: 3 }\n```\n\nExample:\n```text\ntest('flaky database test', { tags: ['flaky', 'db'], timeout: 120_000 })\n// { timeout: 120_000, retry: 3 }\n```\n\nExample:\n```text\nimport 'vitest'\n\ndeclare module 'vitest' {\n interface TestTags {\n tags:\n | 'frontend'\n | 'backend'\n | 'db'\n | 'flaky'\n }\n}\n```\n\nExample:\n```text\nvitest --list-tags\n\nfrontend: Tests written for frontend.\nbackend: Tests written for backend.\ndb: Tests for database queries.\nflaky: Flaky CI tests.\n```\n\nExample:\n```text\n{\n \"tags\": [\n {\n \"name\": \"frontend\",\n \"description\": \"Tests written for frontend.\"\n },\n {\n \"name\": \"backend\",\n \"description\": \"Tests written for backend.\"\n },\n {\n \"name\": \"db\",\n \"description\": \"Tests for database queries.\",\n \"timeout\": 60000\n },\n {\n \"name\": \"flaky\",\n \"description\": \"Flaky CI tests.\",\n \"retry\": 0,\n \"timeout\": 30000,\n \"priority\": 1\n }\n ],\n \"projects\": []\n}\n```\n\nExample:\n```text\nimport { describe, test } from 'vitest'\n\ntest('renders homepage', { tags: ['frontend'] }, () => {\n // ...\n})\n\ndescribe('API endpoints', { tags: ['backend'] }, () => {\n test('returns user data', () => {\n // This test inherits the \"backend\" tag from the parent suite\n })\n\n test('validates input', { tags: ['validation'] }, () => {\n // This test has both \"backend\" (inherited) and \"validation\" tags\n })\n})\n```\n\nExample:\n```text\n/**\n * Auth tests\n * @module-tag admin/pages/dashboard\n * @module-tag acceptance\n */\n\ntest('dashboard renders items', () => {\n // ...\n})\n```\n\nExample:\n```text\ndescribe('forms', () => {\n /**\n * @module-tag frontend\n */\n test('renders a form', () => {\n // ...\n })\n\n /**\n * @module-tag db\n */\n test('db returns users', () => {\n // ...\n })\n})\n```\n\nExample:\n```text\ndescribe('forms', () => {\n test('renders a form', { tags: 'frontend' }, () => {\n // ...\n })\n\n test('db returns users', { tags: 'db' }, () => {\n // ...\n })\n})\n```\n\nExample:\n```text\nvitest --tags-filter=frontend\nvitest --tags-filter=\"frontend and backend\"\n```\n\nExample:\n```text\nimport { startVitest } from 'vitest/node'\n\nawait startVitest('test', [], {\n tagsFilter: ['frontend and backend'],\n})\n```\n\nExample:\n```text\nconst specification = vitest.getRootProject().createSpecification(\n '/path-to-file.js',\n {\n testTagsFilter: ['frontend and backend'],\n },\n)\n```\n\nExample:\n```text\nvitest --tags-filter=\"unit/*\"\n```\n\nExample:\n```text\nvitest --tags-filter=\"!slow and not flaky\"\n```\n\nExample:\n```text\n# Run only unit tests\nvitest --tags-filter=\"unit\"\n\n# Run tests that are both frontend AND fast\nvitest --tags-filter=\"frontend and fast\"\n\n# Run tests that are either unit OR e2e\nvitest --tags-filter=\"unit or e2e\"\n\n# Run all tests except slow ones\nvitest --tags-filter=\"!slow\"\n\n# Run frontend tests that are not flaky\nvitest --tags-filter=\"frontend && !flaky\"\n\n# Run tests matching a wildcard pattern\nvitest --tags-filter=\"api/*\"\n\n# Complex expression with parentheses\nvitest --tags-filter=\"(unit || e2e) && !slow\"\n\n# Run database tests that are either postgres or mysql, but not slow\nvitest --tags-filter=\"db && (postgres || mysql) && !slow\"\n```\n\nExample:\n```text\n# Run tests that match (unit OR e2e) AND are NOT slow\nvitest --tags-filter=\"unit || e2e\" --tags-filter=\"!slow\"\n```\n\nExample:\n```text\nimport { beforeAll, TestRunner } from 'vitest'\n\nbeforeAll(async () => {\n // Seed database when \"vitest --tags-filter db\" is used\n if (TestRunner.matchesTags(['db'])) {\n await seedDatabase()\n }\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.923Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":18,"totalLines":243,"estimatedTokens":1057}}25{"id":"doc-test_filtering_guide_vitest-9dcf4494","source":"documentation","title":"Test Filtering | Guide | Vitest","url":"https://vitest.dev/guide/filtering","text":"Example:\n```text\nvitest utils.test.ts -t \"handles empty input\"\n```\n\nExample:\n```text\nvitest --experimental.preParse -t \"handles empty input\"\n```\n\nExample:\n```text\nvitest basic\n```\n\nExample:\n```text\nbasic.test.ts\nbasic-foo.test.ts\nbasic/foo.test.ts\n```\n\nExample:\n```text\nvitest -t \"handles empty input\"\n```\n\nExample:\n```text\nvitest utils -t \"handles empty input\"\n```\n\nExample:\n```text\nvitest basic/foo.test.ts:10\n```\n\nExample:\n```text\nvitest basic/foo.test.ts:10 # ✅\nvitest ./basic/foo.test.ts:10 # ✅\nvitest /users/project/basic/foo.test.ts:10 # ✅\nvitest foo:10 # ❌ partial name won't work\nvitest ./basic/foo:10 # ❌ missing file extension\n```\n\nExample:\n```text\nvitest basic/foo.test.ts:10 basic/foo.test.ts:25 # ✅\nvitest basic/foo.test.ts:10-25 # ❌ ranges are not supported\n```\n\nExample:\n```text\ntest('renders a form', { tags: ['frontend'] }, () => {\n // ...\n})\n\ntest('calls an external API', { tags: ['backend'] }, () => {\n // ...\n})\n```\n\nExample:\n```text\nvitest --tags-filter=frontend\n```\n\nExample:\n```text\nimport { describe, expect, it } from 'vitest'\n\ndescribe.only('suite', () => {\n it('test', () => {\n // This runs because the suite is marked with .only\n expect(Math.sqrt(4)).toBe(2)\n })\n})\n\ndescribe('another suite', () => {\n it('skipped test', () => {\n // This does not run\n expect(Math.sqrt(4)).toBe(2)\n })\n\n it.only('focused test', () => {\n // This also runs because it is marked with .only\n expect(Math.sqrt(4)).toBe(2)\n })\n})\n```\n\nExample:\n```text\nimport { describe, expect, it } from 'vitest'\n\ndescribe.skip('skipped suite', () => {\n it('test', () => {\n // This entire suite is skipped\n expect(Math.sqrt(4)).toBe(2)\n })\n})\n\ndescribe('suite', () => {\n it.skip('skipped test', () => {\n // Just this one test is skipped\n expect(Math.sqrt(4)).toBe(2)\n })\n})\n```\n\nExample:\n```text\nimport { describe, it } from 'vitest'\n\ndescribe.todo('unimplemented suite')\n\ndescribe('suite', () => {\n it.todo('unimplemented test')\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.923Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":14,"totalLines":123,"estimatedTokens":497}}26{"id":"doc-test_run_lifecycle_guide_vitest-af7aec3e","source":"documentation","title":"Test Run Lifecycle | Guide | Vitest","url":"https://vitest.dev/guide/lifecycle","text":"Example:\n```text\nexport function setup(project) {\n // Runs once before all tests\n console.log('Global setup')\n\n // Share data with tests\n project.provide('apiUrl', 'http://localhost:3000')\n}\n\nexport function teardown() {\n // Runs once after all tests\n console.log('Global teardown')\n}\n```\n\nExample:\n```text\nimport { afterEach } from 'vitest'\n\n// Runs before each test file\nconsole.log('Setup file executing')\n\n// Register hooks that apply to all tests\nafterEach(() => {\n cleanup()\n})\n```\n\nExample:\n```text\n// This runs immediately (collection phase)\nconsole.log('File loaded')\n\ndescribe('User API', () => {\n // This runs immediately (collection phase)\n console.log('Suite defined')\n\n aroundAll(async (runSuite) => {\n // Wraps around all tests in this suite\n console.log('aroundAll before')\n await runSuite()\n console.log('aroundAll after')\n })\n\n beforeAll(() => {\n // Runs once before all tests in this suite\n console.log('beforeAll')\n })\n\n aroundEach(async (runTest) => {\n // Wraps around each test\n console.log('aroundEach before')\n await runTest()\n console.log('aroundEach after')\n })\n\n beforeEach(() => {\n // Runs before each test\n console.log('beforeEach')\n })\n\n test('creates user', () => {\n // Test executes\n console.log('test 1')\n })\n\n test('updates user', () => {\n // Test executes\n console.log('test 2')\n })\n\n afterEach(() => {\n // Runs after each test\n console.log('afterEach')\n })\n\n afterAll(() => {\n // Runs once after all tests in this suite\n console.log('afterAll')\n })\n})\n\n// Output:\n// File loaded\n// Suite defined\n// aroundAll before\n// beforeAll\n// aroundEach before\n// beforeEach\n// test 1\n// afterEach\n// aroundEach after\n// aroundEach before\n// beforeEach\n// test 2\n// afterEach\n// aroundEach after\n// afterAll\n// aroundAll after\n```\n\nExample:\n```text\ndescribe('outer', () => {\n aroundAll(async (runSuite) => {\n console.log('outer aroundAll before')\n await runSuite()\n console.log('outer aroundAll after')\n })\n\n beforeAll(() => console.log('outer beforeAll'))\n\n aroundEach(async (runTest) => {\n console.log('outer aroundEach before')\n await runTest()\n console.log('outer aroundEach after')\n })\n\n beforeEach(() => console.log('outer beforeEach'))\n\n test('outer test', () => console.log('outer test'))\n\n describe('inner', () => {\n aroundAll(async (runSuite) => {\n console.log('inner aroundAll before')\n await runSuite()\n console.log('inner aroundAll after')\n })\n\n beforeAll(() => console.log('inner beforeAll'))\n\n aroundEach(async (runTest) => {\n console.log('inner aroundEach before')\n await runTest()\n console.log('inner aroundEach after')\n })\n\n beforeEach(() => console.log('inner beforeEach'))\n\n test('inner test', () => console.log('inner test'))\n\n afterEach(() => console.log('inner afterEach'))\n afterAll(() => console.log('inner afterAll'))\n })\n\n afterEach(() => console.log('outer afterEach'))\n afterAll(() => console.log('outer afterAll'))\n})\n\n// Output:\n// outer aroundAll before\n// outer beforeAll\n// outer aroundEach before\n// outer beforeEach\n// outer test\n// outer afterEach\n// outer aroundEach after\n// inner aroundAll before\n// inner beforeAll\n// outer aroundEach before\n// inner aroundEach before\n// outer beforeEach\n// inner beforeEach\n// inner test\n// inner afterEach\n// outer afterEach\n// inner aroundEach after\n// outer aroundEach after\n// inner afterAll\n// inner aroundAll after\n// outer afterAll\n// outer aroundAll after\n```\n\nExample:\n```text\nexport function teardown() {\n // Clean up global resources\n console.log('Global teardown complete')\n}\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.924Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":184,"estimatedTokens":956}}27{"id":"doc-aria_snapshots_guide_vitest-6389e923","source":"documentation","title":"ARIA Snapshots | Guide | Vitest","url":"https://vitest.dev/guide/browser/aria-snapshots","text":"Example:\n```text\nawait expect.element(page.getByRole('navigation')).toMatchAriaInlineSnapshot(`\n - navigation \"Main\":\n - link \"Home\":\n - /url: /\n - link \"About\":\n - /url: /about\n`)\n```\n\nExample:\n```text\n<form aria-label=\"Log In\">\n <input aria-label=\"Email\" />\n <input aria-label=\"Password\" type=\"password\" />\n <button>Submit</button>\n</form>\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\n\ntest('login form', async () => {\n await expect.element(page.getByRole('form')).toMatchAriaSnapshot()\n})\n```\n\nExample:\n```text\n// Vitest Snapshot ...\n\nexports[`login form 1`] = `\n- form \"Log In\":\n - textbox \"Email\"\n - textbox \"Password\"\n - button \"Submit\"\n`\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\n\ntest('login form', async () => {\n await expect.element(page.getByRole('form')).toMatchAriaInlineSnapshot(`\n - form \"Log In\":\n - textbox \"Email\"\n - textbox \"Password\"\n - button \"Submit\"\n `)\n})\n```\n\nExample:\n```text\nawait expect.element(page.getByRole('form')).toMatchAriaInlineSnapshot(`\n - form \"Log In\":\n - textbox \"Email\"\n - textbox \"Password\"\n - button \"Submit\"\n`)\n```\n\nExample:\n```text\n<h1>Your Cart</h1>\n<ul aria-label=\"Cart Items\">\n <li>Wireless Headphones — $79.99</li>\n</ul>\n<button>Checkout</button>\n```\n\nExample:\n```text\n- heading \"Your Cart\" [level=1]\n- list \"Cart Items\":\n - listitem: Wireless Headphones — $79.99\n- button \"Checkout\"\n```\n\nExample:\n```text\n- heading \"Your Cart\" [level=1]\n- list \"Cart Items\":\n - listitem: /.+ — \\$\\d+\\.\\d+/\n- button \"Checkout\"\n```\n\nExample:\n```text\n- heading \"Your Cart\" [level=1]\n- list \"Cart Items\":\n - listitem: /.+ — \\$\\d+\\.\\d+/\n- button \"Place Order\" 👈 New snapshot updated with new string\n```\n\nExample:\n```text\n- role \"name\" [attribute=value]\n```\n\nExample:\n```text\n<button>Submit</button>\n<h1>Welcome</h1>\n<a href=\"/\">Home</a>\n<input aria-label=\"Email\" />\n```\n\nExample:\n```text\n- button \"Submit\"\n- heading \"Welcome\" [level=1]\n- link \"Home\"\n- textbox \"Email\"\n```\n\nExample:\n```text\n- text: Hello world\n```\n\nExample:\n```text\n<p>\nLine 1\nLine 2<br />Line 3\nLine 4\n</p>\n```\n\nExample:\n```text\n- paragraph: Line 1 Line 2 Line 3 Line 4\n```\n\nExample:\n```text\n- list:\n - listitem: First\n - listitem: Second\n - listitem: Third\n```\n\nExample:\n```text\n- navigation \"Main\":\n - link \"Home\"\n - link \"About\"\n```\n\nExample:\n```text\n<p>Hello world</p>\n```\n\nExample:\n```text\n- paragraph: Hello world\n```\n\nExample:\n```text\n- link \"Home\":\n - /url: /\n```\n\nExample:\n```text\n<input aria-label=\"Email\" placeholder=\"user@example.com\" />\n```\n\nExample:\n```text\n- textbox \"Email\":\n - /placeholder: user@example.com\n```\n\nExample:\n```text\n<input placeholder=\"Search\" />\n```\n\nExample:\n```text\n- textbox \"Search\"\n```\n\nExample:\n```text\n<input placeholder=\"Search\" aria-label=\"Search products\" />\n```\n\nExample:\n```text\n- textbox \"Search products\":\n - /placeholder: Search\n```\n\nExample:\n```text\n<h1>Welcome, Alice</h1>\n<a href=\"https://example.com/profile/123\">Profile</a>\n```\n\nExample:\n```text\n- heading /Welcome, .*/\n- link \"Profile\":\n - /url: /https:\\/\\/example\\.com\\/.*/\n```\n\nExample:\n```text\n<input aria-label=\"Search\" placeholder=\"Type to search...\" />\n```\n\nExample:\n```text\n- textbox \"Search\":\n - /placeholder: /Type .*/\n```\n\nExample:\n```text\n// ✅ Correct — double backslash\nawait expect.element(button).toMatchAriaInlineSnapshot(`\n - button: /item \\\\d+/\n`)\n\n// ❌ Wrong — single backslash is consumed by JS, regex sees \"d+\" instead of \"\\d+\"\nawait expect.element(button).toMatchAriaInlineSnapshot(`\n - button: /item \\d+/\n`)\n```\n\nExample:\n```text\n<main>\n <h1>Welcome</h1>\n <p>Some intro text</p>\n <button>Get Started</button>\n</main>\n```\n\nExample:\n```text\n// This passes — the template children are a subset of the actual children\nawait expect.element(page.getByRole('main')).toMatchAriaInlineSnapshot(`\n - main:\n - heading \"Welcome\" [level=1]\n`)\n```\n\nExample:\n```text\n// This FAILS — the list has 3 items but the template only lists 2\nawait expect.element(page.getByRole('list')).toMatchAriaInlineSnapshot(`\n - list \"Features\":\n - /children: equal\n - listitem: Feature A\n - listitem: Feature B\n`)\n```\n\nExample:\n```text\n// This PASSES — all 3 items are listed\nawait expect.element(page.getByRole('list')).toMatchAriaInlineSnapshot(`\n - list \"Features\":\n - /children: equal\n - listitem: Feature A\n - listitem: Feature B\n - listitem: Feature C\n`)\n```\n\nExample:\n```text\nawait expect.element(page.getByRole('navigation')).toMatchAriaInlineSnapshot(`\n - navigation \"Main\":\n - /children: deep-equal\n - link \"Home\":\n - /url: /\n - link \"About\":\n - /url: /about\n`)\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.924Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":37,"totalLines":292,"estimatedTokens":1165}}28{"id":"doc-mocking_modules_vitest-9d8a1fc8","source":"documentation","title":"Mocking Modules | Vitest","url":"https://vitest.dev/guide/mocking/modules","text":"Example:\n```text\nexport function answer() {\n // ...\n return 42\n}\n\nexport const variable = 'example'\n```\n\nExample:\n```text\nimport * as exampleObject from './example.js'\n```\n\nExample:\n```text\nimport { answer, variable } from './example.js'\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\n\n// The ./example.js module will be replaced with\n// the result of a factory function, and the\n// original ./example.js module will never be called\nvi.mock(import('./example.js'), () => {\n return {\n answer() {\n // ...\n return 42\n },\n variable: 'mock',\n }\n})\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\n\nvi.mock(import('./example.js'), () => {\n return {\n answer: vi.fn(),\n variable: 'mock',\n }\n})\n```\n\nExample:\n```text\nimport { expect, vi } from 'vitest'\nimport { answer } from './example.js'\n\nvi.mock(import('./example.js'), async (importOriginal) => {\n const originalModule = await importOriginal()\n return {\n answer: vi.fn(originalModule.answer),\n variable: 'mock',\n }\n})\n\nexpect(answer()).toBe(42)\n\nexpect(answer).toHaveBeenCalled()\nexpect(answer).toHaveReturned(42)\n```\n\nExample:\n```text\nimport { expect, vi } from 'vitest'\nimport * as exampleObject from './example.js'\n\nconst spy = vi.spyOn(exampleObject, 'answer').mockReturnValue(0)\n\nexpect(exampleObject.answer()).toBe(0)\nexpect(exampleObject.answer).toHaveBeenCalled()\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\nimport * as exampleObject from './example.js'\n\nvi.mock('./example.js', { spy: true })\n\nvi.mocked(exampleObject.answer).mockReturnValue(0)\n```\n\nExample:\n```text\nimport { answer } from './example.js'\n\nexport function question() {\n if (answer() === 42) {\n return 'Ultimate Question of Life, the Universe, and Everything'\n }\n\n return 'Unknown Question'\n}\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\n\nvi.mock(import('./example.js'))\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\n\nvi.mock(import('./example.js'), { spy: true })\n```\n\nExample:\n```text\nimport { expect, vi } from 'vitest'\nimport { answer } from './example.js'\n\nvi.mock(import('./example.js'), { spy: true })\n\n// calls the original implementation\nexpect(answer()).toBe(42)\n// vitest can still track the invocations\nexpect(answer).toHaveBeenCalled()\n```\n\nExample:\n```text\nexport class Answer {\n constructor(value) {\n this._value = value\n }\n\n value() {\n return this._value\n }\n}\n```\n\nExample:\n```text\nimport { expect, test, vi } from 'vitest'\nimport { Answer } from './answer.js'\n\nvi.mock(import('./answer.js'), { spy: true })\n\ntest('instance inherits the state', () => {\n // these invocations could be private inside another function\n // that you don't have access to in your test\n const answer1 = new Answer(42)\n const answer2 = new Answer(0)\n\n expect(answer1.value()).toBe(42)\n expect(answer1.value).toHaveBeenCalled()\n // note that different instances have their own states\n expect(answer2.value).not.toHaveBeenCalled()\n\n expect(answer2.value()).toBe(0)\n\n // but the prototype state accumulates all calls\n expect(Answer.prototype.value).toHaveBeenCalledTimes(2)\n expect(Answer.prototype.value).toHaveReturned(42)\n expect(Answer.prototype.value).toHaveReturned(0)\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { resolve } from 'node:path'\n\nexport default defineConfig({\n test: {\n alias: {\n vscode: resolve(import.meta.dirname, './mock/vscode.js'),\n },\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { resolve } from 'node:path'\n\nexport default defineConfig({\n plugins: [\n {\n name: 'virtual-vscode',\n resolveId(id) {\n if (id === 'vscode') {\n return 'vscode'\n }\n }\n }\n ]\n})\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\n\nvi.mock(import('vscode'), () => {\n return {\n window: {\n createOutputChannel: vi.fn(),\n }\n }\n})\n```\n\nExample:\n```text\nimport { answer } from './answer.js'\n\nvi.mock(import('./answer.js'))\n\nconsole.log(answer)\n```\n\nExample:\n```text\nvi.mock('./answer.js')\n\nconst __vitest_module_0__ = await __handle_mock__(\n () => import('./answer.js')\n)\n// to keep the live binding, we have to access\n// the export on the module namespace\nconsole.log(__vitest_module_0__.answer())\n```\n\nExample:\n```text\nexport function answer() {\n return 42\n}\n```\n\nExample:\n```text\nfunction answer() {\n return 42\n}\n\nconst __private_module__ = {\n [Symbol.toStringTag]: 'Module',\n answer: vi.fn(answer),\n}\n\nexport const answer = __private_module__.answer\n```\n\nExample:\n```text\nconst resolvedFactoryKeys = await resolveBrowserFactory(url)\nconst mockedModule = `\nconst __private_module__ = getFactoryReturnValue(${url})\n${resolvedFactoryKeys.map(key => `export const ${key} = __private_module__[\"${key}\"]`).join('\\n')}\n`\n```\n\nExample:\n```text\nexport function foo() {\n return 'foo'\n}\n\nexport function foobar() {\n return `${foo()}bar`\n}\n```\n\nExample:\n```text\nimport { vi } from 'vitest'\nimport * as mod from './foobar.js'\n\n// this will only affect \"foo\" outside of the original module\nvi.spyOn(mod, 'foo')\nvi.mock(import('./foobar.js'), async (importOriginal) => {\n return {\n ...await importOriginal(),\n // this will only affect \"foo\" outside of the original module\n foo: () => 'mocked'\n }\n})\n```\n\nExample:\n```text\nimport * as mod from './foobar.js'\n\nvi.spyOn(mod, 'foo')\n\n// exported foo references mocked method\nmod.foobar(mod.foo)\n```\n\nExample:\n```text\nexport function foo() {\n return 'foo'\n}\n\nexport function foobar(injectedFoo) {\n return injectedFoo === foo // false\n}\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.925Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":26,"totalLines":316,"estimatedTokens":1385}}29{"id":"doc-parallelism_guide_vitest-31b179d1","source":"documentation","title":"Parallelism | Guide | Vitest","url":"https://vitest.dev/guide/parallelism","text":"Example:\n```text\nimport { expect, test } from 'vitest'\n\ntest.concurrent('fetches user profile', async () => {\n const user = await fetchUser(1)\n expect(user.name).toBe('Alice')\n})\n\ntest.concurrent('fetches user posts', async () => {\n const posts = await fetchPosts(1)\n expect(posts).toHaveLength(3)\n})\n```\n\nExample:\n```text\n// These run one after another despite `concurrent`,\n// because there is nothing to await\ntest.concurrent('the first test', () => {\n expect(1).toBe(1)\n})\n\ntest.concurrent('the second test', () => {\n expect(2).toBe(2)\n})\n```\n\nExample:\n```text\nimport { describe, expect, test } from 'vitest'\n\ndescribe.concurrent('user API', () => {\n test('fetches profile', async () => {\n const user = await fetchUser(1)\n expect(user.name).toBe('Alice')\n })\n\n test('fetches posts', async () => {\n const posts = await fetchPosts(1)\n expect(posts).toHaveLength(3)\n })\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.925Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":3,"totalLines":46,"estimatedTokens":229}}30{"id":"doc-command_line_interface_guide_vitest-f03178d0","source":"documentation","title":"Command Line Interface | Guide | Vitest","url":"https://vitest.dev/guide/cli","text":"Example:\n```text\nvitest foobar\n```\n\nExample:\n```text\n$ vitest basic/foo.test.ts:10\n```\n\nExample:\n```text\n$ vitest basic/foo.js:10 # ✅\n$ vitest ./basic/foo.js:10 # ✅\n$ vitest /users/project/basic/foo.js:10 # ✅\n$ vitest foo:10 # ❌\n$ vitest ./basic/foo:10 # ❌\n```\n\nExample:\n```text\n$ vitest basic/foo.test.ts:10, basic/foo.test.ts:25 # ✅\n$ vitest basic/foo.test.ts:10-25 # ❌\n```\n\nExample:\n```text\nvitest related /src/index.ts /src/hello-world.js\n```\n\nExample:\n```text\nexport default {\n '*.{js,ts}': 'vitest related --run',\n}\n```\n\nExample:\n```text\nvitest init browser\n```\n\nExample:\n```text\nvitest list filename.spec.ts -t=\"some-test\"\n```\n\nExample:\n```text\ndescribe > some-test\ndescribe > some-test > test 1\ndescribe > some-test > test 2\n```\n\nExample:\n```text\nvitest list filename.spec.ts -t=\"some-test\" --json=./file.json\n```\n\nExample:\n```text\nvitest list --filesOnly\n```\n\nExample:\n```text\ntests/test1.test.ts\ntests/test2.test.ts\n```\n\nExample:\n```text\n# Add to ~/.zshrc for permanent autocompletions (same can be done for other shells)\nsource <(vitest complete zsh)\n```\n\nExample:\n```text\nnpm vitest <Tab>\n```\n\nExample:\n```text\nnpm exec vitest <Tab>\n```\n\nExample:\n```text\npnpm vitest <Tab>\n```\n\nExample:\n```text\nyarn vitest <Tab>\n```\n\nExample:\n```text\nbun vitest <Tab>\n```\n\nExample:\n```text\nvitest --reporter=dot --reporter=default\n```\n\nExample:\n```text\nvitest --no-api\nvitest --api=false\n```\n\nExample:\n```text\nvitest run --shard=1/3\nvitest run --shard=2/3\nvitest run --shard=3/3\n```\n\nExample:\n```text\nvitest --merge-reports --reporter=junit\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.927Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":22,"totalLines":125,"estimatedTokens":389}}31{"id":"doc-extending_matchers_guide_vitest-2e8d1385","source":"documentation","title":"Extending Matchers | Guide | Vitest","url":"https://vitest.dev/guide/extending-matchers","text":"Example:\n```text\nexpect.extend({\n toBeFoo(received, expected) {\n const { isNot } = this\n return {\n // do not alter your \"pass\" based on isNot. Vitest does it for you\n pass: received === 'foo',\n message: () => `${received} is${isNot ? ' not' : ''} foo`\n }\n }\n})\n```\n\nExample:\n```text\nimport 'vitest'\n\ndeclare module 'vitest' {\n interface Matchers<T = any> {\n toBeFoo: () => R\n }\n}\n```\n\nExample:\n```text\ninterface MatcherResult {\n pass: boolean\n message: () => string\n // If you pass these, they will automatically appear inside a diff when\n // the matcher does not pass, so you don't need to print the diff yourself\n actual?: unknown\n expected?: unknown\n}\n```\n\nExample:\n```text\nexpect.extend({\n async toBeAsyncAssertion() {\n // ...\n }\n})\n\nawait expect().toBeAsyncAssertion()\n```\n\nExample:\n```text\nimport type {\n // the function type\n Matcher,\n // the return value\n MatcherResult,\n // state available as `this`\n MatcherState,\n} from 'vitest'\nimport { expect } from 'vitest'\n\n// a simple matcher, using \"function\" to have access to \"this\"\nconst customMatcher: Matcher = function (received) {\n // ...\n}\n\n// a matcher with arguments\nconst customMatcher: Matcher<MatcherState, [arg1: unknown, arg2: unknown]> = function (received, arg1, arg2) {\n // ...\n}\n\n// a matcher with custom annotations\nfunction customMatcher(this: MatcherState, received: unknown, arg1: unknown, arg2: unknown): MatcherResult {\n // ...\n return {\n pass: false,\n message: () => 'something went wrong!',\n }\n}\n\nexpect.extend({ customMatcher })\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.927Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":83,"estimatedTokens":396}}32{"id":"doc-snapshot_guide_vitest-f1a1fdfc","source":"documentation","title":"Snapshot | Guide | Vitest","url":"https://vitest.dev/guide/snapshot","text":"Example:\n```text\nimport { expect, it } from 'vitest'\n\nit('toUpperCase', () => {\n const result = toUpperCase('foobar')\n expect(result).toMatchSnapshot()\n})\n```\n\nExample:\n```text\n// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n\nexports['toUpperCase 1'] = '\"FOOBAR\"'\n```\n\nExample:\n```text\nimport { expect, it } from 'vitest'\n\nit('toUpperCase', () => {\n const result = toUpperCase('foobar')\n expect(result).toMatchInlineSnapshot()\n})\n```\n\nExample:\n```text\nimport { expect, it } from 'vitest'\n\nit('toUpperCase', () => {\n const result = toUpperCase('foobar')\n expect(result).toMatchInlineSnapshot('\"FOOBAR\"')\n})\n```\n\nExample:\n```text\nvitest -u\n```\n\nExample:\n```text\nimport { expect, it } from 'vitest'\n\nit('render basic', async () => {\n const result = renderHTML(h('div', { class: 'foo' }))\n await expect(result).toMatchFileSnapshot('./test/basic.output.html')\n})\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\nimport { page } from 'vitest/browser'\n\ntest('button looks correct', async () => {\n const button = page.getByRole('button')\n await expect(button).toMatchScreenshot('primary-button')\n})\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\nimport { page } from 'vitest/browser'\n\ntest('navigation structure', async () => {\n await expect.element(page.getByRole('navigation')).toMatchAriaInlineSnapshot(`\n - navigation \"Main\":\n - link \"Home\":\n - /url: /\n - link \"About\":\n - /url: /about\n `)\n})\n```\n\nExample:\n```text\nexpect.addSnapshotSerializer({\n serialize(val, config, indentation, depth, refs, printer) {\n // `printer` is a function that serializes a value using existing plugins.\n return `Pretty foo: ${printer(\n val.foo,\n config,\n indentation,\n depth,\n refs,\n )}`\n },\n test(val) {\n return val && Object.prototype.hasOwnProperty.call(val, 'foo')\n },\n})\n```\n\nExample:\n```text\nimport { SnapshotSerializer } from 'vitest'\n\nexport default {\n serialize(val, config, indentation, depth, refs, printer) {\n // `printer` is a function that serializes a value using existing plugins.\n return `Pretty foo: ${printer(\n val.foo,\n config,\n indentation,\n depth,\n refs,\n )}`\n },\n test(val) {\n return val && Object.prototype.hasOwnProperty.call(val, 'foo')\n },\n} satisfies SnapshotSerializer\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n snapshotSerializers: ['path/to/custom-serializer.ts'],\n },\n})\n```\n\nExample:\n```text\ntest('foo snapshot test', () => {\n const bar = {\n foo: {\n x: 1,\n y: 2,\n },\n }\n\n expect(bar).toMatchSnapshot()\n})\n```\n\nExample:\n```text\nPretty foo: Object {\n \"x\": 1,\n \"y\": 2,\n}\n```\n\nExample:\n```text\nimport { expect, test, Snapshots } from 'vitest'\n\nconst { toMatchFileSnapshot, toMatchInlineSnapshot, toMatchSnapshot } = Snapshots\n\nexpect.extend({\n toMatchTrimmedSnapshot(received: string) {\n return toMatchSnapshot.call(this, received.slice(0, 10))\n },\n toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) {\n return toMatchInlineSnapshot.call(this, received.slice(0, 10), inlineSnapshot)\n },\n async toMatchTrimmedFileSnapshot(received: string, file: string) {\n return toMatchFileSnapshot.call(this, received.slice(0, 10), file)\n },\n})\n\ntest('file snapshot', () => {\n // create __snapshots__/demo.test.ts with\n // > exports[`file snapshot 1`] = `\"extra long\"`\n expect('extra long string oh my gerd').toMatchTrimmedSnapshot(10)\n})\n\ntest('inline snapshot', () => {\n expect('super long string oh my gerd').toMatchTrimmedInlineSnapshot(`\"super long\"`)\n})\n\ntest('raw file snapshot', async () => {\n // create raw-file.txt with:\n // > crazy long\n await expect('crazy long string oh my gerd').toMatchTrimmedFileSnapshot('./raw-file.txt')\n})\n```\n\nExample:\n```text\nimport { Snapshots } from 'vitest'\n\nconst { toMatchSnapshot } = Snapshots\n\nexpect.extend({\n toMatchTrimmedSnapshot(received: string, length: number) {\n const result = toMatchSnapshot.call(this, received.slice(0, length))\n return { ...result, message: () => `Trimmed snapshot failed: ${result.message()}` }\n },\n})\n```\n\nExample:\n```text\nimport { expect, chai, Snapshots } from 'vitest'\n\nconst { toMatchInlineSnapshot } = Snapshots\n\nexpect.extend({\n async toMatchTransformedInlineSnapshot(received: string, inlineSnapshot?: string) {\n // capture call site synchronously at the top of matcher implementation\n chai.util.flag(this.assertion, 'error', new Error())\n const transformed = await transform(received)\n return toMatchInlineSnapshot.call(this, transformed, inlineSnapshot)\n },\n})\n```\n\nExample:\n```text\nimport 'vitest'\n\ndeclare module 'vitest' {\n interface Assertion<T = any> {\n toMatchTrimmedSnapshot: (length: number) => T\n toMatchTrimmedInlineSnapshot: (inlineSnapshot?: string) => T\n toMatchTrimmedFileSnapshot: (file: string) => Promise<T>\n }\n}\n```\n\nExample:\n```text\nimport type { DomainMatchResult, DomainSnapshotAdapter } from '@vitest/snapshot'\n\nconst myAdapter: DomainSnapshotAdapter<Captured, Expected> = {\n name: 'my-domain',\n\n // Extract structured data from the received value\n capture(received: unknown): Captured { /* ... */ },\n\n // Render captured data as the snapshot string (what gets stored)\n render(captured: Captured): string { /* ... */ },\n\n // Parse a stored snapshot string into a structured expected value\n parseExpected(input: string): Expected { /* ... */ },\n\n // Compare captured vs expected, return pass/fail and resolved output\n match(captured: Captured, expected: Expected): DomainMatchResult { /* ... */ },\n}\n```\n\nExample:\n```text\ntype KVCaptured = Record<string, string>\ntype KVExpected = Record<string, string | RegExp>\n```\n\nExample:\n```text\nimport { expect, Snaphsots } from 'vitest'\n\nexpect.extend({\n toMatchMyDomainSnapshot(received: unknown) {\n return Snaphsots.toMatchDomainSnapshot.call(this, myAdapter, received)\n },\n toMatchMyDomainInlineSnapshot(received: unknown, inlineSnapshot?: string) {\n return Snaphsots.toMatchDomainInlineSnapshot.call(\n this,\n myAdapter,\n received,\n inlineSnapshot,\n )\n },\n})\n```\n\nExample:\n```text\nexpect(value).toMatchMyDomainSnapshot()\nexpect(value).toMatchMyDomainInlineSnapshot(`key=value`)\n```\n\nExample:\n```text\nimport type { DomainMatchResult, DomainSnapshotAdapter } from '@vitest/snapshot'\n\ntype KVCaptured = Record<string, string>\ntype KVExpected = Record<string, string | RegExp>\n\nfunction renderKV(obj: Record<string, unknown>) {\n return `\\n${Object.entries(obj).map(([k, v]) => `${k}=${v}`).join('\\n')}\\n`\n}\n\nexport const kvAdapter: DomainSnapshotAdapter<KVCaptured, KVExpected> = {\n name: 'kv',\n\n capture(received: unknown): KVCaptured {\n if (received && typeof received === 'object') {\n return Object.fromEntries(\n Object.entries(received).map(([k, v]) => [k, String(v)]),\n )\n }\n throw new TypeError('kv adapter expects a plain object')\n },\n\n render(captured: KVCaptured): string {\n return renderKV(captured)\n },\n\n parseExpected(input: string): KVExpected {\n const entries = input.trim().split('\\n').map((line) => {\n const eq = line.indexOf('=')\n const key = line.slice(0, eq)\n const raw = line.slice(eq + 1)\n const value = (raw.startsWith('/') && raw.endsWith('/') && raw.length > 1)\n ? new RegExp(raw.slice(1, -1))\n : raw\n return [key, value]\n })\n return Object.fromEntries(entries)\n },\n\n match(captured: KVCaptured, expected: KVExpected): DomainMatchResult {\n const resolvedLines: string[] = []\n let pass = true\n\n for (const [key, actualValue] of Object.entries(captured)) {\n const expectedValue = expected[key]\n\n // non-asserted keys are skipped (works as subset match)\n if (typeof expectedValue === 'undefined') {\n continue\n }\n\n // preserve matched pattern for normalized diff and partial update\n if (expectedValue instanceof RegExp && expectedValue.test(actualValue)) {\n resolvedLines.push(`${key}=/${expectedValue.source}/`)\n continue\n }\n\n resolvedLines.push(`${key}=${actualValue}`)\n pass &&= actualValue === expectedValue\n }\n\n return {\n pass,\n message: pass ? undefined : 'KV entries do not match',\n resolved: `\\n${resolvedLines.join('\\n')}\\n`,\n expected: `\\n${renderKV(expected)}\\n`,\n }\n },\n}\n```\n\nExample:\n```text\nimport { expect, Snapshots } from 'vitest'\nimport { kvAdapter } from './kv-adapter'\n\nexpect.extend({\n toMatchKvSnapshot(received: unknown) {\n return Snapshots.toMatchDomainSnapshot.call(this, kvAdapter, received)\n },\n toMatchKvInlineSnapshot(received: unknown, inlineSnapshot?: string) {\n return Snapshots.toMatchDomainInlineSnapshot.call(this, kvAdapter, received, inlineSnapshot)\n },\n})\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\n\ntest('user data', () => {\n const user = { name: 'Alice', score: '42' }\n expect(user).toMatchKvSnapshot()\n})\n\ntest('user data inline', () => {\n const user = { name: 'Alice', age: 100, score: '42' }\n expect(user).toMatchKvInlineSnapshot(`\n name=Alice\n score=/\\\\d+/\n `)\n})\n```\n\nExample:\n```text\n- // Jest Snapshot v1, https://goo.gl/fbAQLP\n+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\n\ntest('snapshot', () => {\n const bar = [\n {\n foo: 'bar',\n },\n ]\n\n // in Jest\n expect(bar).toMatchInlineSnapshot(`\n Array [\n Object {\n \"foo\": \"bar\",\n },\n ]\n `)\n\n // in Vitest\n expect(bar).toMatchInlineSnapshot(`\n [\n {\n \"foo\": \"bar\",\n },\n ]\n `)\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n snapshotFormat: {\n printBasicPrototype: true,\n },\n },\n})\n```\n\nExample:\n```text\ntest('toThrowErrorMatchingSnapshot', () => {\n expect(() => {\n throw new Error('error')\n }).toThrowErrorMatchingSnapshot('hint')\n})\n```\n\nExample:\n```text\nexports[`toThrowErrorMatchingSnapshot: hint 1`] = `\"error\"`;\n```\n\nExample:\n```text\nexports[`toThrowErrorMatchingSnapshot > hint 1`] = `[Error: error]`;\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\n\ntest('snapshot', () => {\n // in Jest and Vitest\n expect(new Error('error')).toMatchInlineSnapshot(`[Error: error]`)\n\n // Jest snapshots `Error.message` for `Error` instance\n // Vitest prints the same value as toMatchInlineSnapshot\n expect(() => {\n throw new Error('error')\n }).toThrowErrorMatchingInlineSnapshot(`\"error\"`) \n }).toThrowErrorMatchingInlineSnapshot(`[Error: error]`) \n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.928Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":31,"totalLines":474,"estimatedTokens":2662}}33{"id":"doc-test_annotations_guide_vitest-927b0d6c","source":"documentation","title":"Test Annotations | Guide | Vitest","url":"https://vitest.dev/guide/test-annotations","text":"Example:\n```text\ntest('hello world', async ({ annotate }) => {\n await annotate('this is my test')\n\n if (condition) {\n await annotate('this should\\'ve errored', 'error')\n }\n\n const file = createTestSpecificFile()\n await annotate('creates a file', { body: file })\n\n await annotate('creates a file with text', {\n contentType: 'text/markdown',\n body: 'Hello **markdown**',\n bodyEncoding: 'utf-8',\n })\n})\n```\n\nExample:\n```text\n⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯\n\n FAIL example.test.js > an example of a test with annotation\nError: thrown error\n ❯ example.test.js:11:21\n 9 | await annotate('annotation 1')\n 10| await annotate('annotation 2', 'warning')\n 11| throw new Error('thrown error')\n | ^\n 12| })\n\n ❯ example.test.js:9:15 notice\n ↳ annotation 1\n ❯ example.test.js:10:15 warning\n ↳ annotation 2\n\n ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯\n```\n\nExample:\n```text\n✓ example.test.js > an example of a test with annotation\n\n ❯ example.test.js:9:15 notice\n ↳ annotation 1\n ❯ example.test.js:10:15 warning\n ↳ annotation 2\n```\n\nExample:\n```text\n<testcase classname=\"basic/example.test.js\" name=\"an example of a test with annotation\" time=\"0.14315\">\n <properties>\n <property name=\"notice\" value=\"the message of the annotation\">\n </property>\n </properties>\n</testcase>\n```\n\nExample:\n```text\nok 1 - an example of a test with annotation # time=143.15ms\n # notice: the message of the annotation\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.928Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":68,"estimatedTokens":372}}34{"id":"doc-debugging_guide_vitest-4ae32ffc","source":"documentation","title":"Debugging | Guide | Vitest","url":"https://vitest.dev/guide/debugging","text":"Example:\n```text\n{\n // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"type\": \"node\",\n \"request\": \"launch\",\n \"name\": \"Debug Current Test File\",\n \"autoAttachChildProcesses\": true,\n \"skipFiles\": [\"<node_internals>/**\", \"**/node_modules/**\"],\n \"program\": \"${workspaceRoot}/node_modules/vitest/vitest.mjs\",\n \"args\": [\"run\", \"${relativeFile}\"],\n \"smartStep\": true,\n \"console\": \"integratedTerminal\"\n }\n ]\n}\n```\n\nExample:\n```text\nvitest --inspect-brk --browser --no-file-parallelism\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n inspectBrk: true,\n fileParallelism: false,\n browser: {\n provider: playwright(),\n instances: [{ browser: 'chromium' }]\n },\n },\n})\n```\n\nExample:\n```text\nvitest --inspect-brk=127.0.0.1:3000 --browser --no-file-parallelism\n```\n\nExample:\n```text\n{\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"type\": \"node\",\n \"request\": \"launch\",\n \"name\": \"Run Vitest Browser\",\n \"program\": \"${workspaceRoot}/node_modules/vitest/vitest.mjs\",\n \"console\": \"integratedTerminal\",\n \"args\": [\"--inspect-brk\", \"--browser\", \"--no-file-parallelism\"]\n },\n {\n \"type\": \"chrome\",\n \"request\": \"attach\",\n \"name\": \"Attach to Vitest Browser\",\n \"port\": 9229\n }\n ],\n \"compounds\": [\n {\n \"name\": \"Debug Vitest Browser\",\n \"configurations\": [\"Attach to Vitest Browser\", \"Run Vitest Browser\"],\n \"stopAll\": true\n }\n ]\n}\n```\n\nExample:\n```text\n# To run in a single worker\nvitest --inspect-brk --no-file-parallelism\n\n# To run in browser mode\nvitest --inspect-brk --browser --no-file-parallelism\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.929Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":6,"totalLines":88,"estimatedTokens":462}}35{"id":"doc-in_source_testing_guide_vitest-c44ed06d","source":"documentation","title":"In-Source Testing | Guide | Vitest","url":"https://vitest.dev/guide/in-source","text":"Example:\n```text\n// the implementation\nexport function add(...args: number[]) {\n return args.reduce((a, b) => a + b, 0)\n}\n\n// in-source test suites\nif (import.meta.vitest) {\n const { it, expect } = import.meta.vitest\n it('add', () => {\n expect(add()).toBe(0)\n expect(add(1)).toBe(1)\n expect(add(1, 2, 3)).toBe(6)\n })\n}\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n includeSource: ['src/**/*.{js,ts}'], \n },\n})\n```\n\nExample:\n```text\n$ npx vitest\n```\n\nExample:\n```text\n/// <reference types=\"vitest/config\" />\n\nimport { defineConfig } from 'vite'\n\nexport default defineConfig({\n test: {\n includeSource: ['src/**/*.{js,ts}'],\n },\n define: { \n 'import.meta.vitest': 'undefined', \n }, \n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'rolldown/config'\n\nexport default defineConfig({\n transform: {\n define: { \n 'import.meta.vitest': 'undefined', \n }, \n },\n})\n```\n\nExample:\n```text\nimport replace from '@rollup/plugin-replace'\n\nexport default {\n plugins: [\n replace({ \n 'import.meta.vitest': 'undefined', \n }) \n ],\n // other options\n}\n```\n\nExample:\n```text\nimport { defineBuildConfig } from 'unbuild'\n\nexport default defineBuildConfig({\n replace: { \n 'import.meta.vitest': 'undefined', \n }, \n // other options\n})\n```\n\nExample:\n```text\nconst webpack = require('webpack')\n\nmodule.exports = {\n plugins: [\n new webpack.DefinePlugin({ \n 'import.meta.vitest': 'undefined', \n })\n ],\n}\n```\n\nExample:\n```text\n{\n \"compilerOptions\": {\n \"types\": [\n \"vitest/importMeta\"\n ]\n }\n}\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.929Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":114,"estimatedTokens":408}}36{"id":"doc-test_context_guide_vitest-de36aae0","source":"documentation","title":"Test Context | Guide | Vitest","url":"https://vitest.dev/guide/test-context","text":"Example:\n```text\nimport { it } from 'vitest'\n\nit('should work', ({ task }) => {\n // prints name of the test\n console.log(task.name)\n})\n```\n\nExample:\n```text\nimport { it } from 'vitest'\n\nit('math is easy', ({ expect }) => {\n expect(2 + 2).toBe(4)\n})\n```\n\nExample:\n```text\nimport { it } from 'vitest'\n\nit.concurrent('math is easy', ({ expect }) => {\n expect(2 + 2).toMatchInlineSnapshot()\n})\n\nit.concurrent('math is hard', ({ expect }) => {\n expect(2 * 2).toMatchInlineSnapshot()\n})\n```\n\nExample:\n```text\nfunction skip(note?: string): never\nfunction skip(condition: boolean, note?: string): void\n```\n\nExample:\n```text\nimport { expect, it } from 'vitest'\n\nit('math is hard', ({ skip }) => {\n skip()\n expect(2 + 2).toBe(5)\n})\n```\n\nExample:\n```text\nit('math is hard', ({ skip, mind }) => {\n skip(mind === 'foggy')\n expect(2 + 2).toBe(5)\n})\n```\n\nExample:\n```text\nfunction annotate(\n message: string,\n attachment?: TestAttachment,\n): Promise<TestAnnotation>\n\nfunction annotate(\n message: string,\n type?: string,\n attachment?: TestAttachment,\n): Promise<TestAnnotation>\n```\n\nExample:\n```text\ntest('annotations API', async ({ annotate }) => {\n await annotate('https://github.com/vitest-dev/vitest/pull/7953', 'issues')\n})\n```\n\nExample:\n```text\nit('stop request when test times out', async ({ signal }) => {\n await fetch('/resource', { signal })\n}, 2000)\n```\n\nExample:\n```text\nimport { test as baseTest } from 'vitest'\n\nexport const test = baseTest\n // Simple value - type is inferred as { port: number; host: string }\n .extend('config', { port: 3000, host: 'localhost' })\n // Function fixture - type is inferred from return value\n .extend('server', async ({ config }) => {\n // TypeScript knows config is { port: number; host: string }\n return `http://${config.host}:${config.port}`\n })\n```\n\nExample:\n```text\nimport { expect } from 'vitest'\nimport { test } from './my-test.js'\n\ntest('server uses correct port', ({ config, server }) => {\n // TypeScript knows the types:\n // - config is { port: number; host: string }\n // - server is string\n expect(server).toBe('http://localhost:3000')\n expect(config.port).toBe(3000)\n})\n```\n\nExample:\n```text\nimport { test as baseTest } from 'vitest'\n\nexport const test = baseTest\n .extend('tempFile', async ({}, { onCleanup }) => {\n const filePath = `/tmp/test-${Date.now()}.txt`\n await fs.writeFile(filePath, 'test data')\n\n // Register cleanup - runs after test completes\n onCleanup(async () => {\n await fs.unlink(filePath)\n })\n\n return filePath\n })\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('database', { scope: 'file' }, async ({}, { onCleanup }) => {\n const db = await createDatabase()\n await db.connect()\n\n onCleanup(async () => {\n await db.disconnect()\n })\n\n return db\n })\n .extend('user', async ({ database }, { onCleanup }) => {\n const user = await database.createTestUser()\n\n onCleanup(async () => {\n await database.deleteUser(user.id)\n })\n\n return user\n })\n```\n\nExample:\n```text\n// ❌ This will throw an error\nconst test = baseTest\n .extend('resources', async ({}, { onCleanup }) => {\n const a = await acquireA()\n onCleanup(() => releaseA(a))\n\n const b = await acquireB()\n onCleanup(() => releaseB(b)) // Error: onCleanup can only be called once\n\n return { a, b }\n })\n\n// ✅ Split into separate fixtures (recommended)\nconst test = baseTest\n .extend('resourceA', async ({}, { onCleanup }) => {\n const a = await acquireA()\n onCleanup(() => releaseA(a))\n return a\n })\n .extend('resourceB', async ({}, { onCleanup }) => {\n const b = await acquireB()\n onCleanup(() => releaseB(b))\n return b\n })\n```\n\nExample:\n```text\nconst test = baseTest\n // Automatic fixture - runs for every test even if not used\n .extend('metrics', { auto: true }, ({}, { onCleanup }) => {\n const metrics = new MetricsCollector()\n metrics.start()\n onCleanup(() => metrics.stop())\n return metrics\n })\n // Worker-scoped fixture - initialized once per worker\n .extend('config', { scope: 'worker' }, () => {\n return loadConfig()\n })\n // File-scoped fixture - initialized once per file\n .extend('database', { scope: 'file' }, async ({ config }, { onCleanup }) => {\n const db = await createDatabase(config)\n onCleanup(() => db.close())\n return db\n })\n // Injected fixture - can be overridden via config\n .extend('baseUrl', { injected: true }, () => {\n return 'http://localhost:3000'\n })\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('simple', () => 'value')\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('config', { apiUrl: 'https://api.example.com', port: 3000 })\n .extend('client', ({ config }) => {\n // TypeScript knows config is { apiUrl: string; port: number }\n return new ApiClient(config.apiUrl)\n })\n .extend('user', async ({ client }) => {\n // TypeScript knows client is ApiClient\n return await client.getCurrentUser()\n })\n```\n\nExample:\n```text\nimport { test as baseTest } from 'vitest'\n\nexport const test = baseTest.extend({\n page: async ({}, use) => {\n // setup the fixture before each test function\n const page = await browser.newPage()\n\n // use the fixture value\n await use(page)\n\n // cleanup the fixture after each test function\n await page.close()\n },\n baseUrl: 'http://localhost:3000'\n})\n```\n\nExample:\n```text\n// Object syntax: cleanup code goes AFTER use()\nconst test = baseTest.extend({\n database: async ({}, use) => {\n const db = await createDatabase()\n await db.connect()\n\n await use(db) // Test runs here\n\n // Cleanup after the test\n await db.disconnect()\n }\n})\n\n// Builder pattern: cleanup is registered with onCleanup()\nconst test = baseTest\n .extend('database', async ({}, { onCleanup }) => {\n const db = await createDatabase()\n await db.connect()\n\n onCleanup(() => db.disconnect())\n\n return db // Test runs after this returns\n })\n```\n\nExample:\n```text\nconst test = baseTest.extend<{\n page: Page\n baseUrl: string\n}>({\n page: async ({}, use) => {\n const page = await browser.newPage()\n await use(page)\n await page.close()\n },\n baseUrl: 'http://localhost:3000'\n})\n```\n\nExample:\n```text\nconst test = baseTest.extend({\n // Auto fixture\n fixture: [\n async ({}, use) => {\n setup()\n await use()\n teardown()\n },\n { auto: true }\n ],\n // Scoped fixture\n database: [\n async ({}, use) => {\n const db = await createDatabase()\n await use(db)\n await db.close()\n },\n { scope: 'file' }\n ],\n // Injected fixture\n url: [\n '/default',\n { injected: true }\n ],\n})\n```\n\nExample:\n```text\nimport { test as baseTest } from 'vitest'\n\nconst test = baseTest\n .extend('database', async () => {\n console.log('database initializing')\n return createDatabase()\n })\n .extend('cache', async () => {\n return createCache()\n })\n\n// database will not run\ntest('no fixtures needed', () => {})\ntest('only cache', ({ cache }) => {})\n\n// database will run\ntest('needs database', ({ database }) => {})\n```\n\nExample:\n```text\ntest('context must be destructured', (context) => { \n expect(context.database).toBeDefined()\n})\n\ntest('context must be destructured', ({ database }) => { \n expect(database).toBeDefined()\n})\n```\n\nExample:\n```text\nimport { test as dbTest } from './my-test.js'\n\nexport const test = dbTest\n .extend('user', ({ database }) => {\n return database.createUser()\n })\n```\n\nExample:\n```text\nimport { test as dbTest } from './my-test.js'\n\nexport const test = dbTest.extend({\n admin: async ({ database }, use) => {\n const admin = await database.createAdmin()\n await use(admin)\n await database.deleteUser(admin.id)\n }\n})\n```\n\nExample:\n```text\nconst test = baseTest\n // Object syntax for simple fixtures\n .extend<{ apiKey: string }>({\n apiKey: 'test-key-123',\n })\n // Builder pattern for complex fixtures with inference\n .extend('client', ({ apiKey }) => {\n // TypeScript knows apiKey is string\n return new ApiClient(apiKey)\n })\n```\n\nExample:\n```text\ntest\n .extend('port', { scope: 'worker' }, 5000)\n .extend('db', { scope: 'worker' }, async ({ port }) => {\n return createDb(port)\n })\n```\n\nExample:\n```text\ntest.describe('a nested suite', () => {\n test.override('port', { scope: 'worker' }, 3000) // throws an error\n})\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('counter', () => {\n return { value: 0 }\n })\n\ntest('first test', ({ counter }) => {\n counter.value++\n expect(counter.value).toBe(1)\n})\n\ntest('second test', ({ counter }) => {\n // Fresh instance, value is 0 again\n expect(counter.value).toBe(0)\n})\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('testInfo', ({ task }) => {\n return { name: task.name }\n })\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('database', { scope: 'file' }, async ({}, { onCleanup }) => {\n const db = await createDatabase()\n onCleanup(() => db.close())\n return db\n })\n\ntest('first test', ({ database }) => {\n // Uses the same database instance\n})\n\ntest('second test', ({ database }) => {\n // Same database instance as first test\n})\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('config', { scope: 'worker' }, () => {\n return await loadExpensiveConfig()\n })\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('config', { scope: 'worker' }, () => {\n return { apiUrl: 'https://api.example.com' }\n })\n .extend('database', { scope: 'file' }, async ({ config }, { onCleanup }) => {\n // ✅ File fixture can access worker fixture\n const db = await createDatabase(config.apiUrl)\n onCleanup(() => db.close())\n return db\n })\n .extend('user', async ({ database, task }) => {\n // ✅ Test fixture can access file fixture AND test context\n return await database.createUser(task.name)\n })\n```\n\nExample:\n```text\nconst test = baseTest.extend<{\n $worker: { config: Config }\n $file: { database: Database }\n $test: { user: User }\n}>({\n config: [async ({}, use) => {\n await use(loadConfig())\n }, { scope: 'worker' }],\n\n database: [async ({ config }, use) => {\n const db = await createDatabase(config)\n await use(db)\n await db.close()\n }, { scope: 'file' }],\n\n user: async ({ database }, use) => {\n const user = await database.createUser()\n await use(user)\n await database.deleteUser(user.id)\n },\n})\n```\n\nExample:\n```text\nimport { test as baseTest } from 'vitest'\n\nconst test = baseTest\n .extend('url', { injected: true }, '/default')\n\ntest('works correctly', ({ url }) => {\n // url is \"/default\" in \"project-new\"\n // url is \"/full\" in \"project-full\"\n // url is \"/empty\" in \"project-empty\"\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n test: {\n name: 'project-new',\n },\n },\n {\n test: {\n name: 'project-full',\n provide: {\n url: '/full',\n },\n },\n },\n {\n test: {\n name: 'project-empty',\n provide: {\n url: '/empty',\n },\n },\n },\n ],\n },\n})\n```\n\nExample:\n```text\nimport { test as baseTest, describe, expect } from 'vitest'\n\nconst test = baseTest\n .extend('config', { port: 3000, host: 'localhost' })\n .extend('server', ({ config }) => `http://${config.host}:${config.port}`)\n\ndescribe('production environment', () => {\n // Override with a new static value (chainable)\n test\n .override('config', { port: 8080, host: 'api.example.com' })\n\n test('uses production config', ({ server }) => {\n expect(server).toBe('http://api.example.com:8080')\n })\n})\n\ndescribe('with custom server', () => {\n // Override with a function that can access other fixtures\n test.override('server', ({ config }) => {\n return `https://${config.host}:${config.port}/v2`\n })\n\n test('uses custom server', ({ server }) => {\n expect(server).toBe('https://localhost:3000/v2')\n })\n})\n\ntest('uses default values', ({ server }) => {\n expect(server).toBe('http://localhost:3000')\n})\n```\n\nExample:\n```text\ndescribe('production environment', () => {\n test\n .override('environment', 'production')\n .override('port', 8080)\n .override('debug', false)\n\n test('uses production settings', ({ environment, port, debug }) => {\n expect(environment).toBe('production')\n expect(port).toBe(8080)\n expect(debug).toBe(false)\n })\n})\n```\n\nExample:\n```text\ndescribe('different configuration', () => {\n test.override({\n config: { port: 4000, host: 'test.local' },\n })\n\n test('uses overwritten config', ({ config }) => {\n expect(config.port).toBe(4000)\n })\n})\n```\n\nExample:\n```text\ndescribe('with custom database', () => {\n test.override('database', async ({ config }, { onCleanup }) => {\n const db = await createTestDatabase(config)\n onCleanup(() => db.drop())\n return db\n })\n\n test('uses custom database', ({ database }) => {\n // Uses the overwritten database\n })\n})\n```\n\nExample:\n```text\ndescribe('level 1', () => {\n test.override('value', 'one')\n\n test('uses level 1 value', ({ value }) => {\n expect(value).toBe('one')\n })\n\n describe('level 2', () => {\n test.override('value', 'two')\n\n test('uses level 2 value', ({ value }) => {\n expect(value).toBe('two')\n })\n })\n\n test('still uses level 1 value', ({ value }) => {\n expect(value).toBe('one')\n })\n})\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('counter', { value: 0, increment() { this.value++ } })\n\n// Unlike global hooks, these hooks are aware of the extended context\ntest.beforeEach(({ counter }) => {\n counter.increment()\n})\n\ntest.afterEach(({ counter }) => {\n console.log('Final count:', counter.value)\n})\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('config', { scope: 'file' }, () => loadConfig())\n .extend('database', { scope: 'file' }, async ({ config }, { onCleanup }) => {\n const db = await createDatabase(config)\n onCleanup(() => db.close())\n return db\n })\n\n// Access file-scoped fixtures in suite-level hooks\ntest.aroundAll(async (runSuite, { database }) => {\n await database.transaction(runSuite)\n})\n\ntest.beforeAll(async ({ database }) => {\n await database.createUsers()\n})\n\ntest.afterAll(async ({ database }) => {\n await database.removeUsers()\n})\n```\n\nExample:\n```text\nimport { test as baseTest, beforeAll } from 'vitest'\n\nconst test = baseTest\n .extend('database', { scope: 'file' }, async ({}, { onCleanup }) => {\n const db = await createDatabase()\n onCleanup(() => db.close())\n return db\n })\n\n// ❌ WRONG: Global beforeAll doesn't have access to 'database'\nbeforeAll(({ database }) => {\n // Error: 'database' is undefined\n})\n\n// ✅ CORRECT: Use test.beforeAll to access fixtures\ntest.beforeAll(({ database }) => {\n // 'database' is available\n})\n```\n\nExample:\n```text\nconst test = baseTest\n .extend('testFixture', () => 'test-scoped')\n .extend('fileFixture', { scope: 'file' }, () => 'file-scoped')\n\n// ❌ Error: test-scoped fixtures not available in beforeAll\ntest.beforeAll(({ testFixture }) => {})\n\n// ✅ Works: file-scoped fixtures are available\ntest.beforeAll(({ fileFixture }) => {})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.930Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":45,"totalLines":721,"estimatedTokens":3779}}37{"id":"doc-common_errors_guide_vitest-a89df619","source":"documentation","title":"Common Errors | Guide | Vitest","url":"https://vitest.dev/guide/common-errors","text":"Example:\n```text\nimport { defineConfig } from 'vitest/config'\nimport tsconfigPaths from 'vite-tsconfig-paths'\n\nexport default defineConfig({\n plugins: [tsconfigPaths()]\n})\n```\n\nExample:\n```text\n- import helpers from 'src/helpers'\n+ import helpers from '../src/helpers'\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n alias: {\n '@/': './src/', \n '@/': new URL('./src/', import.meta.url).pathname, \n }\n }\n})\n```\n\nExample:\n```text\n{\n \"exports\": {\n \".\": {\n \"custom\": \"./lib/custom.js\",\n \"import\": \"./lib/index.js\"\n }\n },\n \"imports\": {\n \"#internal\": {\n \"custom\": \"./src/internal.js\",\n \"default\": \"./lib/internal.js\"\n }\n }\n}\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n ssr: {\n resolve: {\n conditions: ['custom', 'import', 'default'],\n },\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n pool: 'forks',\n },\n})\n```\n\nExample:\n```text\nvitest --pool=forks\n```\n\nExample:\n```text\nasync function fetchUser(id) {\n const res = await fetch(`/api/users/${id}`)\n if (!res.ok) {\n throw new Error(`User ${id} not found`) \n }\n return res.json()\n}\n\ntest('fetches user', async () => {\n fetchUser(123) \n})\n```\n\nExample:\n```text\nUnhandled Rejection: Error: User 123 not found\n```\n\nExample:\n```text\ntest('fetches user', async () => {\n await fetchUser(123) \n})\n```\n\nExample:\n```text\ntest('rejects for missing user', async () => {\n await expect(fetchUser(123)).rejects.toThrow('User 123 not found')\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.930Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":11,"totalLines":112,"estimatedTokens":414}}38{"id":"doc-profiling_test_performance_vitest-71927abf","source":"documentation","title":"Profiling Test Performance | Vitest","url":"https://vitest.dev/guide/profiling-test-performance","text":"Example:\n```text\nRUN v2.1.1 /x/vitest/examples/profiling\n\n✓ test/prime-number.test.ts (1) 4517ms\n ✓ generate prime number 4517ms\n\nTest Files 1 passed (1)\n Tests 1 passed (1)\n Start at 09:32:53\n Duration 4.80s (transform 44ms, setup 0ms, import 35ms, tests 4.52s, environment 0ms)\n # Time metrics ^^\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n fileParallelism: false,\n execArgv: [\n '--cpu-prof',\n '--cpu-prof-dir=test-runner-profile',\n '--heap-prof',\n '--heap-prof-dir=test-runner-profile'\n ],\n },\n})\n```\n\nExample:\n```text\n$ node --cpu-prof --cpu-prof-dir=main-profile ./node_modules/vitest/vitest.mjs --run\n# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^\n# NodeJS arguments Vitest arguments\n```\n\nExample:\n```text\n├── src\n│ └── utils\n│ ├── currency.ts\n│ ├── formatters.ts <-- File to test\n│ ├── index.ts\n│ ├── location.ts\n│ ├── math.ts\n│ ├── time.ts\n│ └── users.ts\n├── test\n│ └── formatters.test.ts\n└── vitest.config.ts\n```\n\nExample:\n```text\nimport { expect, test } from 'vitest'\nimport { formatter } from '../src/utils'\nimport { formatter } from '../src/utils/formatters'\n\ntest('formatter works', () => {\n expect(formatter).not.toThrow()\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n experimental: {\n importDurations: {\n print: true,\n },\n },\n },\n})\n```\n\nExample:\n```text\nImport Duration Breakdown (Top 10)\n\nModule Self Total\nmy-test.test.ts 5ms 620ms [████████████████████]\ndate-fns/index.js 500ms 500ms [████████████████░░░░] \nsrc/utils/helpers.ts 10ms 120ms [████████░░░░░░░░░░░░]\n```\n\nExample:\n```text\nvitest --experimental.importDurations.print\n```\n\nExample:\n```text\nimport { format } from 'date-fns'\nimport { format } from 'date-fns/format'\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n resolve: {\n alias: [\n {\n find: /^date-fns$/,\n replacement: join(dirname(require.resolve('date-fns/package.json')), 'index.cjs'),\n },\n ]\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n deps: {\n optimizer: {\n ssr: {\n enabled: true,\n include: ['date-fns'],\n },\n },\n },\n },\n})\n```\n\nExample:\n```text\n$ DEBUG=vitest:coverage vitest --run --coverage\n\n RUN v3.1.1 /x/vitest-example\n\n vitest:coverage Reading coverage results 2/2\n vitest:coverage Converting 1/2\n vitest:coverage 4 ms /x/src/multiply.ts\n vitest:coverage Converting 2/2\n vitest:coverage 552 ms /x/src/add.ts\n vitest:coverage Uncovered files 1/2\n vitest:coverage File \"/x/src/large-file.ts\" is taking longer than 3s\n vitest:coverage 3027 ms /x/src/large-file.ts\n vitest:coverage Uncovered files 2/2\n vitest:coverage 4 ms /x/src/untested-file.ts\n vitest:coverage Generate coverage total time 3521 ms\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.931Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":155,"estimatedTokens":795}}39{"id":"doc-timers_vitest-6bb18aba","source":"documentation","title":"Timers | Vitest","url":"https://vitest.dev/guide/mocking/timers","text":"Example:\n```text\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nfunction executeAfterTwoHours(func) {\n setTimeout(func, 1000 * 60 * 60 * 2) // 2 hours\n}\n\nfunction executeEveryMinute(func) {\n setInterval(func, 1000 * 60) // 1 minute\n}\n\nconst mock = vi.fn(() => console.log('executed'))\n\ndescribe('delayed execution', () => {\n beforeEach(() => {\n vi.useFakeTimers()\n })\n afterEach(() => {\n vi.clearAllMocks()\n })\n it('should execute the function', () => {\n executeAfterTwoHours(mock)\n vi.runAllTimers()\n expect(mock).toHaveBeenCalledTimes(1)\n })\n it('should not execute the function', () => {\n executeAfterTwoHours(mock)\n // advancing by 2ms won't trigger the func\n vi.advanceTimersByTime(2)\n expect(mock).not.toHaveBeenCalled()\n })\n it('should execute every minute', () => {\n executeEveryMinute(mock)\n vi.advanceTimersToNextTimer()\n expect(mock).toHaveBeenCalledTimes(1)\n vi.advanceTimersToNextTimer()\n expect(mock).toHaveBeenCalledTimes(2)\n })\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.931Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":1,"totalLines":43,"estimatedTokens":262}}40{"id":"doc-vitest_ui_guide_vitest-cfde7508","source":"documentation","title":"Vitest UI | Guide | Vitest","url":"https://vitest.dev/guide/ui","text":"Example:\n```text\nnpm i -D @vitest/ui\n```\n\nExample:\n```text\nvitest --ui\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n reporters: ['html'],\n },\n})\n```\n\nExample:\n```text\nnpx vite preview --outDir ./html\n```\n\nExample:\n```text\n- uses: actions/upload-artifact@v4\n id: upload-report\n with:\n name: vitest-report\n path: html/\n\n- name: Viewer link in summary\n run: echo \"[View HTML report](https://viewer.vitest.dev/?url=${{ steps.upload-report.outputs.artifact-url }})\" >> $GITHUB_STEP_SUMMARY\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.931Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":39,"estimatedTokens":145}}41{"id":"doc-testing_types_guide_vitest-e566a2e9","source":"documentation","title":"Testing Types | Guide | Vitest","url":"https://vitest.dev/guide/testing-types","text":"Example:\n```text\nimport { assertType, expectTypeOf } from 'vitest'\nimport { mount } from './mount.js'\n\ntest('my types work properly', () => {\n expectTypeOf(mount).toBeFunction()\n expectTypeOf(mount).parameter(0).toExtend<{ name: string }>()\n\n // @ts-expect-error name is a string\n assertType(mount({ name: 42 }))\n})\n```\n\nExample:\n```text\nexpectTypeOf({ a: 1 }).toEqualTypeOf<{ a: string }>()\n```\n\nExample:\n```text\ntest/test.ts:999:999 - error TS2344: Type '{ a: string; }' does not satisfy the constraint '{ a: \\\\\"Expected: string, Actual: number\\\\\"; }'.\n Types of property 'a' are incompatible.\n Type 'string' is not assignable to type '\\\\\"Expected: string, Actual: number\\\\\"'.\n\n999 expectTypeOf({a: 1}).toEqualTypeOf<{a: string}>()\n```\n\nExample:\n```text\ntest/test.ts:999:999 - error TS2349: This expression is not callable.\n Type 'ExpectString<number>' has no call signatures.\n\n999 expectTypeOf(1).toBeString()\n ~~~~~~~~~~\n```\n\nExample:\n```text\nexpectTypeOf({ a: 1 }).toEqualTypeOf({ a: '' })\n```\n\nExample:\n```text\nconst one = valueFromFunctionOne({ some: { complex: inputs } })\nconst two = valueFromFunctionTwo({ some: { other: inputs } })\n\nexpectTypeOf(one).toEqualTypeOf<typeof two>()\n```\n\nExample:\n```text\nconst answer = 42\n\nassertType<number>(answer)\n// @ts-expect-error answer is not a string\nassertType<string>(answer)\n```\n\nExample:\n```text\n// @ts-expect-error answer is not a string\nassertType<string>(answr)\n```\n\nExample:\n```text\n{\n \"scripts\": {\n \"test\": \"vitest --typecheck\"\n }\n}\n```\n\nExample:\n```text\nnpm run test\n```\n\nExample:\n```text\nyarn test\n```\n\nExample:\n```text\npnpm run test\n```\n\nExample:\n```text\nbun test\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.932Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":13,"totalLines":95,"estimatedTokens":419}}42{"id":"doc-open_telemetry_support_vitest-d9acab6e","source":"documentation","title":"Open Telemetry Support | Vitest","url":"https://vitest.dev/guide/open-telemetry","text":"Example:\n```text\nnpm i @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-proto\n```\n\nExample:\n```text\nimport { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'\nimport { NodeSDK } from '@opentelemetry/sdk-node'\n\nconst sdk = new NodeSDK({\n serviceName: 'vitest',\n traceExporter: new OTLPTraceExporter(),\n instrumentations: [getNodeAutoInstrumentations()],\n})\n\nsdk.start()\nexport default sdk\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n experimental: {\n openTelemetry: {\n enabled: true,\n sdkPath: './otel.js',\n },\n },\n },\n})\n```\n\nExample:\n```text\nimport { trace } from '@opentelemetry/api'\nimport { test } from 'vitest'\nimport { db } from './src/db'\n\nconst tracer = trace.getTracer('vitest')\n\ntest('db connects properly', async () => {\n // this is shown inside `vitest.test.runner.test.callback` span\n await tracer.startActiveSpan('db.connect', () => db.connect())\n})\n```\n\nExample:\n```text\nnpm i @opentelemetry/sdk-trace-web @opentelemetry/exporter-trace-otlp-proto\n```\n\nExample:\n```text\nimport {\n BatchSpanProcessor,\n WebTracerProvider,\n} from '@opentelemetry/sdk-trace-web'\nimport { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto'\n\nconst provider = new WebTracerProvider({\n spanProcessors: [\n new BatchSpanProcessor(new OTLPTraceExporter()),\n ],\n})\n\nprovider.register()\nexport default provider\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n browser: {\n enabled: true,\n provider: 'playwright',\n instances: [{ browser: 'chromium' }],\n },\n experimental: {\n openTelemetry: {\n enabled: true,\n sdkPath: './otel.js',\n browserSdkPath: './otel-browser.js',\n },\n },\n },\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.932Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":7,"totalLines":97,"estimatedTokens":496}}43{"id":"doc-advanced_api_vitest-d90ef359","source":"documentation","title":"Advanced API | Vitest","url":"https://vitest.dev/guide/advanced/","text":"Example:\n```text\nfunction startVitest(\n mode: VitestRunMode,\n cliFilters: string[] = [],\n options: CliOptions = {},\n viteOverrides?: ViteUserConfig,\n vitestOptions?: VitestOptions,\n): Promise<Vitest>\n```\n\nExample:\n```text\nimport { startVitest } from 'vitest/node'\n\nconst vitest = await startVitest('test')\n\nawait vitest.close()\n```\n\nExample:\n```text\nimport type { TestModule } from 'vitest/node'\n\nconst vitest = await startVitest('test')\n\nconsole.log(vitest.state.getTestModules()) // [TestModule]\n```\n\nExample:\n```text\nfunction createVitest(\n mode: VitestRunMode,\n options: CliOptions,\n viteOverrides: ViteUserConfig = {},\n vitestOptions: VitestOptions = {},\n): Promise<Vitest>\n```\n\nExample:\n```text\nimport { createVitest } from 'vitest/node'\n\nconst vitest = await createVitest('test', {\n watch: false,\n})\n```\n\nExample:\n```text\nfunction resolveConfig(\n options: UserConfig = {},\n viteOverrides: ViteUserConfig = {},\n): Promise<{\n vitestConfig: ResolvedConfig\n viteConfig: ResolvedViteConfig\n}>\n```\n\nExample:\n```text\nimport { resolveConfig } from 'vitest/node'\n\n// vitestConfig only has resolved \"test\" properties\nconst { vitestConfig, viteConfig } = await resolveConfig({\n mode: 'custom',\n configFile: false,\n resolve: {\n conditions: ['custom']\n },\n test: {\n setupFiles: ['/my-setup-file.js'],\n pool: 'threads',\n },\n})\n```\n\nExample:\n```text\nfunction parseCLI(argv: string | string[], config: CliParseOptions = {}): {\n filter: string[]\n options: CliOptions\n}\n```\n\nExample:\n```text\nimport { parseCLI } from 'vitest/node'\n\nconst result = parseCLI('vitest ./files.ts --coverage --browser=chrome')\n\nresult.options\n// {\n// coverage: { enabled: true },\n// browser: { name: 'chrome', enabled: true }\n// }\n\nresult.filter\n// ['./files.ts']\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.932Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":102,"estimatedTokens":446}}44{"id":"doc-mocking_classes_vitest-741cdc6a","source":"documentation","title":"Mocking Classes | Vitest","url":"https://vitest.dev/guide/mocking/classes","text":"Example:\n```text\nclass Dog {\n name: string\n\n constructor(name: string) {\n this.name = name\n }\n\n static getType(): string {\n return 'animal'\n }\n\n greet = (): string => {\n return `Hi! My name is ${this.name}!`\n }\n\n speak(): string {\n return 'bark!'\n }\n\n isHungry() {}\n feed() {}\n}\n```\n\nExample:\n```text\nconst Dog = vi.fn(class {\n static getType = vi.fn(() => 'mocked animal')\n\n constructor(name) {\n this.name = name\n }\n\n greet = vi.fn(() => `Hi! My name is ${this.name}!`)\n speak = vi.fn(() => 'loud bark!')\n feed = vi.fn()\n})\n```\n\nExample:\n```text\nconst CorrectDogClass = vi.fn(function (name) {\n this.name = name\n})\n\nconst IncorrectDogClass = vi.fn(name => ({\n name\n}))\n\nconst Marti = new CorrectDogClass('Marti')\nconst Newt = new IncorrectDogClass('Newt')\n\nMarti instanceof CorrectDogClass // ✅ true\nNewt instanceof IncorrectDogClass // ❌ false!\n```\n\nExample:\n```text\nimport { Dog } from './dog.js'\n\nvi.mock(import('./dog.js'), () => {\n const Dog = vi.fn(class {\n feed = vi.fn()\n // ... other mocks\n })\n return { Dog }\n})\n```\n\nExample:\n```text\nfunction feed(dog: Dog) {\n // ...\n}\n```\n\nExample:\n```text\nimport { expect, test, vi } from 'vitest'\nimport { feed } from '../src/feed.js'\n\nconst Dog = vi.fn(class {\n feed = vi.fn()\n})\n\ntest('can feed dogs', () => {\n const dogMax = new Dog('Max')\n\n feed(dogMax)\n\n expect(dogMax.feed).toHaveBeenCalled()\n expect(dogMax.isHungry()).toBe(false)\n})\n```\n\nExample:\n```text\nconst Cooper = new Dog('Cooper')\nCooper.speak() // loud bark!\nCooper.greet() // Hi! My name is Cooper!\n\n// you can use built-in assertions to check the validity of the call\nexpect(Cooper.speak).toHaveBeenCalled()\nexpect(Cooper.greet).toHaveBeenCalled()\n\nconst Max = new Dog('Max')\n\n// methods are not shared between instances if you assigned them directly\nexpect(Max.speak).not.toHaveBeenCalled()\nexpect(Max.greet).not.toHaveBeenCalled()\n```\n\nExample:\n```text\nconst dog = new Dog('Cooper')\n\n// \"vi.mocked\" is a type helper, since\n// TypeScript doesn't know that Dog is a mocked class,\n// it wraps any function in a Mock<T> type\n// without validating if the function is a mock\nvi.mocked(dog.speak).mockReturnValue('woof woof')\n\ndog.speak() // woof woof\n```\n\nExample:\n```text\nconst dog = new Dog('Cooper')\n\nconst nameSpy = vi.spyOn(dog, 'name', 'get').mockReturnValue('Max')\n\nexpect(dog.name).toBe('Max')\nexpect(nameSpy).toHaveBeenCalledTimes(1)\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.932Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":9,"totalLines":138,"estimatedTokens":606}}45{"id":"doc-test_projects_guide_vitest-0529bfdf","source":"documentation","title":"Test Projects | Guide | Vitest","url":"https://vitest.dev/guide/projects","text":"Example:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: ['packages/*'],\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n // include all folders inside \"packages\" except \"excluded\"\n projects: [\n 'packages/*',\n '!packages/excluded'\n ],\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\n// For example, this will create projects:\n// packages/a\n// packages/b\n// packages/business/c\n// packages/business/d\n// Notice that \"packages/business\" is not a project itself\n\nexport default defineConfig({\n test: {\n projects: [\n // matches every folder inside \"packages\" except \"business\"\n 'packages/!(business)',\n // matches every folder inside \"packages/business\"\n 'packages/business/*',\n ],\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: ['packages/*/vitest.config.{e2e,unit}.ts'],\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: [\n // matches every folder and file inside the `packages` folder\n 'packages/*',\n {\n // add \"extends: true\" to inherit the options from the root config\n extends: true,\n test: {\n include: ['tests/**/*.{browser}.test.{ts,js}'],\n // it is recommended to define a name when using inline configs\n name: 'happy-dom',\n environment: 'happy-dom',\n }\n },\n {\n test: {\n include: ['tests/**/*.{node}.test.{ts,js}'],\n // color of the name label can be changed\n name: { label: 'node', color: 'green' },\n environment: 'node',\n }\n }\n ]\n }\n})\n```\n\nExample:\n```text\nimport { defineProject } from 'vitest/config'\n\nexport default defineProject({\n test: {\n environment: 'jsdom',\n // \"reporters\" is not supported in a project config,\n // so it will show an error\n reporters: ['json']No overload matches this call.\n The last overload gave the following error.\n Object literal may only specify known properties, and 'reporters' does not exist in type 'ProjectConfig'. }\n})\n```\n\nExample:\n```text\n{\n \"scripts\": {\n \"test\": \"vitest\"\n }\n}\n```\n\nExample:\n```text\nnpm run test\n```\n\nExample:\n```text\nyarn test\n```\n\nExample:\n```text\npnpm run test\n```\n\nExample:\n```text\nbun run test\n```\n\nExample:\n```text\nnpm run test --project e2e\n```\n\nExample:\n```text\nyarn test --project e2e\n```\n\nExample:\n```text\npnpm run test --project e2e\n```\n\nExample:\n```text\nbun run test --project e2e\n```\n\nExample:\n```text\nnpm run test --project e2e --project unit\n```\n\nExample:\n```text\nyarn test --project e2e --project unit\n```\n\nExample:\n```text\npnpm run test --project e2e --project unit\n```\n\nExample:\n```text\nbun run test --project e2e --project unit\n```\n\nExample:\n```text\nimport { defineProject, mergeConfig } from 'vitest/config'\nimport configShared from '../vitest.shared.js'\n\nexport default mergeConfig(\n configShared,\n defineProject({\n test: {\n environment: 'jsdom',\n }\n })\n)\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport react from '@vitejs/plugin-react'\n\nexport default defineConfig({\n plugins: [react()],\n test: {\n pool: 'threads',\n projects: [\n {\n // will inherit options from this config like plugins and pool\n extends: true,\n test: {\n name: 'unit',\n include: ['**/*.unit.test.ts'],\n },\n },\n {\n // won't inherit any options from this config\n // this is the default behaviour\n extends: false,\n test: {\n name: 'integration',\n include: ['**/*.integration.test.ts'],\n },\n },\n ],\n },\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.933Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":21,"totalLines":224,"estimatedTokens":970}}46{"id":"doc-recipes_guide_vitest-59d4d376","source":"documentation","title":"Recipes | Guide | Vitest","url":"https://vitest.dev/guide/recipes","text":"Example:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n test: {\n // Non-isolated unit tests\n name: 'Unit tests',\n isolate: false,\n exclude: ['**.integration.test.ts'],\n },\n },\n {\n test: {\n // Isolated integration tests\n name: 'Integration tests',\n include: ['**.integration.test.ts'],\n },\n },\n ],\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n test: {\n name: 'Parallel',\n exclude: ['**.sequential.test.ts'],\n },\n },\n {\n test: {\n name: 'Sequential',\n include: ['**.sequential.test.ts'],\n fileParallelism: false,\n },\n },\n ],\n },\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.933Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":2,"totalLines":53,"estimatedTokens":229}}47{"id":"doc-coverage_guide_vitest-7b60d185","source":"documentation","title":"Coverage | Guide | Vitest","url":"https://vitest.dev/guide/coverage","text":"Example:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n coverage: {\n provider: 'v8' // or 'istanbul'\n },\n },\n})\n```\n\nExample:\n```text\nnpm i -D @vitest/coverage-v8\n```\n\nExample:\n```text\nnpm i -D @vitest/coverage-istanbul\n```\n\nExample:\n```text\n// Simplified example of branch and function coverage counters\nconst coverage = { \n branches: { 1: [0, 0] }, \n functions: { 1: 0 }, \n} \n\nexport function getUsername(id) {\n // Function coverage increased when this is invoked\n coverage.functions['1']++\n\n if (id == null) {\n // Branch coverage increased when this is invoked\n coverage.branches['1'][0]++\n\n throw new Error('User ID is required')\n }\n // Implicit else coverage increased when if-statement condition not met\n coverage.branches['1'][1]++\n\n return database.getUser(id)\n}\n\nglobalThis.__VITEST_COVERAGE__ ||= {} \nglobalThis.__VITEST_COVERAGE__[filename] = coverage\n```\n\nExample:\n```text\n{\n \"scripts\": {\n \"test\": \"vitest\",\n \"coverage\": \"vitest run --coverage\"\n }\n}\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n coverage: {\n enabled: true\n },\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n coverage: {\n include: ['src/**/*.{ts,tsx}']\n },\n },\n})\n```\n\nExample:\n```text\n├── src\n│ ├── components\n│ │ └── counter.tsx\n│ ├── mock-data\n│ │ ├── products.json\n│ │ └── users.json\n│ └── utils\n│ ├── formatters.ts\n│ ├── time.ts\n│ └── users.ts\n├── test\n│ └── utils.test.ts\n│\n├── package.json\n├── tsup.config.ts\n└── vitest.config.ts\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n coverage: {\n include: ['src/**/*.{ts,tsx}'],\n exclude: ['**/utils/users.ts']\n },\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n coverage: {\n reporter: [\n // Specify reporter using name of the NPM package\n ['@vitest/custom-coverage-reporter', { someOption: true }],\n\n // Specify reporter using local path\n '/absolute/path/to/custom-reporter.cjs',\n ],\n },\n },\n})\n```\n\nExample:\n```text\nconst { ReportBase } = require('istanbul-lib-report')\n\nmodule.exports = class CustomReporter extends ReportBase {\n constructor(opts) {\n super()\n\n // Options passed from configuration are available here\n this.file = opts.file\n }\n\n onStart(root, context) {\n this.contentWriter = context.writer.writeFile(this.file)\n this.contentWriter.println('Start of custom coverage report')\n }\n\n onEnd() {\n this.contentWriter.println('End of custom coverage report')\n this.contentWriter.close()\n }\n}\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n coverage: {\n provider: 'custom',\n customProviderModule: 'my-custom-coverage-provider'\n },\n },\n})\n```\n\nExample:\n```text\nimport type {\n CoverageProvider,\n CoverageProviderModule,\n ResolvedCoverageOptions,\n Vitest\n} from 'vitest'\n\nconst CustomCoverageProviderModule: CoverageProviderModule = {\n getProvider(): CoverageProvider {\n return new CustomCoverageProvider()\n },\n\n // Implements rest of the CoverageProviderModule ...\n}\n\nclass CustomCoverageProvider implements CoverageProvider {\n name = 'custom-coverage-provider'\n options!: ResolvedCoverageOptions\n\n initialize(ctx: Vitest) {\n this.options = ctx.config.coverage\n }\n\n // Implements rest of the CoverageProvider ...\n}\n\nexport default CustomCoverageProviderModule\n```\n\nExample:\n```text\n-/* istanbul ignore if */\n+/* istanbul ignore if -- @preserve */\nif (condition) {\n\n-/* v8 ignore if */\n+/* v8 ignore if -- @preserve */\nif (condition) {\n```\n\nExample:\n```text\n/* istanbul ignore start -- @preserve */\nif (parameter) { \n console.log('Ignored') \n} \nelse { \n console.log('Ignored') \n} \n/* istanbul ignore stop -- @preserve */\n\nconsole.log('Included')\n\n/* v8 ignore start -- @preserve */\nif (parameter) { \n console.log('Ignored') \n} \nelse { \n console.log('Ignored') \n} \n/* v8 ignore stop -- @preserve */\n\nconsole.log('Included')\n```\n\nExample:\n```text\n/* v8 ignore if -- @preserve */\nif (parameter) { \n console.log('Ignored') \n} \nelse {\n console.log('Included')\n}\n\n/* v8 ignore else -- @preserve */\nif (parameter) {\n console.log('Included')\n}\nelse { \n console.log('Ignored') \n}\n```\n\nExample:\n```text\n/* v8 ignore next -- @preserve */\nconsole.log('Ignored') \nconsole.log('Included')\n\n/* v8 ignore next -- @preserve */\nfunction ignored() { \n console.log('all') \n console.log('lines') \n console.log('are') \n console.log('ignored') \n} \n\n/* v8 ignore next -- @preserve */\nclass Ignored { \n ignored() {} \n alsoIgnored() {} \n} \n\n/* v8 ignore next -- @preserve */\ncondition \n ? console.log('ignored') \n : console.log('also ignored')\n```\n\nExample:\n```text\n/* v8 ignore next -- @preserve */\ntry { \n console.log('Ignored') \n} \ncatch (error) { \n console.log('Ignored') \n} \n\ntry {\n console.log('Included')\n}\ncatch (error) {\n /* v8 ignore next -- @preserve */\n console.log('Ignored') \n /* v8 ignore next -- @preserve */\n console.log('Ignored') \n}\n\n// Requires rolldown-vite due to esbuild's lack of support.\n// See https://vite.dev/guide/rolldown.html#how-to-try-rolldown\ntry {\n console.log('Included')\n}\ncatch (error) /* v8 ignore next */ { \n console.log('Ignored') \n}\n```\n\nExample:\n```text\nswitch (type) {\n case 1:\n return 'Included'\n\n /* v8 ignore next -- @preserve */\n case 2: \n return 'Ignored'\n\n case 3:\n return 'Included'\n\n /* v8 ignore next -- @preserve */\n default: \n return 'Ignored'\n}\n```\n\nExample:\n```text\n/* v8 ignore file -- @preserve */\nexport function ignored() { \n return 'Whole file is ignored'\n}\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.934Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":20,"totalLines":348,"estimatedTokens":1471}}48{"id":"doc-running_tests_advanced_vitest-92e11681","source":"documentation","title":"Running Tests advanced | Vitest","url":"https://vitest.dev/guide/advanced/tests","text":"Example:\n```text\nimport { startVitest } from 'vitest/node'\n\nconst vitest = await startVitest(\n 'test',\n [], // CLI filters\n {}, // override test config\n {}, // override Vite config\n {}, // custom Vitest options\n)\nconst testModules = vitest.state.getTestModules()\nfor (const testModule of testModules) {\n console.log(testModule.moduleId, testModule.ok() ? 'passed' : 'failed')\n}\n```\n\nExample:\n```text\nimport { createVitest } from 'vitest/node'\n\nconst vitest = await createVitest(\n 'test',\n {}, // override test config\n {}, // override Vite config\n {}, // custom Vitest options\n)\n\n// called when `vitest.cancelCurrentRun()` is invoked\nvitest.onCancel(() => {})\n// called during `vitest.close()` call\nvitest.onClose(() => {})\n// called when Vitest reruns test files\nvitest.onTestsRerun((files) => {})\n\ntry {\n // this will set process.exitCode to 1 if tests failed,\n // and won't close the process automatically\n await vitest.start(['my-filter'])\n}\ncatch (err) {\n // this can throw\n // \"FilesNotFoundError\" if no files were found\n // \"GitNotFoundError\" with `--changed` and repository is not initialized\n}\nfinally {\n await vitest.close()\n}\n```\n\nExample:\n```text\nwatcher.on('change', async (file) => {\n const specifications = vitest.getModuleSpecifications(file)\n if (specifications.length) {\n vitest.invalidateFile(file)\n // you can use runTestSpecifications if \"reporter.onWatcher*\" hooks\n // should not be invoked\n await vitest.rerunTestSpecifications(specifications)\n }\n})\n```\n\nExample:\n```text\nwatcher.on('add', async (file) => {\n const specifications = []\n for (const project of vitest.projects) {\n if (project.matchesGlobPattern(file)) {\n specifications.push(project.createSpecification(file))\n }\n }\n\n if (specifications.length) {\n await vitest.rerunTestSpecifications(specifications)\n }\n})\n```\n\nExample:\n```text\nawait createVitest(\n 'test',\n {},\n {\n plugins: [\n {\n name: 'stop-watcher',\n async configureServer(server) {\n await server.watcher.close()\n }\n }\n ],\n server: {\n watch: null,\n },\n }\n)\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.934Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":101,"estimatedTokens":532}}49{"id":"doc-custom_pool_advanced_vitest-94cf582a","source":"documentation","title":"Custom Pool advanced | Vitest","url":"https://vitest.dev/guide/advanced/pool","text":"Example:\n```text\nimport { defineConfig } from 'vitest/config'\nimport customPool from './my-custom-pool.ts'\n\nexport default defineConfig({\n test: {\n // will run every file with a custom pool by default\n pool: customPool({\n customProperty: true,\n })\n },\n})\n```\n\nExample:\n```text\nimport customPool from './my-custom-pool.ts'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n extends: true,\n test: {\n pool: 'threads',\n },\n },\n {\n extends: true,\n test: {\n pool: customPool({\n customProperty: true,\n })\n }\n }\n ],\n },\n})\n```\n\nExample:\n```text\nimport type { PoolRunnerInitializer } from 'vitest/node'\n\nexport function customPool(customOptions: CustomOptions): PoolRunnerInitializer {\n return {\n name: 'custom-pool',\n createPoolWorker: options => new CustomPoolWorker(options, customOptions),\n }\n}\n```\n\nExample:\n```text\nimport type { PoolOptions, PoolWorker, WorkerRequest } from 'vitest/node'\n\nclass CustomPoolWorker implements PoolWorker {\n name = 'custom-pool'\n private customOptions: CustomOptions\n\n constructor(options: PoolOptions, customOptions: CustomOptions) {\n this.customOptions = customOptions\n }\n\n send(message: WorkerRequest): void {\n // Provide way to send your worker a message\n }\n\n on(event: string, callback: (arg: any) => void): void {\n // Provide way to listen to your workers events, e.g. message, error, exit\n }\n\n off(event: string, callback: (arg: any) => void): void {\n // Provide way to unsubscribe `on` listeners\n }\n\n async start() {\n // do something when the worker is started\n }\n\n async stop() {\n // cleanup the state\n }\n\n deserialize(data) {\n return data\n }\n}\n```\n\nExample:\n```text\nimport { init, runBaseTests, setupEnvironment } from 'vitest/worker'\n\ninit({\n post: (response) => {\n // Provide way to send this message to CustomPoolRunner's onWorker as message event\n },\n on: (callback) => {\n // Provide a way to listen CustomPoolRunner's \"postMessage\" calls\n },\n off: (callback) => {\n // Optional, provide a way to remove listeners added by \"on\" calls\n },\n teardown: () => {\n // Optional, provide a way to teardown worker, e.g. unsubscribe all the `on` listeners\n },\n serialize: (value) => {\n // Optional, provide custom serializer for `post` calls\n },\n deserialize: (value) => {\n // Optional, provide custom deserializer for `on` callbacks\n },\n runTests: (state, traces) => runBaseTests('run', state, traces),\n collectTests: (state, traces) => runBaseTests('collect', state, traces),\n setup: setupEnvironment,\n})\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.935Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":5,"totalLines":121,"estimatedTokens":666}}50{"id":"doc-migration_guide_guide_vitest-de81b528","source":"documentation","title":"Migration Guide | Guide | Vitest","url":"https://vitest.dev/guide/migration","text":"Example:\n```text\nexport default defineConfig({\n test: {\n coverage: {\n // Include covered and uncovered files matching this pattern:\n include: ['packages/**/src/**.{js,jsx,ts,tsx}'], \n\n // Exclusion is applied for the files that match include pattern above\n // No need to define root level *.config.ts files or node_modules, as we didn't add those in include\n exclude: ['**/some-pattern/**'], \n\n // These options are removed now\n all: true, \n extensions: ['js', 'ts'], \n }\n }\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n coverage: {\n // Include not set, include only files that are loaded during test run\n include: undefined, \n\n // Loaded files that match this pattern will be excluded:\n exclude: ['**/some-pattern/**'], \n }\n }\n})\n```\n\nExample:\n```text\nimport { configDefaults, defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n dir: './frontend/tests', \n },\n})\n```\n\nExample:\n```text\nimport { configDefaults, defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n exclude: [\n ...configDefaults.exclude,\n '**/dist/**', \n '**/cypress/**', \n '**/.{idea,git,cache,output,temp}/**', \n '**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*'\n ],\n },\n})\n```\n\nExample:\n```text\nconst cart = {\n Apples: class Apples {\n getApples() {\n return 42\n }\n }\n}\n\nconst Spy = vi.spyOn(cart, 'Apples')\n .mockImplementation(() => ({ getApples: () => 0 })) \n // with a function keyword\n .mockImplementation(function () {\n this.getApples = () => 0\n })\n // with a custom class\n .mockImplementation(class MockApples {\n getApples() {\n return 0\n }\n })\n\nconst mock = new Spy()\n```\n\nExample:\n```text\nimport { AutoMockedClass } from './example.js'\nconst instance1 = new AutoMockedClass()\nconst instance2 = new AutoMockedClass()\n\ninstance1.method.mockReturnValue(42)\n\nexpect(instance1.method()).toBe(42)\nexpect(instance2.method()).toBe(undefined)\n\nexpect(AutoMockedClass.prototype.method).toHaveBeenCalledTimes(2)\n\ninstance1.method.mockReset()\nAutoMockedClass.prototype.method.mockReturnValue(100)\n\nexpect(instance1.method()).toBe(100)\nexpect(instance2.method()).toBe(100)\n\nexpect(AutoMockedClass.prototype.method).toHaveBeenCalledTimes(4)\n```\n\nExample:\n```text\n# In Vitest v3 and below this command would ignore \"math.test.ts\" filename filter.\n# In Vitest v4 the math.test.ts will run automatically.\n$ vitest --standalone math.test.ts\n```\n\nExample:\n```text\n{\n \"scripts\": {\n \"test:dev\": \"vitest --standalone\"\n }\n}\n```\n\nExample:\n```text\n# Start Vitest in standalone mode, without running any files on start\n$ pnpm run test:dev\n\n# Run math.test.ts immediately\n$ pnpm run test:dev math.test.ts\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n workspace: './vitest.workspace.js', \n projects: [ \n './packages/*', \n { \n test: { \n name: 'unit', \n }, \n }, \n ] \n }\n})\n```\n\nExample:\n```text\nimport { defineWorkspace } from 'vitest/config'\n\nexport default defineWorkspace([ \n './packages/*', \n { \n test: { \n name: 'unit', \n }, \n } \n])\n```\n\nExample:\n```text\nimport { playwright } from '@vitest/browser-playwright'\n\nexport default defineConfig({\n test: {\n browser: {\n provider: 'playwright', \n provider: playwright({ \n launchOptions: { \n slowMo: 100, \n }, \n }), \n instances: [\n {\n browser: 'chromium',\n launch: { \n slowMo: 100, \n }, \n },\n ],\n },\n },\n})\n```\n\nExample:\n```text\nimport { page } from '@vitest/browser/context'\nimport { page } from 'vitest/browser'\n\ntest('example', async () => {\n await page.getByRole('button').click()\n})\n```\n\nExample:\n```text\nimport { getElementError } from '@vitest/browser/utils'\nimport { utils } from 'vitest/browser'\nconst { getElementError } = utils\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n poolOptions: { \n forks: { \n execArgv: ['--expose-gc'], \n isolate: false, \n singleFork: true, \n }, \n vmThreads: { \n memoryLimit: '300Mb'\n }, \n }, \n execArgv: ['--expose-gc'], \n isolate: false, \n maxWorkers: 1, \n vmMemoryLimit: '300Mb', \n }\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n // Non-isolated unit tests\n name: 'Unit tests',\n isolate: false,\n exclude: ['**.integration.test.ts'],\n },\n {\n // Isolated integration tests\n name: 'Integration tests',\n include: ['**.integration.test.ts'],\n },\n ],\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n name: 'Parallel',\n exclude: ['**.sequential.test.ts'],\n },\n {\n name: 'Sequential',\n include: ['**.sequential.test.ts'],\n fileParallelism: false,\n },\n ],\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n name: 'Production env',\n execArgv: ['--env-file=.env.prod']\n },\n {\n name: 'Staging env',\n execArgv: ['--env-file=.env.staging']\n },\n ],\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['default', { summary: false }]\n ]\n }\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['verbose'], \n reporters: ['tree'], \n }\n})\n```\n\nExample:\n```text\n// before Vitest 4.0\nexports[`custom element with shadow root 1`] = `\n\"<body>\n <div>\n <custom-element />\n </div>\n</body>\"\n`\n\n// after Vitest 4.0\nexports[`custom element with shadow root 1`] = `\n\"<body>\n <div>\n <custom-element>\n #shadow-root\n <span\n class=\"some-name\"\n data-test-id=\"33\"\n id=\"5\"\n >\n hello\n </span>\n </custom-element>\n </div>\n</body>\"\n`\n```\n\nExample:\n```text\ntest('example', () => { /* ... */ }, { retry: 2 }) \ntest('example', { retry: 2 }, () => { /* ... */ })\n```\n\nExample:\n```text\ntest('example', () => { /* ... */ }, 1000) // ✅\n```\n\nExample:\n```text\nconst mock = vi.fn()\nconst state = mock.mock\nmock.mockClear()\n\nexpect(state).toBe(mock.mock) // fails in Jest\n```\n\nExample:\n```text\njest.mock('./some-path', () => 'hello') \nvi.mock('./some-path', () => ({ \n default: 'hello', \n}))\n```\n\nExample:\n```text\nconst { cloneDeep } = jest.requireActual('lodash/cloneDeep') \nconst { cloneDeep } = await vi.importActual('lodash/cloneDeep')\n```\n\nExample:\n```text\nserver.deps.inline: [\"lib-name\"]\n```\n\nExample:\n```text\n- `${describeTitle} ${testTitle}`\n+ `${describeTitle} > ${testTitle}`\n```\n\nExample:\n```text\nit('should work', (done) => { \nit('should work', () => new Promise(done => { \n // ...\n done()\n}) \n}))\n```\n\nExample:\n```text\nbeforeEach(() => setActivePinia(createTestingPinia())) \nbeforeEach(() => { setActivePinia(createTestingPinia()) })\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n sequence: { \n hooks: 'list', \n } \n }\n})\n```\n\nExample:\n```text\nlet fn: jest.Mock<(name: string) => number> \nimport type { Mock } from 'vitest'\nlet fn: Mock<(name: string) => number>\n```\n\nExample:\n```text\njest.setTimeout(5_000) \nvi.setConfig({ testTimeout: 5_000 })\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n snapshotSerializers: ['jest-serializer-vue']\n }\n})\n```\n\nExample:\n```text\nconst { toMatchSnapshot } = require('jest-snapshot') \nimport { Snapshots } from 'vitest'\nconst { toMatchSnapshot } = Snapshots \n\nexpect.extend({\n toMatchTrimmedSnapshot(received: string, length: number) {\n return toMatchSnapshot.call(this, received.slice(0, length))\n },\n})\n```\n\nExample:\n```text\nconst { toMatchInlineSnapshot } = require('jest-snapshot') \nimport { Snapshots } from 'vitest'\nconst { toMatchInlineSnapshot } = Snapshots \n\nexpect.extend({\n toMatchTrimmedInlineSnapshot(received: string, inlineSnapshot?: string) {\n return toMatchInlineSnapshot.call(this, received.slice(0, 10), inlineSnapshot)\n },\n})\n```\n\nExample:\n```text\n// Mocha\ndescribe('suite', () => {\n before(() => { /* setup */ })\n after(() => { /* teardown */ })\n beforeEach(() => { /* setup */ })\n afterEach(() => { /* teardown */ })\n\n it('test', () => {\n // test code\n })\n})\n\n// Vitest - same structure works!\nimport { afterAll, afterEach, beforeAll, beforeEach, describe, it } from 'vitest'\n\ndescribe('suite', () => {\n beforeAll(() => { /* setup */ })\n afterAll(() => { /* teardown */ })\n beforeEach(() => { /* setup */ })\n afterEach(() => { /* teardown */ })\n\n it('test', () => {\n // test code\n })\n})\n```\n\nExample:\n```text\n// Both Mocha+Chai and Vitest\nimport { expect } from 'vitest' // or 'chai' in Mocha\n\nexpect(value).to.equal(42)\nexpect(value).to.be.true\nexpect(array).to.have.lengthOf(3)\nexpect(obj).to.have.property('key')\n```\n\nExample:\n```text\n// Before (Mocha + Chai + Sinon)\nconst sinon = require('sinon')\nconst chai = require('chai')\nconst sinonChai = require('sinon-chai')\nchai.use(sinonChai)\n\nconst spy = sinon.spy(obj, 'method')\nobj.method('arg1', 'arg2')\n\nexpect(spy).to.have.been.called\nexpect(spy).to.have.been.calledOnce\nexpect(spy).to.have.been.calledWith('arg1', 'arg2')\n\n// After (Vitest) - same assertion syntax!\nimport { expect, vi } from 'vitest'\n\nconst spy = vi.spyOn(obj, 'method')\nobj.method('arg1', 'arg2')\n\nexpect(spy).to.have.been.called\nexpect(spy).to.have.been.calledOnce\nexpect(spy).to.have.been.calledWith('arg1', 'arg2')\n```\n\nExample:\n```text\n// Sinon\nconst sinon = require('sinon')\nconst spy = sinon.spy()\nconst stub = sinon.stub(obj, 'method')\nconst mock = sinon.mock(obj)\n\n// Vitest\nimport { vi } from 'vitest'\nconst spy = vi.fn()\nconst stub = vi.spyOn(obj, 'method')\n// Vitest doesn't have \"mocks\" - use spies instead\n```\n\nExample:\n```text\n// Sinon\nstub.returns(42)\nstub.onFirstCall().returns(1)\nstub.onSecondCall().returns(2)\n\n// Vitest\nstub.mockReturnValue(42)\nstub.mockReturnValueOnce(1)\nstub.mockReturnValueOnce(2)\n```\n\nExample:\n```text\n// Sinon\nstub.callsFake(arg => arg * 2)\n\n// Vitest\nstub.mockImplementation(arg => arg * 2)\n```\n\nExample:\n```text\n// Sinon\nspy.restore()\nsinon.restore() // restore all\n\n// Vitest\nspy.mockRestore()\nvi.restoreAllMocks() // restore all\n```\n\nExample:\n```text\n// Sinon\nconst clock = sinon.useFakeTimers()\nclock.tick(1000)\nclock.restore()\n\n// Vitest\nimport { vi } from 'vitest'\nvi.useFakeTimers()\nvi.advanceTimersByTime(1000)\nvi.useRealTimers()\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.936Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":44,"totalLines":600,"estimatedTokens":2694}}51{"id":"doc-reporters_guide_vitest-24360561","source":"documentation","title":"Reporters | Guide | Vitest","url":"https://vitest.dev/guide/reporters","text":"Example:\n```text\nnpx vitest --reporter=verbose\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n reporters: ['verbose']\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n 'default',\n ['junit', { suiteName: 'UI tests' }]\n ],\n },\n})\n```\n\nExample:\n```text\nnpx vitest --reporter=json --outputFile=./test-output.json\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['json'],\n outputFile: './test-output.json'\n },\n})\n```\n\nExample:\n```text\nnpx vitest --reporter=json --reporter=default\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['json', 'default'],\n outputFile: './test-output.json'\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['junit', 'json', 'verbose'],\n outputFile: {\n junit: './junit-report.xml',\n json: './json-report.json',\n },\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['default', { summary: false }]\n ]\n },\n})\n```\n\nExample:\n```text\n✓ test/example-1.test.ts (5 tests | 1 skipped) 306ms\n ✓ test/example-2.test.ts (5 tests | 1 skipped) 307ms\n\n ❯ test/example-3.test.ts 3/5\n ❯ test/example-4.test.ts 1/5\n\n Test Files 2 passed (4)\n Tests 10 passed | 3 skipped (65)\n Start at 11:01:36\n Duration 2.00s\n```\n\nExample:\n```text\n✓ test/example-1.test.ts (5 tests | 1 skipped) 306ms\n ✓ test/example-2.test.ts (5 tests | 1 skipped) 307ms\n ✓ test/example-3.test.ts (5 tests | 1 skipped) 307ms\n ✓ test/example-4.test.ts (5 tests | 1 skipped) 307ms\n\n Test Files 4 passed (4)\n Tests 16 passed | 4 skipped (20)\n Start at 12:34:32\n Duration 1.26s (transform 35ms, setup 1ms, collect 90ms, tests 1.47s, environment 0ms, prepare 267ms)\n```\n\nExample:\n```text\n✓ __tests__/file1.test.ts (2) 725ms\n ✓ first test file (2) 725ms\n ✓ 2 + 2 should equal 4\n ✓ 4 - 2 should equal 2\n\n Test Files 1 passed (1)\n Tests 2 passed (2)\n Start at 12:34:32\n Duration 1.26s (transform 35ms, setup 1ms, collect 90ms, tests 1.47s, environment 0ms, prepare 267ms)\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['verbose', { summary: false }]\n ]\n },\n})\n```\n\nExample:\n```text\n✓ __tests__/file1.test.ts > first test file > 2 + 2 should equal 4 1ms\n✓ __tests__/file1.test.ts > first test file > 4 - 2 should equal 2 1ms\n✓ __tests__/file2.test.ts > second test file > 1 + 1 should equal 2 1ms\n✓ __tests__/file2.test.ts > second test file > 2 - 1 should equal 1 1ms\n\n Test Files 2 passed (2)\n Tests 4 passed (4)\n Start at 12:34:32\n Duration 1.26s (transform 35ms, setup 1ms, collect 90ms, tests 1.47s, environment 0ms, prepare 267ms)\n```\n\nExample:\n```text\n✓ __tests__/file1.test.ts:2:1 > first test file > 2 + 2 should equal 4 1ms\n✓ __tests__/file1.test.ts:3:1 > first test file > 4 - 2 should equal 2 1ms\n✓ __tests__/file2.test.ts:2:1 > second test file > 1 + 1 should equal 2 1ms\n✓ __tests__/file2.test.ts:3:1 > second test file > 2 - 1 should equal 1 1ms\n\n Test Files 2 passed (2)\n Tests 4 passed (4)\n Start at 12:34:32\n Duration 1.26s (transform 35ms, setup 1ms, collect 90ms, tests 1.47s, environment 0ms, prepare 267ms)\n```\n\nExample:\n```text\nnpx vitest --reporter=tree\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['tree', { summary: false }]\n ]\n },\n})\n```\n\nExample:\n```text\n✓ __tests__/example-1.test.ts (2) 725ms\n ✓ first test file (2) 725ms\n ✓ 2 + 2 should equal 4\n ✓ 4 - 2 should equal 2\n\n ❯ test/example-2.test.ts 3/5\n ↳ should run longer than three seconds 1.57s\n ❯ test/example-3.test.ts 1/5\n\n Test Files 2 passed (4)\n Tests 10 passed | 3 skipped (65)\n Start at 11:01:36\n Duration 2.00s\n```\n\nExample:\n```text\n✓ __tests__/file1.test.ts (2) 725ms\n ✓ first test file (2) 725ms\n ✓ 2 + 2 should equal 4\n ✓ 4 - 2 should equal 2\n✓ __tests__/file2.test.ts (2) 746ms\n ✓ second test file (2) 746ms\n ✓ 1 + 1 should equal 2\n ✓ 2 - 1 should equal 1\n\n Test Files 2 passed (2)\n Tests 4 passed (4)\n Start at 12:34:32\n Duration 1.26s (transform 35ms, setup 1ms, collect 90ms, tests 1.47s, environment 0ms, prepare 267ms)\n```\n\nExample:\n```text\nnpx vitest --reporter=dot\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['dot']\n },\n})\n```\n\nExample:\n```text\n....\n\n Test Files 2 passed (2)\n Tests 4 passed (4)\n Start at 12:34:32\n Duration 1.26s (transform 35ms, setup 1ms, collect 90ms, tests 1.47s, environment 0ms, prepare 267ms)\n```\n\nExample:\n```text\nnpx vitest --reporter=junit\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['junit']\n },\n})\n```\n\nExample:\n```text\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<testsuites name=\"vitest tests\" tests=\"2\" failures=\"1\" errors=\"0\" time=\"0.503\">\n <testsuite name=\"__tests__/test-file-1.test.ts\" timestamp=\"2023-10-19T17:41:58.580Z\" hostname=\"My-Computer.local\" tests=\"2\" failures=\"1\" errors=\"0\" skipped=\"0\" time=\"0.013\">\n <testcase classname=\"__tests__/test-file-1.test.ts\" name=\"first test file > 2 + 2 should equal 4\" time=\"0.01\">\n <failure message=\"expected 5 to be 4 // Object.is equality\" type=\"AssertionError\">\nAssertionError: expected 5 to be 4 // Object.is equality\n ❯ __tests__/test-file-1.test.ts:20:28\n </failure>\n </testcase>\n <testcase classname=\"__tests__/test-file-1.test.ts\" name=\"first test file > 4 - 2 should equal 2\" time=\"0\">\n </testcase>\n </testsuite>\n</testsuites>\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['junit', { suiteName: 'custom suite name', classnameTemplate: 'filename:{filename} - filepath:{filepath}' }]\n ]\n },\n})\n```\n\nExample:\n```text\nnpx vitest --reporter=json\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['json']\n },\n})\n```\n\nExample:\n```text\n{\n \"numTotalTestSuites\": 4,\n \"numPassedTestSuites\": 2,\n \"numFailedTestSuites\": 1,\n \"numPendingTestSuites\": 1,\n \"numTotalTests\": 4,\n \"numPassedTests\": 1,\n \"numFailedTests\": 1,\n \"numPendingTests\": 1,\n \"numTodoTests\": 1,\n \"startTime\": 1697737019307,\n \"success\": false,\n \"testResults\": [\n {\n \"assertionResults\": [\n {\n \"ancestorTitles\": [\n \"\",\n \"first test file\"\n ],\n \"fullName\": \" first test file 2 + 2 should equal 4\",\n \"status\": \"failed\",\n \"title\": \"2 + 2 should equal 4\",\n \"duration\": 9,\n \"failureMessages\": [\n \"expected 5 to be 4 // Object.is equality\"\n ],\n \"location\": {\n \"line\": 20,\n \"column\": 28\n },\n \"meta\": {}\n }\n ],\n \"startTime\": 1697737019787,\n \"endTime\": 1697737019797,\n \"status\": \"failed\",\n \"message\": \"\",\n \"name\": \"/root-directory/__tests__/test-file-1.test.ts\"\n }\n ],\n \"coverageMap\": {}\n}\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['json', {\n filterMeta: (key, value) => key !== 'internalField',\n }]\n ]\n },\n})\n```\n\nExample:\n```text\nnpx vitest --reporter=html\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['html']\n },\n})\n```\n\nExample:\n```text\nnpx vitest --reporter=tap\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['tap']\n },\n})\n```\n\nExample:\n```text\nTAP version 13\n1..1\nnot ok 1 - __tests__/test-file-1.test.ts # time=14.00ms {\n 1..1\n not ok 1 - first test file # time=13.00ms {\n 1..2\n not ok 1 - 2 + 2 should equal 4 # time=11.00ms\n ---\n error:\n name: \"AssertionError\"\n message: \"expected 5 to be 4 // Object.is equality\"\n at: \"/root-directory/__tests__/test-file-1.test.ts:20:28\"\n actual: \"5\"\n expected: \"4\"\n ...\n ok 2 - 4 - 2 should equal 2 # time=1.00ms\n }\n}\n```\n\nExample:\n```text\nnpx vitest --reporter=tap-flat\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['tap-flat']\n },\n})\n```\n\nExample:\n```text\nTAP version 13\n1..2\nnot ok 1 - __tests__/test-file-1.test.ts > first test file > 2 + 2 should equal 4 # time=11.00ms\n ---\n error:\n name: \"AssertionError\"\n message: \"expected 5 to be 4 // Object.is equality\"\n at: \"/root-directory/__tests__/test-file-1.test.ts:20:28\"\n actual: \"5\"\n expected: \"4\"\n ...\nok 2 - __tests__/test-file-1.test.ts > first test file > 4 - 2 should equal 2 # time=0.00ms\n```\n\nExample:\n```text\nnpx vitest --reporter=hanging-process\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['hanging-process']\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: process.env.GITHUB_ACTIONS === 'true' ? ['dot', 'github-actions'] : ['dot'],\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: process.env.GITHUB_ACTIONS === 'true'\n ? [\n 'default',\n ['github-actions', { onWritePath(path) {\n return path.replace(/^\\/app\\//, `${process.env.GITHUB_WORKSPACE}/`)\n } }],\n ]\n : ['default'],\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['github-actions', { displayAnnotations: false }],\n ],\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['github-actions', {\n jobSummary: {\n outputPath: '/home/runner/jobs/summary/step',\n },\n }],\n ],\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['github-actions', { jobSummary: { enabled: false } }],\n ],\n },\n})\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: [\n ['github-actions', {\n jobSummary: {\n fileLinks: {\n repository: 'owner/repo',\n commitHash: 'abcdefg',\n workspacePath: '/home/runner/work/repo/',\n },\n },\n }],\n ],\n },\n})\n```\n\nExample:\n```text\nnpx vitest --reporter=minimal\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['minimal']\n },\n})\n```\n\nExample:\n```text\nnpx vitest --reporter=blob --outputFile=reports/blob-1.json\n```\n\nExample:\n```text\nnpx vitest --merge-reports=reports --reporter=json --reporter=default\n```\n\nExample:\n```text\nnpx vitest --reporter=some-published-vitest-reporter\n```\n\nExample:\n```text\nexport default defineConfig({\n test: {\n reporters: ['some-published-vitest-reporter']\n },\n})\n```\n\nExample:\n```text\nnpx vitest --reporter=./path/to/reporter.ts\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.939Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":53,"totalLines":568,"estimatedTokens":2686}}52{"id":"doc-extending_reporters_advanced_vitest-84127a6a","source":"documentation","title":"Extending Reporters advanced | Vitest","url":"https://vitest.dev/guide/advanced/reporters","text":"Example:\n```text\nimport { DefaultReporter } from 'vitest/node'\n\nexport default class MyDefaultReporter extends DefaultReporter {\n // do something\n}\n```\n\nExample:\n```text\nimport type { Reporter } from 'vitest/node'\n\nexport default class CustomReporter implements Reporter {\n onTestModuleCollected(testModule) {\n console.log(testModule.moduleId, 'is finished')\n\n for (const test of testModule.children.allTests()) {\n console.log(test.name, test.result().state)\n }\n }\n}\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\nimport CustomReporter from './custom-reporter.js'\n\nexport default defineConfig({\n test: {\n reporters: [new CustomReporter()],\n },\n})\n```\n\nExample:\n```text\nimport type { Reporter, TestModule } from 'vitest/node'\n\nclass MyReporter implements Reporter {\n onTestRunEnd(testModules: ReadonlyArray<TestModule>) {\n for (const testModule of testModules) {\n for (const task of testModule.children) {\n console.log('test run end', task.type, task.fullName)\n }\n }\n }\n}\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.940Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":4,"totalLines":52,"estimatedTokens":264}}53{"id":"doc-improving_performance_vitest-ee1f499a","source":"documentation","title":"Improving Performance | Vitest","url":"https://vitest.dev/guide/improving-performance","text":"Example:\n```text\nvitest --no-isolate\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n isolate: false,\n },\n})\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n projects: [\n {\n test: {\n name: 'Isolated',\n isolate: true, // (default value)\n exclude: ['**.non-isolated.test.ts'],\n },\n },\n {\n test: {\n name: 'Non-isolated',\n isolate: false,\n include: ['**.non-isolated.test.ts'],\n },\n },\n ],\n },\n})\n```\n\nExample:\n```text\nvitest --no-file-parallelism\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n fileParallelism: false,\n },\n})\n```\n\nExample:\n```text\n# the first run\nDuration 8.75s (transform 4.02s, setup 629ms, import 5.52s, tests 2.52s, environment 0ms, prepare 3ms)\n\n# the second run\nDuration 5.90s (transform 842ms, setup 543ms, import 2.35s, tests 2.94s, environment 0ms, prepare 3ms)\n```\n\nExample:\n```text\nvitest --pool=threads\n```\n\nExample:\n```text\nimport { defineConfig } from 'vitest/config'\n\nexport default defineConfig({\n test: {\n pool: 'threads',\n },\n})\n```\n\nExample:\n```text\nvitest run --reporter=blob --shard=1/3 # 1st machine\nvitest run --reporter=blob --shard=2/3 # 2nd machine\nvitest run --reporter=blob --shard=3/3 # 3rd machine\n```\n\nExample:\n```text\nvitest run --merge-reports\n```\n\nExample:\n```text\n# Inspired from https://playwright.dev/docs/test-sharding\nname: Tests\non:\n push:\n branches:\n - main\njobs:\n tests:\n runs-on: ubuntu-latest\n strategy:\n matrix:\n shardIndex: [1, 2, 3, 4]\n shardTotal: [4]\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-node@v4\n with:\n node-version: 20\n\n - name: Install pnpm\n uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0\n\n - name: Install dependencies\n run: pnpm i\n\n - name: Run tests\n run: pnpm run test --reporter=blob --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }}\n\n - name: Upload blob report to GitHub Actions Artifacts\n if: ${{ !cancelled() }}\n uses: actions/upload-artifact@v4\n with:\n name: blob-report-${{ matrix.shardIndex }}\n path: .vitest-reports/*\n include-hidden-files: true\n retention-days: 1\n\n - name: Upload attachments to GitHub Actions Artifacts\n if: ${{ !cancelled() }}\n uses: actions/upload-artifact@v4\n with:\n name: blob-attachments-${{ matrix.shardIndex }}\n path: .vitest-attachments/**\n include-hidden-files: true\n retention-days: 1\n\n merge-reports:\n if: ${{ !cancelled() }}\n needs: [tests]\n\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - uses: actions/setup-node@v4\n with:\n node-version: 20\n\n - name: Install pnpm\n uses: pnpm/action-setup@a7487c7e89a18df4991f7f222e4898a00d66ddda # v4.1.0\n\n - name: Install dependencies\n run: pnpm i\n\n - name: Download blob reports from GitHub Actions Artifacts\n uses: actions/download-artifact@v4\n with:\n path: .vitest-reports\n pattern: blob-report-*\n merge-multiple: true\n\n - name: Download attachments from GitHub Actions Artifacts\n uses: actions/download-artifact@v4\n with:\n path: .vitest-attachments\n pattern: blob-attachments-*\n merge-multiple: true\n\n - name: Merge reports\n run: npx vitest --merge-reports\n```\n\nExample:\n```text\n# Example for splitting tests on 32 CPU to 4 shards.\n# As each process needs 1 main thread, there's 7 threads for test runners (1+7)*4 = 32\n# Use VITEST_MAX_WORKERS:\nVITEST_MAX_WORKERS=7 vitest run --reporter=blob --shard=1/4 & \\\nVITEST_MAX_WORKERS=7 vitest run --reporter=blob --shard=2/4 & \\\nVITEST_MAX_WORKERS=7 vitest run --reporter=blob --shard=3/4 & \\\nVITEST_MAX_WORKERS=7 vitest run --reporter=blob --shard=4/4 & \\\nwait # https://man7.org/linux/man-pages/man2/waitpid.2.html\n\nvitest run --merge-reports\n```\n\n<|endofdoc|>","metadata":{"transformedAt":"2026-08-18T15:21:53.940Z","totalSectionsIncluded":0,"totalCodeBlocksIncluded":12,"totalLines":193,"estimatedTokens":1057}}54 