agent-docs 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.cursor/plans/OPTIMISE.md +379 -0
  2. package/.cursor/plans/VERSIONING.md +207 -0
  3. package/.cursor/rules/IMPORTANT.mdc +97 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +13 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +17 -0
  6. package/.github/dependabot.yml +38 -0
  7. package/.github/pull_request_template.md +10 -0
  8. package/.github/workflows/format.yml +35 -0
  9. package/CODE_OF_CONDUCT.md +64 -0
  10. package/CONTRIBUTING.md +52 -0
  11. package/LICENSE.md +20 -0
  12. package/PLAN.md +707 -0
  13. package/README.md +133 -0
  14. package/SECURITY.md +21 -0
  15. package/docs/APEXANNOTATIONS.md +472 -0
  16. package/docs/APEXDOC.md +198 -0
  17. package/docs/CML.md +877 -0
  18. package/docs/CODEANALYZER.md +435 -0
  19. package/docs/CONTEXTDEFINITIONS.md +617 -0
  20. package/docs/ESLINT.md +827 -0
  21. package/docs/ESLINTJSDOC.md +520 -0
  22. package/docs/FIELDSERVICE.md +4452 -0
  23. package/docs/GRAPHBINARY.md +208 -0
  24. package/docs/GRAPHENGINE.md +616 -0
  25. package/docs/GRAPHML.md +337 -0
  26. package/docs/GRAPHSON.md +302 -0
  27. package/docs/GREMLIN.md +490 -0
  28. package/docs/GRYO.md +232 -0
  29. package/docs/HUSKY.md +106 -0
  30. package/docs/JEST.md +387 -0
  31. package/docs/JORJE.md +537 -0
  32. package/docs/JSDOC.md +621 -0
  33. package/docs/PMD.md +910 -0
  34. package/docs/PNPM.md +409 -0
  35. package/docs/PRETTIER.md +716 -0
  36. package/docs/PRETTIERAPEX.md +874 -0
  37. package/docs/REVENUETRANSACTIONMANAGEMENT.md +887 -0
  38. package/docs/TINKERPOP.md +252 -0
  39. package/docs/VITEST.md +706 -0
  40. package/docs/VSCODE.md +231 -0
  41. package/docs/XPATH31.md +213 -0
  42. package/package.json +32 -0
  43. package/postinstall.mjs +51 -0
  44. package/prettier.config.js +18 -0
package/docs/VITEST.md ADDED
@@ -0,0 +1,706 @@
1
+ # VITEST (Vite-native test framework)
2
+
3
+ > **Version**: 1.0.0
4
+
5
+ Requires: Vite≥6.0.0, Node≥20.0.0
6
+
7
+ ## CORE FEATURES
8
+
9
+ - Shared Vite config/transformers/resolvers/plugins
10
+ - Watch mode: auto in dev, run in CI (`process.env.CI`); `vitest watch|run`;
11
+ `--standalone` keeps running, waits for changes
12
+ - ES Module/TypeScript/JSX/PostCSS out-of-box
13
+ - Parallelism: `node:child_process` default; `--pool=threads` uses
14
+ `node:worker_threads` (faster, some pkg incompatible); `--no-isolate` disables
15
+ env isolation
16
+ - `.concurrent` runs tests parallel; `.skip`/`.only`/`.todo` modifiers;
17
+ concurrent tests require local `expect` from Test Context
18
+ - Jest-compatible snapshots
19
+ - Chai built-in + Jest `expect` API; `test.globals=true` for better 3rd-party
20
+ matcher compat
21
+ - Tinyspy built-in for mocking via `vi`; jsdom/happy-dom for DOM (install
22
+ separately)
23
+ - Coverage: v8 (native) or istanbul
24
+ - In-source testing via `import.meta.vitest`
25
+ - Benchmarking (experimental) via Tinybench
26
+ - Type testing (experimental) via expect-type
27
+ - Sharding: `--shard`+`--reporter=blob`, merge via `--merge-reports`
28
+ - Env vars: auto-loads `VITE_`-prefixed from .env; use `loadEnv` from vite for
29
+ all
30
+ - Unhandled errors: caught/reported by default; disable with
31
+ `dangerouslyIgnoreUnhandledErrors`
32
+
33
+ ## INSTALL
34
+
35
+ ```bash
36
+ npm i -D vitest
37
+ ```
38
+
39
+ ## BASIC
40
+
41
+ ```ts
42
+ import { test, expect } from 'vitest';
43
+ test('adds', () => expect(1 + 2).toBe(3));
44
+ ```
45
+
46
+ Run: `vitest` (watch) | `vitest run` (single)
47
+
48
+ ## CONFIG
49
+
50
+ File: `vitest.config.ts` or `test` in `vite.config.ts`
51
+
52
+ ```ts
53
+ import { defineConfig } from 'vitest/config';
54
+ export default defineConfig({
55
+ test: {
56
+ /* opts */
57
+ },
58
+ });
59
+ ```
60
+
61
+ ### OPTIONS (format: `name: type` [default] CLI: flags | notes)
62
+
63
+ **Core**
64
+
65
+ - `include: string[]` ['\*_/_.{test,spec}.?(c|m)[jt]s?(x)'] CLI:
66
+ `vitest [...patterns]` | tinyglobby, relative to root
67
+ - `exclude: string[]` ['**/node_modules/**','**/.git/**'] CLI: `--exclude`
68
+ (additive) | use configDefaults to extend
69
+ - `root: string` [process.cwd()] CLI: `-r, --root`
70
+ - `name: string|{label,color?}` | auto-assigns from package.json or folder; must
71
+ be unique
72
+ - `testTimeout: number` [5000, 15000 if browser] CLI: `--test-timeout`;
73
+ 0=disable
74
+ - `setupFiles: string|string[]` | runs before each test file; rerun triggers on
75
+ edit
76
+ - `globalSetup: string|string[]` | exports setup/teardown; runs only if tests
77
+ exist; `provide` for data passing
78
+ - `globals: boolean` [false] CLI: `--globals` | add `vitest/globals` to tsconfig
79
+ types
80
+ - `passWithNoTests: boolean` [false] CLI: `--passWithNoTests`
81
+ - `allowOnly: boolean` [!process.env.CI] CLI: `--allowOnly`
82
+
83
+ **Environment**
84
+
85
+ - `environment: 'node'|'jsdom'|'happy-dom'|'edge-runtime'|string` [node] CLI:
86
+ `--environment` | per-file via `@vitest-environment` docblock
87
+ - `environmentOptions: Record<string,unknown>` | keyed by env name (jsdom,
88
+ happyDOM)
89
+
90
+ **Coverage** (CLI prefix: `--coverage.`)
91
+
92
+ - `provider: 'v8'|'istanbul'|'custom'` [v8]
93
+ - `enabled: boolean` [false]
94
+ - `include/exclude: string[]` | glob patterns
95
+ - `clean: boolean` [true] | clear before run
96
+ - `cleanOnRerun: boolean` [true]
97
+ - `reportsDirectory: string` ['./coverage']
98
+ - `reporter: string|string[]|[string,{}][]` [['text','html','clover','json']]
99
+ - `reportOnFailure: boolean` [false]
100
+ - `allowExternal: boolean` [false]
101
+ - `excludeAfterRemap: boolean` [false]
102
+ - `skipFull: boolean` [false]
103
+ - `thresholds: {lines,functions,branches,statements: number, perFile?: boolean, autoUpdate?: boolean|fn, 100?: boolean, [glob]: object}`
104
+ - `ignoreClassMethods: string[]` []
105
+ - `watermarks: {statements,functions,branches,lines: [low,high]}` [[50,80]...]
106
+ - `processingConcurrency: number` [min(20, cpus)]
107
+ - `customProviderModule: string` | for custom provider
108
+
109
+ **Pools**
110
+
111
+ - `pool: 'threads'|'forks'|'vmThreads'|'vmForks'` [forks] CLI: `--pool`
112
+ - `poolOptions.{threads|forks|vmThreads|vmForks}: object`
113
+ - `minThreads/maxThreads: number`
114
+ - `isolate: boolean` [true]
115
+ - `singleThread/singleFork: boolean` [false]
116
+ - `useAtomics: boolean` [false]
117
+ - `execArgv: string[]`
118
+
119
+ **Isolation & Parallelism**
120
+
121
+ - `isolate: boolean` [true] CLI: `--no-isolate`
122
+ - `fileParallelism: boolean` [true] CLI: `--no-file-parallelism`
123
+
124
+ **Reporters** CLI: `--reporter`
125
+
126
+ - Built-in: default, basic, verbose, dot, json, tap, tap-flat, junit,
127
+ hanging-process, github-actions, blob, html, tree
128
+ - `outputFile: string|Record<reporter,path>` | for json/junit/blob/html
129
+
130
+ **Sequence**
131
+
132
+ - `sequence.shuffle: boolean` [false] CLI: `--sequence.shuffle`
133
+ - `sequence.seed: number` CLI: `--sequence.seed`
134
+ - `sequence.concurrent: boolean` [false] CLI: `--sequence.concurrent`
135
+ - `sequence.hooks: 'stack'|'list'|'parallel'` [parallel]
136
+ - `sequence.setupFiles: 'list'|'parallel'` [parallel]
137
+
138
+ **Retry/Repeat**
139
+
140
+ - `retry: number` [0] CLI: `--retry`
141
+ - `repeats: number` [0] CLI: `--repeats`
142
+
143
+ **Deps**
144
+
145
+ - `deps.optimizer.{ssr|client}: {enabled,include,exclude,force}` | Vite dep
146
+ optimization
147
+ - `deps.client.transformAssets/transformCss: boolean` [true] | vmThreads/vmForks
148
+ only
149
+ - `deps.interopDefault: boolean` [true]
150
+ - `deps.moduleDirectories: string[]` ['node_modules']
151
+
152
+ **Mocking**
153
+
154
+ - `clearMocks: boolean` [false] | vi.clearAllMocks before each
155
+ - `mockReset: boolean` [false] | vi.resetAllMocks before each
156
+ - `restoreMocks: boolean` [false] | vi.restoreAllMocks before each
157
+ - `unstubGlobals: boolean` [false]
158
+ - `unstubEnvs: boolean` [false]
159
+
160
+ **Snapshots**
161
+
162
+ - `snapshotFormat: PrettyFormatOptions`
163
+ - `resolveSnapshotPath: (testPath,ext,ctx)=>string`
164
+ - `snapshotSerializers: string[]`
165
+ - `snapshotEnvironment: string` | custom impl
166
+ - `expandSnapshotDiff: boolean` [false] CLI: `--expandSnapshotDiff`
167
+ - `update: boolean` [false] CLI: `-u, --update`
168
+
169
+ **Typecheck** (experimental)
170
+
171
+ - `typecheck.enabled: boolean` [false] CLI: `--typecheck`
172
+ - `typecheck.only: boolean` [false]
173
+ - `typecheck.checker: 'tsc'|'vue-tsc'|string` [tsc]
174
+ - `typecheck.include/exclude: string[]`
175
+ - `typecheck.allowJs: boolean` [false]
176
+ - `typecheck.ignoreSourceErrors: boolean` [false]
177
+ - `typecheck.tsconfig: string`
178
+
179
+ **Fake Timers** (`fakeTimers` for vi.useFakeTimers)
180
+
181
+ - `now: number|Date` [Date.now()]
182
+ - `toFake: string[]` | methods to fake; nextTick not supported in forks pool
183
+ - `loopLimit: number` [10000]
184
+ - `shouldAdvanceTime: boolean` [false]
185
+ - `advanceTimeDelta: number` [20]
186
+ - `shouldClearNativeTimers: boolean` [true]
187
+
188
+ **Expect**
189
+
190
+ - `expect.requireAssertions: boolean` [false]
191
+ - `expect.poll: {interval: number, timeout: number}` [50, 1000]
192
+
193
+ **Chai**
194
+
195
+ - `chaiConfig: {includeStack: boolean, showDiff: boolean, truncateThreshold: number}`
196
+ [false,true,40]
197
+
198
+ **Misc**
199
+
200
+ - `alias: Record<string,string>|Array<{find,replacement,customResolver?}>` |
201
+ merged with resolve.alias
202
+ - `css: boolean|{include?,exclude?,modules?}` [false] | process CSS
203
+ - `logHeapUsage: boolean` [false] CLI: `--logHeapUsage`
204
+ - `dangerouslyIgnoreUnhandledErrors: boolean` [false]
205
+ - `forceRerunTriggers: string[]`
206
+ ['**/package.json/**','**/vitest.config.*/**','**/vite.config.*/**']
207
+ - `includeSource: string[]` [] | in-source test globs
208
+ - `server: {deps,sourcemap}` | Vite server options for tests
209
+ - `inspect/inspectBrk: boolean|string` CLI: `--inspect`, `--inspect-brk`
210
+ - `slowTestThreshold: number` [300] | highlight slow tests
211
+ - `bail: number` [0] CLI: `--bail` | stop after N failures
212
+ - `cache: {dir: string}` | cache location
213
+ - `env: Record<string,string>` | process.env vars
214
+ - `attachmentsDir: string` ['.vitest-attachments']
215
+ - `execArgv: string[]` | node args for worker
216
+
217
+ **Experimental**
218
+
219
+ - `experimental.fsModuleCache: boolean` [false] | persistent cache
220
+ - `experimental.fsModuleCachePath: string`
221
+ ['node_modules/.experimental-vitest-cache']
222
+ - `experimental.openTelemetry: {enabled,sdkPath?,browserSdkPath?}` | perf
223
+ tracing
224
+ - `experimental.printImportBreakdown: boolean` [false]
225
+
226
+ **UI**
227
+
228
+ - `ui: boolean` [false] CLI: `--ui` | requires @vitest/ui
229
+ - `api: boolean|number|{port,host,strictPort}` [false, port 51204]
230
+
231
+ ## CLI
232
+
233
+ ```
234
+ vitest [filters] [options]
235
+ vitest run # single run
236
+ vitest watch # watch mode (default in dev)
237
+ vitest bench # benchmarks
238
+ vitest init browser # setup browser mode
239
+ vitest typecheck # type tests only
240
+ vitest list # list tests without running
241
+
242
+ --config/-c <path> --root/-r <path> --project <name>
243
+ --update/-u --watch/-w --run
244
+ --reporter <name> --outputFile <path> --coverage
245
+ --globals --environment <env> --pool <type>
246
+ --browser[=name] --browser.headless --no-isolate
247
+ --no-file-parallelism --test-timeout <ms> --bail <n>
248
+ --retry <n> --repeats <n> --shard <i>/<n>
249
+ --merge-reports --changed [ref] --passWithNoTests
250
+ --sequence.shuffle --sequence.seed <n> --sequence.concurrent
251
+ --inspect-brk --logHeapUsage --clearCache
252
+ ```
253
+
254
+ ## ENVIRONMENTS
255
+
256
+ Built-in: `node` (default), `jsdom`, `happy-dom`, `edge-runtime` Per-file:
257
+ `// @vitest-environment <name>` or `/** @vitest-environment <name> */` Custom:
258
+ export `Environment` object with `{name, viteEnvironment, setup()}`
259
+
260
+ ## TEST API
261
+
262
+ ```ts
263
+ import {
264
+ describe,
265
+ test,
266
+ it,
267
+ expect,
268
+ vi,
269
+ beforeAll,
270
+ beforeEach,
271
+ afterAll,
272
+ afterEach,
273
+ } from 'vitest';
274
+ ```
275
+
276
+ ### Suites
277
+
278
+ ```ts
279
+ describe(name, fn, timeout?)
280
+ describe.skip/only/todo/skipIf(cond)/runIf(cond)/shuffle/concurrent/sequential/scoped
281
+ describe.each(table)(name, fn, timeout?) // parametrized: %s %d %i %f %j %o %# %%
282
+ ```
283
+
284
+ ### Tests
285
+
286
+ ```ts
287
+ test(name, fn, timeout?)
288
+ test.skip/only/todo/skipIf(cond)/runIf(cond)/fails/concurrent/sequential/scoped
289
+ test.each(table)(name, fn, timeout?)
290
+ test.for(cases)(name, fn, timeout?) // parallel-safe alternative to .each
291
+ test.extend({fixtures}) // fixture injection
292
+ ```
293
+
294
+ ### Hooks
295
+
296
+ ```ts
297
+ beforeAll(fn, timeout?) afterAll(fn, timeout?)
298
+ beforeEach(fn, timeout?) afterEach(fn, timeout?)
299
+ onTestFinished(fn) onTestFailed(fn)
300
+ ```
301
+
302
+ ### Test Context
303
+
304
+ ```ts
305
+ test('name', (context) => {
306
+ context.task // current test
307
+ context.expect // bound expect (required for concurrent)
308
+ context.skip() // skip dynamically
309
+ await context.annotate(msg, type?, attachment?)
310
+ })
311
+ ```
312
+
313
+ ## EXPECT API
314
+
315
+ ```ts
316
+ expect(value)
317
+ .toBe(expected) // ===
318
+ .toEqual(expected) // deep equal
319
+ .toStrictEqual(expected) // deep + type
320
+ .toBeCloseTo(num, digits?) // float
321
+ .toBeDefined() / .toBeUndefined()
322
+ .toBeNull() / .toBeTruthy() / .toBeFalsy() / .toBeNaN()
323
+ .toBeTypeOf(type) // typeof
324
+ .toBeInstanceOf(Class)
325
+ .toBeGreaterThan(num) / .toBeGreaterThanOrEqual(num)
326
+ .toBeLessThan(num) / .toBeLessThanOrEqual(num)
327
+ .toContain(item) // array/string
328
+ .toContainEqual(item) // deep
329
+ .toHaveLength(n)
330
+ .toHaveProperty(path, value?)
331
+ .toMatch(regex|string)
332
+ .toMatchObject(obj)
333
+ .toMatchSnapshot(name?) / .toMatchInlineSnapshot(snapshot?)
334
+ .toMatchFileSnapshot(path)
335
+ .toThrow(error?) / .toThrowError(msg|regex|class)
336
+ .resolves / .rejects // promise
337
+ .toHaveBeenCalled() / .toHaveBeenCalledTimes(n)
338
+ .toHaveBeenCalledWith(...args) / .toHaveBeenLastCalledWith(...args)
339
+ .toHaveBeenNthCalledWith(n, ...args)
340
+ .toHaveReturned() / .toHaveReturnedTimes(n)
341
+ .toHaveReturnedWith(value) / .toHaveLastReturnedWith(value)
342
+ .toSatisfy(predicate)
343
+
344
+ .not // negate
345
+ expect.soft(value) // continue on fail
346
+ expect.poll(fn, opts?) // retry until pass
347
+ expect.extend({matchers}) // custom matchers
348
+ expect.assertions(n) // count assertions
349
+ expect.hasAssertions() // at least one
350
+ expect.anything() // any non-null
351
+ expect.any(Class) // instanceof
352
+ expect.arrayContaining(arr)
353
+ expect.objectContaining(obj)
354
+ expect.stringContaining(str)
355
+ expect.stringMatching(regex)
356
+ expect.addSnapshotSerializer(serializer)
357
+ ```
358
+
359
+ ## VI (Mock Utilities)
360
+
361
+ ```ts
362
+ import { vi } from 'vitest'
363
+
364
+ // Functions
365
+ vi.fn(impl?) // create mock fn
366
+ vi.spyOn(obj, method, accessType?) // spy; accessType: 'get'|'set'
367
+ vi.isMockFunction(fn)
368
+
369
+ // Mock methods (on mock fn)
370
+ mock.mockImplementation(fn)
371
+ mock.mockImplementationOnce(fn)
372
+ mock.mockReturnValue(value)
373
+ mock.mockReturnValueOnce(value)
374
+ mock.mockResolvedValue(value)
375
+ mock.mockResolvedValueOnce(value)
376
+ mock.mockRejectedValue(error)
377
+ mock.mockRejectedValueOnce(error)
378
+ mock.mockClear() // clear call history
379
+ mock.mockReset() // + reset impl
380
+ mock.mockRestore() // restore original (spyOn only)
381
+ mock.getMockName() / .mockName(name)
382
+ mock.getMockImplementation()
383
+ mock.mock.calls // [[args], ...]
384
+ mock.mock.results // [{type,value}, ...]
385
+ mock.mock.instances // [this, ...]
386
+ mock.mock.contexts // [context, ...]
387
+ mock.mock.lastCall // last args
388
+
389
+ // Modules
390
+ vi.mock(path, factory?) // mock module; hoisted
391
+ vi.mock(import(path), factory?) // better IDE support
392
+ vi.mock(path, { spy: true }) // automock with spies
393
+ vi.doMock(path, factory?) // not hoisted
394
+ vi.unmock(path) / vi.doUnmock(path)
395
+ vi.importActual(path) // get original in factory
396
+ vi.importMock(path) // get mocked
397
+ vi.mocked(obj, deep?) // TS: typed mock
398
+ vi.hoisted(factory) // hoist to top
399
+
400
+ // Timers
401
+ vi.useFakeTimers(opts?) // enable fake timers
402
+ vi.useRealTimers() // restore
403
+ vi.setSystemTime(date) // set Date.now()
404
+ vi.getMockedSystemTime()
405
+ vi.getRealSystemTime()
406
+ vi.runAllTimers() // run all pending
407
+ vi.runOnlyPendingTimers()
408
+ vi.runAllTimersAsync()
409
+ vi.advanceTimersByTime(ms)
410
+ vi.advanceTimersByTimeAsync(ms)
411
+ vi.advanceTimersToNextTimer(steps?)
412
+ vi.advanceTimersToNextTimerAsync(steps?)
413
+ vi.getTimerCount()
414
+ vi.clearAllTimers()
415
+
416
+ // Globals
417
+ vi.stubGlobal(name, value) // set globalThis[name]
418
+ vi.unstubAllGlobals()
419
+ vi.stubEnv(name, value) // set import.meta.env[name]
420
+ vi.unstubAllEnvs()
421
+
422
+ // Utils
423
+ vi.spyOn(console, 'log') // common pattern
424
+ vi.resetAllMocks()
425
+ vi.restoreAllMocks()
426
+ vi.clearAllMocks()
427
+ vi.dynamicImportSettled() // wait for imports
428
+ vi.waitFor(callback, opts?) // poll until truthy
429
+ vi.waitUntil(callback, opts?) // poll until truthy
430
+ vi.setConfig(opts) // runtime config
431
+ vi.resetConfig()
432
+ ```
433
+
434
+ ## MOCKING PATTERNS
435
+
436
+ ### Module Mock
437
+
438
+ ```ts
439
+ vi.mock('./mod', () => ({ fn: vi.fn() }));
440
+ vi.mock(import('./mod'), () => ({ fn: vi.fn() })); // better types
441
+ vi.mock('./mod', { spy: true }); // automock
442
+ ```
443
+
444
+ ### Partial Mock
445
+
446
+ ```ts
447
+ vi.mock('./mod', async (importOriginal) => ({
448
+ ...(await importOriginal()),
449
+ fn: vi.fn(),
450
+ }));
451
+ ```
452
+
453
+ ### Spy on Export
454
+
455
+ ```ts
456
+ import * as mod from './mod';
457
+ vi.spyOn(mod, 'fn');
458
+ vi.spyOn(mod, 'value', 'get').mockReturnValue('x');
459
+ ```
460
+
461
+ ### Class Mock
462
+
463
+ ```ts
464
+ vi.mock('./mod', () => ({
465
+ MyClass: vi.fn(
466
+ class {
467
+ method = vi.fn();
468
+ },
469
+ ),
470
+ }));
471
+ ```
472
+
473
+ ### Timer Mock
474
+
475
+ ```ts
476
+ vi.useFakeTimers();
477
+ vi.setSystemTime(new Date('2024-01-01'));
478
+ vi.advanceTimersByTime(1000);
479
+ vi.runAllTimers();
480
+ vi.useRealTimers();
481
+ ```
482
+
483
+ ### Request Mock (MSW)
484
+
485
+ ```ts
486
+ import { setupServer } from 'msw/node';
487
+ const server = setupServer(...handlers);
488
+ beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
489
+ afterEach(() => server.resetHandlers());
490
+ afterAll(() => server.close());
491
+ ```
492
+
493
+ ### File System Mock (memfs)
494
+
495
+ ```ts
496
+ vi.mock('fs', async () => (await import('memfs')).fs);
497
+ vi.mock('fs/promises', async () => (await import('memfs')).fs.promises);
498
+ ```
499
+
500
+ ## BROWSER MODE
501
+
502
+ Runs tests in real browsers via Playwright/WebdriverIO/preview.
503
+
504
+ ### Config
505
+
506
+ ```ts
507
+ test: {
508
+ browser: {
509
+ enabled: true,
510
+ provider: playwright({ launch: { headless: true } }), // or webdriverio()
511
+ // provider options: preview (limited), playwright (recommended), webdriverio
512
+ instances: [{ browser: 'chromium' }, { browser: 'firefox' }],
513
+ headless: boolean, // default: process.env.CI
514
+ api: number|{port,host}, // default: 63315
515
+ viewport: { width, height },
516
+ screenshotDirectory: string,
517
+ screenshotFailures: boolean,
518
+ locators: { testIdAttribute: string }
519
+ }
520
+ }
521
+ ```
522
+
523
+ ### Browser API
524
+
525
+ ```ts
526
+ import { page, userEvent, expect, server, commands, cdp } from 'vitest/browser'
527
+
528
+ // Locators
529
+ page.getByRole(role, opts?)
530
+ page.getByText(text, opts?)
531
+ page.getByTestId(id)
532
+ page.getByLabelText(text, opts?)
533
+ page.getByPlaceholder(text, opts?)
534
+ page.getByAltText(text, opts?)
535
+ page.getByTitle(text, opts?)
536
+ page.elementLocator(element)
537
+
538
+ // Locator methods
539
+ locator.click(opts?)
540
+ locator.fill(value)
541
+ locator.clear()
542
+ locator.selectOptions(values)
543
+ locator.screenshot(opts?)
544
+ locator.query() / .all() / .elements()
545
+ locator.nth(n) / .first() / .last()
546
+ locator.element()
547
+
548
+ // User Events (real browser events via CDP/WebDriver)
549
+ userEvent.click(el, opts?)
550
+ userEvent.dblClick(el, opts?)
551
+ userEvent.tripleClick(el, opts?)
552
+ userEvent.fill(el, text, opts?) // fast, clears first
553
+ userEvent.type(el, text, opts?) // slow, keyboard syntax
554
+ userEvent.clear(el)
555
+ userEvent.hover(el) / .unhover(el)
556
+ userEvent.keyboard(text) // {Shift}, {Enter}, etc
557
+ userEvent.tab()
558
+ userEvent.dragAndDrop(src, tgt, opts?)
559
+ userEvent.upload(el, files)
560
+ userEvent.copy() / .cut() / .paste()
561
+
562
+ // Page
563
+ page.screenshot(opts?)
564
+ page.extend({commands})
565
+ page.imageSnapshot(locator?, opts?)
566
+
567
+ // Commands
568
+ commands.readFile(path)
569
+ commands.writeFile(path, data)
570
+ commands.removeFile(path)
571
+
572
+ // CDP (Playwright/WebdriverIO chromium only)
573
+ cdp().send(method, params?)
574
+ cdp().on(event, handler)
575
+ ```
576
+
577
+ ### Browser Limitations
578
+
579
+ - No `alert`/`confirm`/`prompt` (mocked by default)
580
+ - No `vi.spyOn` on imports (use `vi.mock({spy:true})`)
581
+ - Use `userEvent` not `@testing-library/user-event`
582
+
583
+ ## PROJECTS
584
+
585
+ ```ts
586
+ export default defineConfig({
587
+ test: {
588
+ projects: [
589
+ 'packages/*', // glob
590
+ { test: { name: 'unit' } }, // inline
591
+ './e2e/vitest.config.ts', // file
592
+ ],
593
+ },
594
+ });
595
+ ```
596
+
597
+ - Root config = global opts (reporters, coverage)
598
+ - Filter: `--project <name>`
599
+ - Each project can have own: environment, pool, setupFiles, browser config
600
+
601
+ ## COVERAGE
602
+
603
+ ### Providers
604
+
605
+ - **v8** (default): Native V8 inspector; faster, lower memory; no pre-transpile;
606
+ AST-based remapping in v3.2+
607
+ - **istanbul**: Instrumentation-based; battle-tested; works everywhere; slower
608
+ due to instrumentation
609
+
610
+ ### Ignore Comments
611
+
612
+ ```ts
613
+ /* v8 ignore next */
614
+ /* v8 ignore next 3 */
615
+ /* v8 ignore start */ ... /* v8 ignore stop */
616
+ /* v8 ignore if */
617
+ /* v8 ignore else */
618
+ /* v8 ignore file */
619
+ // For esbuild (strips comments), add @preserve:
620
+ /* v8 ignore next -- @preserve */
621
+ ```
622
+
623
+ ## IN-SOURCE TESTING
624
+
625
+ ```ts
626
+ // src/utils.ts
627
+ export const add = (a, b) => a + b;
628
+
629
+ if (import.meta.vitest) {
630
+ const { it, expect } = import.meta.vitest;
631
+ it('adds', () => expect(add(1, 2)).toBe(3));
632
+ }
633
+ ```
634
+
635
+ Config: `includeSource: ['src/**/*.ts']` Build:
636
+ `define: { 'import.meta.vitest': 'undefined' }` for dead code elimination
637
+ TypeScript: add `vitest/importMeta` to tsconfig types
638
+
639
+ ## SNAPSHOTS
640
+
641
+ ```ts
642
+ expect(obj).toMatchSnapshot();
643
+ expect(obj).toMatchInlineSnapshot();
644
+ expect(obj).toMatchFileSnapshot('./snap.txt');
645
+ expect.addSnapshotSerializer({ serialize, test });
646
+ ```
647
+
648
+ Update: `vitest -u` or press `u` in watch mode
649
+
650
+ ## ANNOTATIONS
651
+
652
+ ```ts
653
+ test('name', async ({ annotate }) => {
654
+ await annotate('message', 'notice'); // notice|warning|error
655
+ await annotate('msg', 'info', {
656
+ path: './file.txt',
657
+ contentType: 'text/plain',
658
+ });
659
+ });
660
+ ```
661
+
662
+ ## SHARDING
663
+
664
+ ```bash
665
+ vitest --shard=1/3 --reporter=blob
666
+ vitest --shard=2/3 --reporter=blob
667
+ vitest --shard=3/3 --reporter=blob
668
+ vitest --merge-reports --reporter=default --coverage.reporter=text
669
+ ```
670
+
671
+ ## PERFORMANCE
672
+
673
+ - `--pool=threads` faster than forks (if compatible)
674
+ - `--no-isolate` if no side effects
675
+ - `--no-file-parallelism` reduces startup
676
+ - `test.dir` limits file search
677
+ - `deps.optimizer` for many imports
678
+ - `vmThreads`/`vmForks` fastest (memory leak risk)
679
+ - `experimental.fsModuleCache` for reruns
680
+
681
+ ## DEBUGGING
682
+
683
+ ```bash
684
+ vitest --inspect-brk --no-file-parallelism
685
+ ```
686
+
687
+ VS Code: JavaScript Debug Terminal or launch.json with
688
+ `program: node_modules/vitest/vitest.mjs`
689
+
690
+ ## COMMON ERRORS
691
+
692
+ - **Cannot find module**: Check path; use `vite-tsconfig-paths` for baseUrl;
693
+ avoid relative aliases
694
+ - **Failed to terminate worker**: Switch to `pool: 'forks'` (fetch + threads
695
+ issue)
696
+ - **Segfaults**: Native modules not thread-safe; use `pool: 'forks'`
697
+
698
+ ## V4 MIGRATION
699
+
700
+ - Coverage: `coverage.all` removed; define `coverage.include` explicitly
701
+ - `exclude` simplified (only node_modules/.git by default)
702
+ - `vi.fn()`/`vi.spyOn` support constructors (use class/function, not arrow)
703
+ - `vi.restoreAllMocks` only restores `vi.spyOn` mocks (not automocks)
704
+ - `workspace` renamed to `projects`
705
+ - Browser provider: object syntax required (`playwright()` not `'playwright'`)
706
+ - `@vitest/browser/context` → `vitest/browser`