Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
23 changes: 23 additions & 0 deletions api/browser/locators.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,29 @@ outline: [2, 3]
::: tip
本页介绍了 API 的使用。为了更好地了解定位器及其用法,请阅读 [Playwright 的“定位器”文档](https://playwright.dev/docs/locators)。
:::
<!-- TODO: translation -->
::: tip Difference from `testing-library`
Vitest's `page.getBy*` methods return a locator object, not a DOM element. This makes locator queries composable and allows Vitest to retry interactions and assertions when needed.

Compared to testing-library queries:

- Use locator chaining (`.getBy*`, `.filter`, `.nth`) instead of `within(...)`.
- Keep locators around and interact with them later (`await locator.click()`), instead of resolving elements up front.
- Single-element escape hatches like `.element()` and `.query()` are strict and throw if multiple elements match.

```ts
import { expect } from 'vitest'
import { page } from 'vitest/browser'

const deleteButton = page
.getByRole('row')
.filter({ hasText: 'Vitest' })
.getByRole('button', { name: /delete/i })

await deleteButton.click()
await expect.element(deleteButton).toBeEnabled()
```
:::

## getByRole

Expand Down
44 changes: 44 additions & 0 deletions guide/common-errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,47 @@ vitest --pool=forks
```

:::
<!-- TODO: translation -->
## Unhandled Promise Rejection

This error happens when a Promise rejects but no `.catch()` handler or `await` is attached to it before the microtask queue flushes. This behavior comes from JavaScript itself and is not specific to Vitest. Learn more in the [Node.js documentation](https://nodejs.org/api/process.html#event-unhandledrejection).

A common cause is calling an async function without `await`ing it:

```ts
async function fetchUser(id) {
const res = await fetch(`/api/users/${id}`)
if (!res.ok) {
throw new Error(`User ${id} not found`) // [!code highlight]
}
return res.json()
}

test('fetches user', async () => {
fetchUser(123) // [!code error]
})
```

Because `fetchUser()` is not `await`ed, its rejection has no handler and Vitest reports:

```
Unhandled Rejection: Error: User 123 not found
```

### Fix

`await` the promise so Vitest can catch the error:

```ts
test('fetches user', async () => {
await fetchUser(123) // [!code ++]
})
```

If you expect the call to throw, use [`expect().rejects`](/api/expect#rejects):

```ts
test('rejects for missing user', async () => {
await expect(fetchUser(123)).rejects.toThrow('User 123 not found')
})
```
32 changes: 20 additions & 12 deletions guide/recipes.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,19 @@ export default defineConfig({
test: {
projects: [
{
// 禁用隔离的单元测试
name: 'Unit tests',
isolate: false,
exclude: ['**.integration.test.ts'],
test: {
// Non-isolated unit tests
name: 'Unit tests',
isolate: false,
exclude: ['**.integration.test.ts'],
},
},
{
// 集成隔离的测试
name: 'Integration tests',
include: ['**.integration.test.ts'],
test: {
// Isolated integration tests
name: 'Integration tests',
include: ['**.integration.test.ts'],
},
},
],
},
Expand All @@ -41,13 +45,17 @@ export default defineConfig({
test: {
projects: [
{
name: 'Parallel',
exclude: ['**.sequential.test.ts'],
test: {
name: 'Parallel',
exclude: ['**.sequential.test.ts'],
},
},
{
name: 'Sequential',
include: ['**.sequential.test.ts'],
fileParallelism: false,
test: {
name: 'Sequential',
include: ['**.sequential.test.ts'],
fileParallelism: false,
},
},
],
},
Expand Down
Loading