Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
f0dd8d8
docs: update `page.mark()` nesting behavior (#11484)
hi-ogawa Oct 5, 2026
55a88d6
chore(deps): update all non-major dependencies (#11477)
renovate[bot] Oct 5, 2026
0478de6
docs: align `mock` guide with the current implementation (#11503)
sheremet-va Oct 5, 2026
d19cdc9
feat: support `test.ui.theme` option (#11499)
sheremet-va Oct 6, 2026
7c5bd3d
chore: make ui.theme experimental (#11509)
sheremet-va Oct 6, 2026
2c05a5a
feat(experimental): add an option to cache dependencies instead of st…
sheremet-va Oct 8, 2026
e173ef5
fix: respect root in projects (#11521)
sheremet-va Oct 8, 2026
6129288
refactor: resolve maxWorkers once in config (#11524)
sheremet-va Oct 8, 2026
d3c2af9
fix(browser): run browser instances as workers (#11525)
sheremet-va Oct 9, 2026
f33a7af
chore(deps): update all non-major dependencies (#11550)
renovate[bot] Oct 12, 2026
69558b5
chore(deps): update oxc packages (#11551)
renovate[bot] Oct 12, 2026
f9b6d51
docs: fix `test.projects` usage, test descriptions (#11565)
AriPerkkio Oct 13, 2026
bba5b41
fix: set `skip` in `skipIf`, ignore `undefined` options (#11591)
sheremet-va Oct 15, 2026
7b1ba1b
fix(browser): run global setup once with instances (#11596)
sheremet-va Oct 15, 2026
9beee5f
docs: explain outer-realm values in vm pools (#11608)
sheremet-va Oct 15, 2026
b737fcc
fix(browser): change default port to 23315 (#11640)
hi-ogawa Oct 19, 2026
f145e83
feat(browser): mock modules through an import map (#11534)
sheremet-va Oct 19, 2026
299b181
feat: add `--last-failed` to run only failed tests (#11558)
sheremet-va Oct 19, 2026
8ff9f47
feat(browser): drop experimental label from trace view (#11518)
hi-ogawa Oct 19, 2026
9a2a056
feat: support `Temporal.Instant` and `Temporal.ZonedDateTime` in `vi.…
Prajwal2246 Oct 19, 2026
3accf71
feat(browser): introduce experimental `pointer` API (#10780)
macarie Oct 19, 2026
063d305
fix(deps): update all non-major dependencies (#11637)
renovate[bot] Oct 19, 2026
213155c
feat(browser): capture aria snapshot in trace view (#11492)
hi-ogawa Oct 19, 2026
1ec0fdc
feat: introduce `--since-last-run` flag (#11516)
sheremet-va Oct 19, 2026
43f262e
feat: expose per-retry/repeat attempt result (#11232)
hi-ogawa Oct 19, 2026
bdcede2
fix(browser): advance fake timers in actions and expect.element (#11242)
julienw Oct 19, 2026
aff1977
feat: support fake timers for `node:timers` and `node:timers/promise`…
hi-ogawa Oct 19, 2026
3760e1c
feat(browser): show trace steps timeline on terminal on test failure …
hi-ogawa Oct 20, 2026
0825766
chore: address code scanning alerts (#11671)
sheremet-va Oct 21, 2026
37439f1
docs(coverage): update istanbuljs mentions (#11685)
AriPerkkio Oct 22, 2026
802c980
feat(coverage): v8 to support `ignoreNode` option (#11688)
erickserra Oct 22, 2026
4f5231b
fix(mocker): don't change the original prototype chain (#11737)
sheremet-va Oct 26, 2026
93a53b5
fix(mocker): use root __mocks__ for linked packages (fix #7708) (#11739)
sheremet-va Oct 26, 2026
e045f77
feat(browser): add failure-only trace view mode (#11612)
hi-ogawa Oct 26, 2026
702ad48
docs(browser): explain `--ui`, `browser.ui`, and `browser.headless` i…
hi-ogawa Oct 28, 2026
4cf2461
feat(browser): enable failure-only trace view by default (#11766)
hi-ogawa Oct 28, 2026
e9b363e
fix: prefix expect.poll message to all errors (#11756)
hi-ogawa Oct 28, 2026
5f1d4cd
docs(browser): rework trace view guide and config (#11767)
hi-ogawa Oct 28, 2026
e3931b6
fix: support api.port 0 (#11641)
hi-ogawa Oct 28, 2026
cc54eaf
chore(deps): update dependency vite-plugin-pwa to v2 (#11741)
renovate[bot] Oct 28, 2026
16d0d75
docs(coverage): html reporter theme (#11803)
AriPerkkio Nov 1, 2026
ee64f78
feat(experimental): add trace timeline for node (#11753)
hi-ogawa Nov 2, 2026
f8f7189
feat(experimental): add message option to vi.waitFor and vi.waitUntil…
hi-ogawa Nov 2, 2026
59df235
docs(browser): update trace view demo screenshots (#11826)
hi-ogawa Nov 2, 2026
e91dd11
docs: update sponsors (#11824)
sheremet-va Nov 2, 2026
6053cdc
docs: vitest 5.1 blog post (#11821)
sheremet-va Nov 2, 2026
8867869
fix(typecheck): add env var to hide experimental warning (#11840)
aliamanatali Nov 3, 2026
b0dc20c
docs(en): merging all conflicts
docschina-bot Nov 4, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export default ({ mode }: { mode: string }) => {

search: {
provider: 'local',
<<<<<<< HEAD
options: {
translations: {
button: {
Expand All @@ -168,6 +169,8 @@ export default ({ mode }: { mode: string }) => {
},
},
},
=======
>>>>>>> 88678699d9e33ecbfb4173873cba54a44cba4255
},

// banner: {
Expand Down Expand Up @@ -731,6 +734,10 @@ export default ({ mode }: { mode: string }) => {
text: 'browser.trackUnhandledErrors',
link: '/config/browser/trackunhandlederrors',
},
{
text: 'browser.importMapMocks',
link: '/config/browser/importmapmocks',
},
{
text: 'browser.expect',
link: '/config/browser/expect',
Expand Down Expand Up @@ -1107,6 +1114,10 @@ export default ({ mode }: { mode: string }) => {
text: '并行和串行测试文件',
link: '/guide/recipes/parallel-sequential',
},
{
text: 'Running Only Affected Tests',
link: '/guide/recipes/affected-tests',
},
],
},
{
Expand Down
3 changes: 2 additions & 1 deletion .vitepress/scripts/cli-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const cliTablePath = resolve(docsDir, './guide/cli-generated.md')

const nonNullable = <T>(value: T): value is NonNullable<T> => value !== null && value !== undefined

const skipCli = new Set(['mergeReports', 'shard'])
const skipCli = new Set(['mergeReports', 'shard', 'sinceLastRun'])

const skipConfig = new Set([
'config',
Expand All @@ -25,6 +25,7 @@ const skipConfig = new Set([
'coverage.thresholds.functions',
'coverage.thresholds.lines',
'standalone',
'lastFailed',
'clearScreen',
'configLoader',
'color',
Expand Down
15 changes: 0 additions & 15 deletions .vitepress/sponsors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,12 @@ export const sponsors: SponsorTier[] = [
url: 'https://bolt.new',
img: '/bolt.svg',
},
{
name: 'Latitude',
url: 'https://latitude.so/',
img: '/latitude.svg',
},
],
},
{
tier: '金牌赞助商',
size: 'medium',
items: [
{
name: 'vital',
url: 'https://vital.io/',
img: '/vital.svg',
},
{
name: 'Mailmeteor',
url: 'https://mailmeteor.com/',
Expand All @@ -62,11 +52,6 @@ export const sponsors: SponsorTier[] = [
url: 'https://kraken.tech/',
img: '/kraken.svg',
},
{
name: 'Aerius Ventilation',
url: 'https://aerius.se/',
img: '/aerius.png',
},
{
name: 'TestMu AI',
url: 'https://www.testmuai.com/?utm_medium=sponsor&utm_source=vitest-dev',
Expand Down
11 changes: 11 additions & 0 deletions .vitepress/theme/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,17 @@
--vp-code-color: #007d38;
}

/* .ansi code blocks color the background of inverse and background-colored text */
html:not(.dark) .shiki span[style*='--shiki-light-bg'],
html[data-theme='light'] .shiki span[style*='--shiki-light-bg'] {
background-color: var(--shiki-light-bg);
}

html.dark:not([data-theme]) .shiki span[style*='--shiki-dark-bg'],
html[data-theme='dark'] .shiki span[style*='--shiki-dark-bg'] {
background-color: var(--shiki-dark-bg);
}

.highlighted-word {
background-color: var(--vp-code-line-highlight-color);
transition: background-color 0.5s;
Expand Down
31 changes: 31 additions & 0 deletions api/advanced/runner.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,37 @@ export interface TaskResult {
* The zero-based index of the current repeat.
*/
repeatCount?: number
/**
* Individual results for every retry and repeat attempt.
*/
attempts?: TaskResultAttempt[]
}

export interface TaskResultAttempt {
/**
* The state after applying the test's expected failure option.
*/
state: 'pass' | 'fail' | 'skip'
/**
* Errors produced by this attempt.
*/
errors?: TestError[]
/**
* How long in milliseconds the attempt took to run.
*/
duration: number
/**
* Time in milliseconds when the attempt started running.
*/
startTime: number
/**
* The zero-based retry index within the repeat.
*/
retryIndex: number
/**
* The zero-based repeat index.
*/
repeatIndex: number
}
```

Expand Down
56 changes: 56 additions & 0 deletions api/advanced/test-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,11 @@ interface TestResultPassed {
```

::: warning
<<<<<<< HEAD
请注意,状态为 `passed` 的测试仍可能附带有错误——如果 `retry` 至少触发了一次,这种情况就可能发生。
=======
Note that the test with `passed` state can still have errors attached - this can happen if `retry` was triggered at least once. Use [`attempts()`](#attempts) to see which run produced each error.
>>>>>>> 88678699d9e33ecbfb4173873cba54a44cba4255
:::

## diagnostic
Expand Down Expand Up @@ -278,6 +282,58 @@ interface TestDiagnostic {
如果测试尚未被安排运行,`diagnostic()` 将返回 `undefined`。
:::

## attempts <Version>5.1.0</Version> {#attempts}

```ts
function attempts(): ReadonlyArray<TestAttempt>
```

Results of every run of the test, in execution order. A test runs more than once when [`retry`](/config/retry) or [`repeats`](/api/test#repeats) is configured, and each run produces one entry. Unlike `result()`, which only reports the final outcome and merges errors from all runs, each attempt keeps its own state, errors and timing.

```ts
interface TestAttempt {
/**
* The state of this attempt. `fails` tests are already inverted,
* so an expected failure is reported as `passed`.
*/
readonly state: 'passed' | 'failed' | 'skipped'
/**
* Errors thrown during this attempt only.
*/
readonly errors: ReadonlyArray<TestError> | undefined
/**
* How long in milliseconds the attempt took to run.
*/
readonly duration: number
/**
* Time in milliseconds when the attempt started.
*/
readonly startTime: number
/**
* The zero-based retry index within the current repeat.
*/
readonly retryIndex: number
/**
* The zero-based repeat index.
*/
readonly repeatIndex: number
}
```

For example, a test with `retry: 2` that passes on its third run returns:

```ts
[
{ state: 'failed', retryIndex: 0, repeatIndex: 0, errors: [/* ... */] },
{ state: 'failed', retryIndex: 1, repeatIndex: 0, errors: [/* ... */] },
{ state: 'passed', retryIndex: 2, repeatIndex: 0, errors: undefined },
]
```

::: info
`attempts()` returns an empty array if the test has not run yet.
:::

## annotations

```ts
Expand Down
4 changes: 4 additions & 0 deletions api/advanced/test-specification.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ describe('a group of tests', () => { // [!code error]

当前 TestSpecification 中需要运行的任务 ID 集合。

## testNames <Version>5.1.0</Version> {#testnames}

The full names of the tests inside of this specification to run, including the parent suites separated with `>`.

## testTagsFilter <Version>4.1.0</Version> {#testtagsfilter}

测试必须通过的 [标签过滤器](/guide/test-tags#syntax) 才能被纳入运行范围。多个过滤器将按 `AND` 逻辑处理。
Expand Down
12 changes: 11 additions & 1 deletion api/advanced/vitest.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ const testCase = vitest.state.getReportedEntity(task) // 新 API

## cache

<<<<<<< HEAD
<!-- TODO: translation -->

Cache manager that stores the results of the previous test runs. In Vitest itself this is only used by the default sequencer to sort tests.
=======
Cache manager that stores the results of the previous test runs. Vitest uses it to sort tests in the default sequencer and to select tests with [`--last-failed`](/guide/cli#last-failed).
>>>>>>> 88678699d9e33ecbfb4173873cba54a44cba4255

### cache.getTestSpecificationResult <Version type="experimental">5.0.4</Version> {#cache-gettestspecificationresult}

Expand All @@ -60,7 +64,7 @@ function getTestSpecificationResult(
interface CachedTestFileResult {
/**
* The file has a known failure.
* Only a complete run of the file clears it.
* A complete run of the file clears it, or a run in which every known failed test passes.
*/
failed: boolean
/**
Expand All @@ -72,6 +76,12 @@ interface CachedTestFileResult {
* It is not set if the file never ran completely.
*/
lastRun?: number
/**
* Full names of the tests that failed in the last run of the file.
* `--last-failed` runs only these tests.
* It is not set if the failure happened outside of tests, for example in a hook or during collection.
*/
failedTests?: string[]
}
```

Expand Down
4 changes: 4 additions & 0 deletions api/browser/assertions.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,11 @@ interface ExpectPollOptions {
```

::: tip
<<<<<<< HEAD
与 [expect.poll](/api/expect#poll) 类似,`expect.element` 会反复重试 DOM 断言,直到断言通过或达到超时时间。当接收到定位器时,Vitest 会先通过 [locator.findElement()](/api/browser/locators#findelement) 解析该定位器,再执行 DOM 断言。`timeout` 参数适用于整个重试过程。`interval` 参数控制失败 DOM 断言的重试频率,但定位器解析使用 `findElement` 自身递增的重试间隔。
=======
Like [`expect.poll`](/api/expect#poll), `expect.element` retries DOM assertions until they pass or the timeout is reached. When it receives a locator, Vitest resolves it with [`locator.findElement()`](/api/browser/locators#findelement) before running the DOM assertion. The `timeout` option applies to the whole retry operation. The `interval` option controls how often failed DOM assertions are retried, but locator resolution uses `findElement`'s own increasing retry intervals. If [fake timers](/api/vi#vi-usefaketimers) are enabled, `expect.element` advances them while it retries. See [Automatic Advancing](/guide/mocking/timers#automatic-advancing) for details.
>>>>>>> 88678699d9e33ecbfb4173873cba54a44cba4255

`toMatchTextContent` 以及其他所有断言在常规的 `expect` 中仍然可用,但没有内置的重试机制:

Expand Down
52 changes: 52 additions & 0 deletions api/browser/interactivity.md
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,58 @@ await page.getByRole('tablist').wheel({ direction: 'right' })
此方法用于测试显式监听 `wheel` 事件的 UI(例如自定义缩放控制、水平滚动标签页或 canvas 交互)。如果需要滚动页面以使元素进入视口,请改用其他 `userEvent` 方法或 [定位器操作](/api/browser/locators#methods) 提供的内置自动滚动功能。
:::

## userEvent.pointer <Version type="experimental">5.1.0</Version> <Experimental /> {#userevent-pointer}

```ts
function pointer(options: UserEventPointerInput): Promise<void>
```

Performs one or more pointer actions. Pass a key string, an action object, or an array of strings and objects. Key strings use [user-event `pointer` syntax](https://testing-library.com/docs/user-event/pointer). For example, `[MouseLeft]` presses and releases the left mouse button, `[MouseLeft>]` keeps it pressed, and `[/MouseLeft]` releases it.

::: tip
The `pointer` method is a low-level API for composing complex pointer interactions and performing actions that dedicated methods do not support, such as dragging an element to a precise position.

For one-off actions, prefer the equivalent dedicated method because in most cases they are simpler to use. For example, if you just want to click an element once, use [`userEvent.click`](#userevent-click).
:::

An action object accepts `keys`, `target`, and `coords`. An object without `keys` only moves the pointer.

The pointer position persists between `userEvent.pointer` calls on the same `userEvent` instance. This means that if an action omits both `target` and `coords`, it uses the position from the previous action.

::: warning
When the [Browser UI](/config/browser/ui) is enabled, the test iframe can be scaled to fit the available space. Vitest adjusts pointer coordinates to account for the scaling, but browser pixel rounding can cause the resulting event coordinates to differ by several _iframe pixels_. **Avoid relying on exact coordinates in this mode**.
:::

```ts
import { page, userEvent } from 'vitest/browser'

test('drags an element with pointer actions', async () => {
const source = page.getByTestId('source')
const target = page.getByTestId('target')

await userEvent.pointer([
{ target: source, keys: '[MouseLeft>]' },
{ target, coords: { x: 10, y: 10 }, keys: '[/MouseLeft]' },
])
})
```

::: warning Provider support and differences from user-event
This API is not consistently supported across providers, and its behavior can differ from the `user-event` library.

- The `playwright` provider does not support touch pointer keys such as `TouchA`.
- The `webdriverio` provider does not support this method at all.
- The `preview` provider simulates events using `@testing-library/user-event`.

Vitest does not support the `node` and `offset` fields used for text selection and only accepts `x` and `y` values in `coords`.

Without `target`, `coords` values are considered coordinates relative to the viewport. With `target`, they are offsets from its top-left corner. Unlike user-event, where coordinates paired with a target describe the final pointer position rather than an offset. When `coords` is provided, an omitted axis defaults to `0`.
:::

References:

- [testing-library `pointer` API](https://testing-library.com/docs/user-event/pointer)

## userEvent.fill

```ts
Expand Down
4 changes: 4 additions & 0 deletions api/browser/locators.md
Original file line number Diff line number Diff line change
Expand Up @@ -632,6 +632,10 @@ page.getByRole('article').filter({ hasText: 'Vite' }) // ✅

所有方法都是异步的,必须使用 `await`。自 Vitest 3 起,如果方法没有被 `await`,测试将会失败。

::: tip
If [fake timers](/api/vi#vi-usefaketimers) are enabled, these methods advance them while they run. See [Automatic Advancing](/guide/mocking/timers#automatic-advancing) for details.
:::

### click

```ts
Expand Down
4 changes: 4 additions & 0 deletions api/expect-typeof.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ expectTypeOf({ a: 1, b: 1 }).not.toEqualTypeOf<{ a: number }>()
自 expect-type v1.2.0 版本起,此匹配器已被弃用。请改用 [`toExtend`](#toextend)。
:::

<<<<<<< HEAD
此匹配器检查期望类型是否扩展了提供的类型。它不同于 `toEqual`,更类似于 [expect's](/api/expect) `toMatchObject()`。使用此匹配器,你可以检查对象是否“匹配”类型。
=======
This matcher checks if expect type extends provided type. It is different from `toEqual` and is more similar to [expect's](/api/expect) `toMatchObject()`. With this matcher, you can check if an object “matches” a type.
>>>>>>> 88678699d9e33ecbfb4173873cba54a44cba4255

```ts
import { expectTypeOf } from 'vitest'
Expand Down
9 changes: 9 additions & 0 deletions api/expect.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ interface ExpectPoll extends ExpectStatic {

如果在 `expect.poll` 回调中抛出错误,Vitest 将重试直到超时为止。

The `message` option describes what the poll waits for. If the poll fails, Vitest adds the message to the start of the error. The message also names the step in the [trace timeline](/config/experimental#experimental-tracetimeline).

```ts
await expect.poll(() => queue.count(), { message: 'queue drained' }).toBe(0)
// AssertionError: queue drained: expected 3 to be 0 // Object.is equality
```

If `vi.useFakeTimers` is used, `expect.poll` automatically calls `vi.advanceTimersByTime(interval)` after every failed attempt. See [Automatic Advancing](/guide/mocking/timers#automatic-advancing) for details.

```ts
import { expect, test } from 'vitest'

Expand Down
Loading
Loading