diff --git a/.vitepress/config.ts b/.vitepress/config.ts
index d2228f9d..6959c157 100644
--- a/.vitepress/config.ts
+++ b/.vitepress/config.ts
@@ -246,6 +246,11 @@ export default ({ mode }: { mode: string }) => {
link: '/guide/browser/webdriverio',
docFooterText: 'Configuring WebdriverIO | Browser Mode',
},
+ {
+ text: 'Configuring Preview',
+ link: '/guide/browser/preview',
+ docFooterText: 'Configuring Preview | Browser Mode',
+ },
],
},
{
diff --git a/guide/browser/assertion-api.md b/guide/browser/assertion-api.md
index 9220073d..aad91ac4 100644
--- a/guide/browser/assertion-api.md
+++ b/guide/browser/assertion-api.md
@@ -7,18 +7,27 @@ title: Assertion API | Browser Mode
Vitest 默认提供了一组丰富的 DOM 断言,这些断言源自 [`@testing-library/jest-dom`](https://github.com/testing-library/jest-dom) 库,并增加了对定位器的支持以及内置的重试能力。
::: tip TypeScript Support
+<<<<<<< HEAD
如果您使用 [TypeScript](/guide/browser/#typescript) 或希望在 `expect` 中获得正确的类型提示,请确保在某个地方引用了 `@vitest/browser/context`。如果您从未从该模块导入过,可以在 `tsconfig.json` 覆盖范围内的任何文件中添加一个 `reference` 注释:
+=======
+If you are using [TypeScript](/guide/browser/#typescript) or want to have correct type hints in `expect`, make sure you have `vitest/browser` referenced somewhere. If you never imported from there, you can add a `reference` comment in any file that's covered by your `tsconfig.json`:
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
```ts
-///
+///
```
:::
浏览器中的测试由于其异步特性,可能会不一致地失败。因此,即使条件延迟(如超时、网络请求或动画),也必须有办法保证断言成功。为此,Vitest 通过 [`expect.poll`](/api/expect#poll)和 `expect.element` API 提供了可重试的断言:
```ts
+<<<<<<< HEAD
import { page } from '@vitest/browser/context'
import { expect, test } from 'vitest'
+=======
+import { expect, test } from 'vitest'
+import { page } from 'vitest/browser'
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
test('error banner is rendered', async () => {
triggerError()
diff --git a/guide/browser/commands.md b/guide/browser/commands.md
index 0766cad9..7c8c0059 100644
--- a/guide/browser/commands.md
+++ b/guide/browser/commands.md
@@ -20,7 +20,7 @@ outline: deep
:::
```ts
-import { server } from '@vitest/browser/context'
+import { server } from 'vitest/browser'
const { readFile, writeFile, removeFile } = server.commands
@@ -38,10 +38,14 @@ it('handles files', async () => {
## CDP Session
+<<<<<<< HEAD
Vitest 通过 `@vitest/browser/context` 中导出的 `cdp` 方法访问原始 Chrome Devtools 协议。它主要用于库作者在其基础上构建工具。
+=======
+Vitest exposes access to raw Chrome Devtools Protocol via the `cdp` method exported from `vitest/browser`. It is mostly useful to library authors to build tools on top of it.
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
```ts
-import { cdp } from '@vitest/browser/context'
+import { cdp } from 'vitest/browser'
const input = document.createElement('input')
document.body.appendChild(input)
@@ -97,10 +101,14 @@ export default function BrowserCommands(): Plugin {
}
```
+<<<<<<< HEAD
然后,你可以通过从 `@vitest/brower/context` 导入它,在测试中调用它:
+=======
+Then you can call it inside your test by importing it from `vitest/browser`:
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
```ts
-import { commands } from '@vitest/browser/context'
+import { commands } from 'vitest/browser'
import { expect, test } from 'vitest'
test('custom command works correctly', async () => {
@@ -108,8 +116,13 @@ test('custom command works correctly', async () => {
expect(result).toEqual({ someValue: true })
})
+<<<<<<< HEAD
// 如果你使用 TypeScript,你可以扩展模块。
declare module '@vitest/browser/context' {
+=======
+// if you are using TypeScript, you can augment the module
+declare module 'vitest/browser' {
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
interface BrowserCommands {
myCustomCommand: (arg1: string, arg2: string) => Promise<{
someValue: true
diff --git a/guide/browser/component-testing.md b/guide/browser/component-testing.md
index 8ea0d022..6af86876 100644
--- a/guide/browser/component-testing.md
+++ b/guide/browser/component-testing.md
@@ -138,7 +138,7 @@ test('ProductList filters and displays products correctly', async () => {
```jsx
// For Solid.js components
import { render } from '@testing-library/solid'
-import { page } from '@vitest/browser/context'
+import { page } from 'vitest/browser'
test('Solid component handles user interaction', async () => {
// Use Testing Library to render the component
@@ -563,9 +563,15 @@ import { render } from 'vitest-browser-react' // [!code ++]
### 主要差异
+<<<<<<< HEAD
- 使用 `await expect.element()` 而不是 `expect()` 进行 DOM 断言
- 使用 `@vitest/browser/context` 进行用户交互而不是 `@testing-library/user-event`
- 浏览器模式提供真实的浏览器环境以进行准确的测试
+=======
+- Use `await expect.element()` instead of `expect()` for DOM assertions
+- Use `vitest/browser` for user interactions instead of `@testing-library/user-event`
+- Browser Mode provides real browser environment for accurate testing
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
## 了解更多
diff --git a/guide/browser/config.md b/guide/browser/config.md
index 5ff9c9a4..910b9bc5 100644
--- a/guide/browser/config.md
+++ b/guide/browser/config.md
@@ -4,7 +4,7 @@
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
test: {
@@ -46,6 +46,7 @@ export default defineConfig({
## browser.instances
+<<<<<<< HEAD
- **类型:** `BrowserConfig`
- **默认值:** `[{ browser: name }]`
@@ -55,6 +56,14 @@ export default defineConfig({
- [配置 WebdriverIO](/guide/browser/webdriverio)
除此之外,你还可以指定大多数[项目选项](/config/)(未标记为图标的选项)和一些 `browser` 选项,例如`browser.testerHtmlPath`。
+=======
+- **Type:** `BrowserConfig`
+- **Default:** `[]`
+
+Defines multiple browser setups. Every config has to have at least a `browser` field.
+
+You can specify most of the [project options](/config/) (not marked with a icon) and some of the `browser` options like `browser.testerHtmlPath`.
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
::: warning
每个浏览器配置都从根配置继承选项:
@@ -79,9 +88,13 @@ export default defineConfig({
})
```
+<<<<<<< HEAD
在开发过程中,Vitest 仅支持一个 [非无头](#browser-headless) 配置。我们可以通过在配置中指定 `headless: false`,或提供 `--browser.headless=false` 标志,或使用 `--project=chromium` 标志过滤项目来限制有头项目。
有关更多示例,请参阅 ["多设置" 指南](/guide/browser/multiple-setups)。
+=======
+For more examples, refer to the ["Multiple Setups" guide](/guide/browser/multiple-setups).
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
:::
可用的 `browser` 选项列表:
@@ -94,9 +107,13 @@ export default defineConfig({
- [`browser.screenshotFailures`](#browser-screenshotfailures)
- [`browser.provider`](#browser-provider)
+<<<<<<< HEAD
默认情况下,Vitest 创建一个包含单个元素的数组,该元素使用 [`browser.name`](#browser-name) 字段作为 `browser`。请注意,此行为将在 Vitest 4 中移除。
在底层,Vitest 将这些实例转换为共享单个 Vite 服务器的单独 [测试项目](/advanced/api/test-project),以获得更好的缓存性能。
+=======
+Under the hood, Vitest transforms these instances into separate [test projects](/advanced/api/test-project) sharing a single Vite server for better caching performance.
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
## browser.headless
@@ -134,12 +151,16 @@ HTML 入口点的路径。可以是相对于项目根目录的路径。此文件
- **默认值:** `'preview'`
- **CLI:** `--browser.provider=playwright`
+<<<<<<< HEAD
提供者工厂的返回值。你可以从 `@vitest/browser/providers/` 导入工厂函数,或者创建自己的提供者:
+=======
+The return value of the provider factory. You can import the factory from `@vitest/browser-` or make your own provider:
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
```ts{8-10}
-import { playwright } from '@vitest/browser/providers/playwright'
-import { webdriverio } from '@vitest/browser/providers/webdriverio'
-import { preview } from '@vitest/browser/providers/preview'
+import { playwright } from '@vitest/browser-playwright'
+import { webdriverio } from '@vitest/browser-webdriverio'
+import { preview } from '@vitest/browser-preview'
export default defineConfig({
test: {
@@ -155,7 +176,7 @@ export default defineConfig({
要配置提供者如何初始化浏览器,你可以将选项传递给工厂函数:
```ts{7-13,20-26}
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
test: {
@@ -294,7 +315,11 @@ export interface BrowserScript {
- **类型:** `Record`
- **默认值:** `{ readFile, writeFile, ... }`
+<<<<<<< HEAD
可以从 `@vitest/browser/commands` 导入的自定义 [命令](/guide/browser/commands)。
+=======
+Custom [commands](/guide/browser/commands) that can be imported during browser tests from `vitest/browser`.
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
## browser.connectTimeout
diff --git a/guide/browser/context.md b/guide/browser/context.md
index ad803637..ecc2d017 100644
--- a/guide/browser/context.md
+++ b/guide/browser/context.md
@@ -4,7 +4,11 @@ title: Context API | Browser Mode
# 上下文
+<<<<<<< HEAD
Vitest 通过 `@vitest/browser/context` 入口点公开上下文模块。从 2.0 开始,它公开了一小部分实用程序,这些实用程序可能在测试中对你有用。
+=======
+Vitest exposes a context module via `vitest/browser` entry point. As of 2.0, it exposes a small set of utilities that might be useful to you in tests.
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
## `userEvent`
diff --git a/guide/browser/index.md b/guide/browser/index.md
index 0a424c63..e6220c4d 100644
--- a/guide/browser/index.md
+++ b/guide/browser/index.md
@@ -99,7 +99,7 @@ bun add -D vitest @vitest/browser webdriverio
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
test: {
@@ -126,7 +126,7 @@ Vitest 默认分配端口号 `63315` 以避免与开发服务器冲突,允许
::: code-group
```ts [react]
import react from '@vitejs/plugin-react'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
plugins: [react()],
@@ -143,7 +143,7 @@ export default defineConfig({
```
```ts [vue]
import { defineConfig } from 'vitest/config'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'vitest/config'
@@ -162,7 +162,7 @@ export default defineConfig({
```
```ts [svelte]
import { svelte } from '@sveltejs/vite-plugin-svelte'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
plugins: [svelte()],
@@ -179,7 +179,7 @@ export default defineConfig({
```
```ts [solid]
import solidPlugin from 'vite-plugin-solid'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
plugins: [solidPlugin()],
@@ -196,7 +196,7 @@ export default defineConfig({
```
```ts [marko]
import marko from '@marko/vite'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
plugins: [marko()],
@@ -213,7 +213,7 @@ export default defineConfig({
```
```ts [qwik]
import { qwikVite } from '@builder.io/qwik/optimizer'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
// optional, run the tests in SSR mode
import { testSSR } from 'vitest-browser-qwik/ssr-plugin'
@@ -239,7 +239,7 @@ export default defineConfig({
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
test: {
@@ -333,7 +333,7 @@ headless 模式是浏览器模式下可用的另一个选项。在 headless 模
```ts [vitest.config.ts]
import { defineConfig } from 'vitest/config'
-import { playwright } from '@vitest/browser/providers/playwright'
+import { playwright } from '@vitest/browser-playwright'
export default defineConfig({
test: {
@@ -363,8 +363,13 @@ npx vitest --browser.headless
一般情况下,我们不需要任何依赖来使用浏览器模式:
```js [example.test.js]
+<<<<<<< HEAD
import { page } from '@vitest/browser/context'
import { expect, test } from 'vitest'
+=======
+import { expect, test } from 'vitest'
+import { page } from 'vitest/browser'
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
import { render } from './my-render-function.js'
test('properly handles form inputs', async () => {
@@ -401,15 +406,25 @@ test('properly handles form inputs', async () => {
除了渲染组件和定位元素外,你还需要进行断言。Vitest 基于 [`@testing-library/jest-dom`](https://github.com/testing-library/jest-dom) 库提供了一整套开箱即用的 DOM 断言。更多信息请参阅 [Assertions API](/guide/browser/assertion-api)。
```ts
+<<<<<<< HEAD
import { page } from '@vitest/browser/context'
import { expect } from 'vitest'
// element is rendered correctly
await expect.element(page.getByText('Hello World')).toBeInTheDocument()
```
Vitest 公开了一个[Context API](/guide/browser/context),其中包含一小套在测试中可能有用的实用程序。例如,如果我们需要进行交互,如点击元素或在输入框中输入文本,我们可以使用 `@vitest/browser/context` 中的 `userEvent`。更多信息请参阅 [Interactivity API](/guide/browser/interactivity-api)。
+=======
+import { expect } from 'vitest'
+import { page } from 'vitest/browser'
+// element is rendered correctly
+await expect.element(page.getByText('Hello World')).toBeInTheDocument()
+```
+
+Vitest exposes a [Context API](/guide/browser/context) with a small set of utilities that might be useful to you in tests. For example, if you need to make an interaction, like clicking an element or typing text into an input, you can use `userEvent` from `vitest/browser`. Read more at the [Interactivity API](/guide/browser/interactivity-api).
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
```ts
-import { page, userEvent } from '@vitest/browser/context'
+import { page, userEvent } from 'vitest/browser'
await userEvent.fill(page.getByLabelText(/username/i), 'Alice')
// or just locator.fill
await page.getByLabelText(/username/i).fill('Alice')
@@ -526,7 +541,11 @@ Vitest 并不支持所有开箱即用的框架,但我们可以使用外部工
我们还可以在 [`browser-examples`](https://github.com/vitest-tests/browser-examples) 中查看更多的案例。
::: warning
+<<<<<<< HEAD
`testing-library` 提供了一个软件包 `@testing-library/user-event`。我们不建议直接使用它,因为它会模拟事件而非实际触发事件--相反,请使用从 `@vitest/browser/context`导入的 [`userEvent`](/guide/browser/interactivity-api),它在引擎盖下使用 Chrome DevTools 协议或 Webdriver(取决于provider)。
+=======
+`testing-library` provides a package `@testing-library/user-event`. We do not recommend using it directly because it simulates events instead of actually triggering them - instead, use [`userEvent`](/guide/browser/interactivity-api) imported from `vitest/browser` that uses Chrome DevTools Protocol or Webdriver (depending on the provider) under the hood.
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
:::
::: code-group
diff --git a/guide/browser/interactivity-api.md b/guide/browser/interactivity-api.md
index 3b2cacfb..928524aa 100644
--- a/guide/browser/interactivity-api.md
+++ b/guide/browser/interactivity-api.md
@@ -7,7 +7,7 @@ title: Interactivity API | Browser Mode
Vitest 使用 [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/) 或 [webdriver](https://www.w3.org/TR/webdriver/) 实现了 [`@testing-library/user-event`](https://testing-library.com/docs/user-event/intro) 库的子集 API,而不是伪造事件,这使得浏览器行为更加可靠和一致,符合用户与页面交互的方式。
```ts
-import { userEvent } from '@vitest/browser/context'
+import { userEvent } from 'vitest/browser'
await userEvent.click(document.querySelector('.button'))
```
@@ -23,9 +23,16 @@ function setup(): UserEvent
创建一个新的用户事件实例。如果需要保持键盘状态,以便正确按下和释放按钮,这将非常有用。
::: warning
+<<<<<<< HEAD
与 `@testing-library/user-event` 不同,来自 `@vitest/browser/context` 的默认 `userEvent` 实例只创建一次,而不是每次调用其方法时都创建一次!您可以从本代码段中看到其工作方式的不同之处:
```ts
+=======
+Unlike `@testing-library/user-event`, the default `userEvent` instance from `vitest/browser` is created once, not every time its methods are called! You can see the difference in how it works in this snippet:
+
+```ts
+import { userEvent as vitestUserEvent } from 'vitest/browser'
+>>>>>>> 19c97cda6761cd60ffae67ea0d917be9f960dd1a
import { userEvent as originalUserEvent } from '@testing-library/user-event'
import { userEvent as vitestUserEvent } from '@vitest/browser/context'
@@ -51,7 +58,7 @@ function click(
点击元素。继承 provider 的选项。有关此方法如何工作的详细说明,请参阅 provider 的文档。
```ts
-import { page, userEvent } from '@vitest/browser/context'
+import { page, userEvent } from 'vitest/browser'
test('clicks on an element', async () => {
const logo = page.getByRole('img', { name: /logo/ })
@@ -82,7 +89,7 @@ function dblClick(
请参阅你的 provider 的文档以获取有关此方法如何工作的详细说明。
```ts
-import { page, userEvent } from '@vitest/browser/context'
+import { page, userEvent } from 'vitest/browser'
test('triggers a double click on an element', async () => {
const logo = page.getByRole('img', { name: /logo/ })
@@ -113,7 +120,7 @@ function tripleClick(
请参阅你的提供商文档以获取有关此方法工作原理的详细说明。
```ts
-import { page, userEvent } from '@vitest/browser/context'
+import { page, userEvent } from 'vitest/browser'
test('triggers a triple click on an element', async () => {
const logo = page.getByRole('img', { name: /logo/ })
@@ -150,7 +157,7 @@ function fill(
为 `input` `、textarea` 或 `contenteditable` 元素设置新的内容,并且在赋值前会先清空其中已有的文本。
```ts
-import { page, userEvent } from '@vitest/browser/context'
+import { page, userEvent } from 'vitest/browser'
test('update input', async () => {
const input = page.getByRole('input')
@@ -189,7 +196,7 @@ function keyboard(text: string): Promise
此 API 支持 [user-event `keyboard` 语法](https://testing-library.com/docs/user-event/keyboard)。
```ts
-import { userEvent } from '@vitest/browser/context'
+import { userEvent } from 'vitest/browser'
test('trigger keystrokes', async () => {
await userEvent.keyboard('foo') // translates to: f, o, o
@@ -215,7 +222,7 @@ function tab(options?: UserEventTabOptions): Promise
发送一个 `Tab` 键事件。这是`userEvent.keyboard('{tab}')`的简写。
```ts
-import { page, userEvent } from '@vitest/browser/context'
+import { page, userEvent } from 'vitest/browser'
test('tab works', async () => {
const [input1, input2] = page.getByRole('input').elements()
@@ -259,7 +266,7 @@ function type(
如果只需按下字符而无需输入,请使用 [`userEvent.keyboard`](#userevent-keyboard) API。
```ts
-import { page, userEvent } from '@vitest/browser/context'
+import { page, userEvent } from 'vitest/browser'
test('update input', async () => {
const input = page.getByRole('input')
@@ -289,7 +296,7 @@ function clear(element: Element | Locator, options?: UserEventClearOptions): Pro
此方法会清除输入元素的内容。
```ts
-import { page, userEvent } from '@vitest/browser/context'
+import { page, userEvent } from 'vitest/browser'
test('clears input', async () => {
const input = page.getByRole('input')
@@ -336,7 +343,7 @@ The `userEvent.selectOptions` allows selecting a value in a `