diff --git a/.vitepress/config.ts b/.vitepress/config.ts index ec7a09b2..17ce4ca2 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -813,9 +813,9 @@ export default ({ mode }: { mode: string }) => { docFooterText: 'Playwright Traces | Browser Mode', }, { - text: 'ARIA Snapshots', + text: 'ARIA 快照', link: '/guide/browser/aria-snapshots', - docFooterText: 'ARIA Snapshots | Browser Mode', + docFooterText: 'ARIA 快照 | 浏览器模式', }, ], }, diff --git a/guide/browser/aria-snapshots.md b/guide/browser/aria-snapshots.md index 28e423b8..4766c4d7 100644 --- a/guide/browser/aria-snapshots.md +++ b/guide/browser/aria-snapshots.md @@ -1,13 +1,13 @@ --- -title: ARIA Snapshots | Guide +title: ARIA 快照 | 指南 outline: deep --- - -# ARIA Snapshots experimental 4.1.4 -ARIA snapshots let you test the accessibility structure of your pages. Instead of asserting against raw HTML or visual output, you assert against the accessibility tree — the same structure that screen readers and other assistive technologies use. +# ARIA 快照 4.1.4 {#aria-snapshots} -Given this HTML: +ARIA 快照可以让你测试页面的无障碍结构。你不是去断言原始 HTML 或视觉输出,而是去断言无障碍树,也就是屏幕阅读器和其他辅助技术所使用的那套结构。 + +给定以下 HTML: ```html ``` -You can assert its accessibility tree: +你可以断言其无障碍树: ```ts await expect.element(page.getByRole('navigation')).toMatchAriaInlineSnapshot(` @@ -28,19 +28,19 @@ await expect.element(page.getByRole('navigation')).toMatchAriaInlineSnapshot(` `) ``` -This catches accessibility regressions: missing labels, broken roles, incorrect heading levels, and more — things that DOM snapshots would miss. Even if the underlying HTML structure changes, the assertion would not fail as long as content matches semantically. +这可以捕获无障碍方面的回归问题,比如缺失的标签、错误的角色、错误的标题层级等等,而这些往往是 DOM 快照捕捉不到的。即使底层的 HTML 结构发生了变化,只要内容在语义上仍然一致,这个断言就不会失败。 -For advanced cases, you can also generate and inspect the ARIA tree through `utils.aria` from `vitest/browser`. See the [Context API](/api/browser/context#aria) for details. +对于更高级的场景,你还可以通过 `vitest/browser` 中的 `utils.aria` 生成并检查 ARIA 树。更多内容请参阅 [上下文 API](/api/browser/context#aria)。 -## Snapshot Workflow +## 快照工作流 {#snapshot-workflow} -ARIA snapshots use the same Vitest snapshot workflow as other snapshot assertions. File snapshots, inline snapshots, `--update` / `-u`, watch mode updates, and CI snapshot behavior all work the same way. +ARIA 快照与其他快照断言使用相同的 Vitest 快照工作流。文件快照、内联快照、`--update`/`-u`、watch 模式更新以及 CI 快照行为都以相同的方式工作。 -See the main [Snapshot guide](/guide/snapshot) for the general snapshot workflow, update behavior, and review guidelines. +关于通用快照工作流、更新行为和审查指南,请参阅 [快照指南](/guide/snapshot)。 -## Basic Usage +## 基础使用 {#basic-usage} -Given a page with this HTML: +给定一个包含以下 HTML 的页面: ```html
@@ -50,9 +50,9 @@ Given a page with this HTML:
``` -### File Snapshots +### 文件快照 {#file-snapshots} -Use `toMatchAriaSnapshot()` to store the snapshot in a `.snap` file alongside your test: +使用 `toMatchAriaSnapshot()` 将快照存储在与测试文件同目录的 `.snap` 文件中: ```ts [basic.test.ts] import { expect, test } from 'vitest' @@ -62,10 +62,10 @@ test('login form', async () => { }) ``` -On first run, Vitest generates a snapshot file entry: +首次运行时,Vitest 会生成一条快照文件记录: ```js [__snapshots__/basic.test.ts.snap] -// Vitest Snapshot ... +// Vitest 快照... exports[`login form 1`] = ` - form "Log In": @@ -75,9 +75,9 @@ exports[`login form 1`] = ` ` ``` -### Inline Snapshots +### 内联快照 {#inline-snapshots} -Use `toMatchAriaInlineSnapshot()` to store the snapshot directly in the test file: +使用 `toMatchAriaInlineSnapshot()` 将快照直接存储在测试文件中: ```ts import { expect, test } from 'vitest' @@ -92,9 +92,9 @@ test('login form', async () => { }) ``` -## Browser Mode Retry Behavior +## 浏览器模式的重试行为 {#browser-mode-retry-behavior} -In [Browser Mode](/guide/browser/), `expect.element()` polls the DOM and waits for the accessibility tree to **stabilize** before evaluating the result. On each poll, the matcher re-queries the element and re-captures the accessibility tree. The snapshot is considered stable when two consecutive polls produce the same output. +在 [浏览器模式](/guide/browser/) 中,`expect.element()` 会轮询 DOM 并等待无障碍树 **稳定** 后再评估结果。每次轮询时,匹配器会重新查询元素并重新捕获无障碍树。当连续两次轮询产生相同输出时,快照即被视为稳定。 ```ts await expect.element(page.getByRole('form')).toMatchAriaInlineSnapshot(` @@ -105,17 +105,17 @@ await expect.element(page.getByRole('form')).toMatchAriaInlineSnapshot(` `) ``` -On first run or with `--update`, the stable result is written as the new snapshot. +首次运行或使用 `--update` 时,稳定结果会被写入作为新快照。 -When an existing snapshot is present, the matcher also checks whether the stable result matches. If it does not, polling resets and continues — giving the DOM time to reach the expected state. This handles cases like animations, async rendering, or delayed state updates where the tree may briefly stabilize in an intermediate state before settling into its final form. +当已存在快照时,这个匹配器还会检查当前稳定下来的结果是否与快照一致。如果不一致,轮询就会重置并继续进行,从而给 DOM 留出时间到达期望状态。这可以处理诸如动画、异步渲染或延迟状态更新之类的情况:在这些场景中,树结构可能会先短暂稳定在某个中间状态,然后才最终稳定到目标状态。 -## Preserving Hand-Edited Patterns +## 保留手动编辑的模式 {#preserving-hand-edited-patterns} -When you hand-edit a snapshot to use regex patterns, those patterns survive `--update`. Only the literal parts that changed are overwritten. This lets you write flexible assertions that don't break when content changes. +当你手动编辑快照并使用正则模式时,这些匹配规则在 `--update` 后仍会保留。只有发生更改的字面量会被覆盖。这让你可以编写灵活的断言,在内容变化时不会失效。 -### Example +### 示例 {#example} -**Step 1.** Your shopping cart page renders this HTML: +**步骤 1.** 你的购物车页面渲染了以下 HTML: ```html

Your Cart

@@ -125,7 +125,7 @@ When you hand-edit a snapshot to use regex patterns, those patterns survive `--u ``` -You run your test for the first time with `--update`. Vitest generates the snapshot: +你首次使用 `--update` 运行测试。Vitest 生成了快照: ```yaml - heading "Your Cart" [level=1] @@ -134,7 +134,7 @@ You run your test for the first time with `--update`. Vitest generates the snaps - button "Checkout" ``` -**Step 2.** The item names and prices are seeded test data that may change. You hand-edit those lines to regex patterns, but keep the stable structure as literals: +**步骤 2.** 商品名称和价格是可能变化的种子测试数据。你手动将这些行编辑为正则表达式模式,但将稳定的结构保留为字面量: ```yaml - heading "Your Cart" [level=1] @@ -143,7 +143,7 @@ You run your test for the first time with `--update`. Vitest generates the snaps - button "Checkout" ``` -**Step 3.** Later, a developer renames the button from "Checkout" to "Place Order". Running `--update` updates that literal but preserves your regex patterns: +**步骤 3.** 后来,开发者将按钮从 “Checkout” 重命名为 “Place Order”。运行 `--update` 会更新该字面量,但保留你的正则表达式模式: ```yaml - heading "Your Cart" [level=1] @@ -152,35 +152,35 @@ You run your test for the first time with `--update`. Vitest generates the snaps - button "Place Order" 👈 New snapshot updated with new string ``` -The regex patterns you wrote in step 2 are preserved because they still match the actual content. Only the mismatched literal "Checkout" was updated to "Place Order". +你在步骤 2 中编写的正则表达式模式被保留,因为它们仍然匹配实际内容。只有不匹配的字面量 “Checkout” 被更新为 “Place Order”。 -## Snapshot Format +## 快照格式 {#snapshot-format} -ARIA snapshots use a YAML-like syntax. Each line represents a node in the accessibility tree. +ARIA 快照使用类似 YAML 的语法。每行代表无障碍树中的一个节点。 -::: info -ARIA snapshot templates use a **subset of YAML** syntax. Only the features needed for accessibility trees are supported: scalar values, nested mappings via indentation, and sequences (`- item`). Advanced YAML features like anchors, tags, flow collections, and multi-line scalars are not supported. +:::info +ARIA 快照模板使用 **YAML 语法的子集**。仅支持无障碍树所需的功能:标量值、通过缩进实现的嵌套映射以及序列(`- item`)。不支持 YAML 的高级功能,如锚点、标签、流集合和多行标量。 -Captured text is also whitespace-normalized before it is rendered into the snapshot. Newlines, `
` line breaks, tabs, and repeated whitespace collapse to single spaces, so multi-line DOM text is emitted as a single-line snapshot value. +捕获的文本在渲染到快照之前也会进行空白字符规范化。换行符、`
` 换行、制表符和重复的空白字符都会折叠为单个空格,因此多行 DOM 文本会以单行快照值的形式输出。 ::: -Each accessible element in the tree is represented as a YAML node: +树中的每个无障碍元素都表示为一个 YAML 节点: ```yaml - role "name" [attribute=value] ``` -- `role`: The ARIA role of the element, such as `heading`, `list`, `listitem`, or `button` -- `"name"`: The [accessible name](https://w3c.github.io/accname/), when present. Quoted strings match exact values, and `/patterns/` match regular expressions -- `[attribute=value]`: Accessibility states and properties such as `checked`, `disabled`, `expanded`, `level`, `pressed`, or `selected` +- `role`:元素的 ARIA 角色,例如 `heading`、`list`、`listitem` 或 `button` +- `"name"`:[无障碍名称](https://w3c.github.io/accname/),当存在时。带引号的字符串匹配精确值,`/patterns/` 匹配正则表达式 +- `[attribute=value]`:无障碍性状态和属性,例如 `checked`、`disabled`、`expanded`、`level`、`pressed` 或 `selected` -These values come from ARIA attributes and the browser's accessibility tree, including semantics inferred from native HTML elements. +这些值来自 ARIA 属性和浏览器的无障碍树,其中也包括从原生 HTML 元素推断出来的语义信息。 -Because ARIA snapshots reflect the browser's accessibility tree, content excluded from that tree, such as `aria-hidden="true"` or `display: none`, does not appear in the snapshot. +由于 ARIA 快照反映的是浏览器的无障碍树,因此那些被排除在无障碍树之外的内容,比如 `aria-hidden="true"` 或 `display: none` 的元素,不会出现在快照中。 -### Roles and Accessible Names +### 角色与无障碍名称 {#roles-and-accessible-names} -For example: +例如: ```html @@ -196,11 +196,11 @@ For example: - textbox "Email" ``` -The role usually comes from the element's native semantics, though it can also be defined with ARIA. The accessible name is computed from text content, associated labels, `aria-label`, `aria-labelledby`, and related naming rules. +角色通常来自元素的原生语义,但也可以通过 ARIA 定义。无障碍名称根据文本内容、关联标签、`aria-label`、`aria-labelledby` 及相关命名规则计算得出。 -For a closer look at how names are computed, see [Accessible Name and Description Computation](https://w3c.github.io/accname/). +要更深入了解名称的计算方式,请参阅 [无障碍名称与描述计算](https://w3c.github.io/accname/)。 -Some content appears in the snapshot as a text node instead of a role-based element: +某些内容在快照中显示为文本节点而非基于角色的元素: ```html Hello world @@ -210,7 +210,7 @@ Some content appears in the snapshot as a text node instead of a role-based elem - text: Hello world ``` -Text values are always serialized on a single line after whitespace normalization. For example: +文本值在经过空白字符规范化后,总是会被序列化到单独一行中。例如: ```html

@@ -224,9 +224,9 @@ Line 4 - paragraph: Line 1 Line 2 Line 3 Line 4 ``` -### Children +### 子元素 {#children} -Child elements appear nested under their parent: +子元素嵌套在其父元素下方显示: ```html