# @cerios/playwright-step-decorator 中文文档

规范地址：https://npmcn.com/package/%40cerios/playwright-step-decorator/

版本：2\.3\.0
npm 元数据更新时间：2026-11-05T12:32:16.298Z
中文译文更新时间：2026-11-09T08:11:07.754Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40cerios/playwright-step-decorator
原文对照：https://npmcn.com/package/%40cerios/playwright-step-decorator/?lang=original
项目主页：https://github.com/CeriosTesting/playwright-step-decorator#readme
源码仓库：https://github.com/CeriosTesting/playwright-step-decorator

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：212 kB，9 个文件
- 模块格式：ESM + CJS
- TypeScript 类型：包内自带
- Node.js 要求：\>=18
- 运行依赖：0 个
- peer 依赖：typescript \>=5\.0\.2 \<8，@playwright/test ^1\.51\.0
- 首次发布：2025-06-02T07:08:52.899Z
- 最新版本发布：2026-11-05T12:32:15.773Z
- 近 30 天下载量：4127（2026-10-10 至 2026-11-08，npm 官方下载统计）
- 已发布版本数：13（近 12 个月 7 个）

## 中文简介

创建步法测试的 Playwright 装饰器

## 安装

```sh
npm install @cerios/playwright-step-decorator
```

也可以使用：`pnpm add @cerios/playwright-step-decorator`、`yarn add @cerios/playwright-step-decorator`、`bun add @cerios/playwright-step-decorator`

## README

# 由 Cerios 制作

用于 Playwright 的 TypeScript 装饰器,通过允许您在测试步骤中添加动态,参数化描述,使您的测试步骤更加可读和可追踪.

## 特征

-   **装饰语法** 用于Playwright步骤.
-   **动态说明**: 使用占位符将参数值注入步骤描述.
-   **支持嵌入属性**:在描述中引用嵌入对象属性.
-   **基于索引的占位符**: 按其立场提出的参考论据.
-   **类型安全值占位符**数字 : `__key__` 占位符由羊肉填充,其参数取自装饰法. 你得到完整的自动补全, 和编译器检查 每个密钥 完全有一个选择器.
-   **更好的参数匹配**:命名的占位符现在处理默认值和休息参数更加可靠.
-   **可读复数**: 可能时, 对象和阵列作为步骤描述中的 JSON 提供 .
-   **转发 Playwright 步骤选项**: 传出 `box`, (中文(简体) ), `timeout`,或习惯 `location` 改为 `test.step()`。 。 。 .
-   **准确来源位置**: 报告中的步入位置指实际方法调用站点,而不是装饰器的执行.

* * *

## 安装

```sh
npm install @cerios/playwright-step-decorator
```

### 促进发展

```sh
npm install --save-dev @cerios/playwright-step-decorator
```

* * *

## 使用量

`@step` 是类方法的标准ECMAScript装饰. Playwright的转写器支持这个出盒子. 如果您将测试汇编为 `tsc`,确保 `experimentalDecorators` 未启用 : `@step` 然后没有效果,没有步骤的报告.

**符号命名方法:** babel 版本被 Playwright 所捆绑 `Cannot convert a Symbol value to a string` 在装饰器运行之前,使用以符号命名的方法进行任何装饰。 装饰一种具有正常名称的方法,并从符号名取出:

```typescript
class MyTest {
    @step("Iterate over {{items}}")
    async iterate(items: string[]) {
        // ...
    }

    [run](items: string[]) {
        return this.iterate(items);
    }
}
```

### 导入装饰器

```typescript
import { step, stepResult } from "@cerios/playwright-step-decorator";
```

使用 `stepResult()` 用于非同步 `@step` 解析无值的方法, `stepResult(value)` 当它们解决非函数值时,或 `stepResult(() => { ... })` 当你想要一个有多重动作的小羊羔。 函数输入作为工厂处理,所以如果需要自行解决某个函数,则从lobda中返回,例如: `stepResult(() => actualFunction)`。 。 。 .

### 基本示例

```typescript
class MyTest {
    @step("Login as {{user.name}}")
    async login(user: { name: string }) {
        // ...login logic
    }

    @step("Click button [[0]] times")
    async clickButton(times: number) {
        // ...click logic
    }

    @step("Build greeting for {{name}}")
    buildGreeting(name: string): Promise<string> {
        return stepResult(`Hello ${name}`);
    }

    @step("Prepare greeting for {{name}}")
    prepareGreeting(name: string): Promise<string> {
        return stepResult(() => {
            const greeting = `Hello ${name}`;
            return greeting.toUpperCase();
        });
    }

    @step("Reset the form")
    resetForm(): Promise<void> {
        // No `await` inside and no `async` keyword needed (avoids the require-await lint error)
        this.dirty = false;
        return stepResult();
    }
}
```

### 通过 `test.step()` 选项

您可以通过 Playwright 步骤选项作为唯一的装饰器参数, 或者在您同时想要自定义描述时作为第二个参数 :

```typescript
class MyTest {
    @step("Wait for checkout", { box: true, timeout: 15_000 })
    async waitForCheckout() {
        // ...wait logic
    }

    @step({ timeout: 5_000 })
    async refreshTotals() {
        // Uses the default step name: "MyTest.refreshTotals"
    }

    @step("Open modal", {
        location: { file: "tests/cart.spec.ts", line: 42, column: 7 },
    })
    async openModal() {
        // Uses the explicit location instead of the generated call site
    }

    @step("Submit order", { timeout: 30_000 })
    async submitOrder() {
        // Still auto-generates the call-site location because no custom location was supplied
    }
}
```

* * *

## 如何运作

这个 `@step` 装饰器用 Playwright 将你的承诺返回方法包起来 `test.step`,使用动态描述。 描述中的占位符被运行时的实际参数值所取代.

> **说明:** 装饰方法不需要 `async` 关键词 如果一个方法机构没有 `await`,您可以放弃 `async` 以避开 `require-await` 错误 。 因为装饰的电话是包裹在 `test.step` 呼唤者 `await` 它, 保留返回类型 a `Promise` 返回时 `stepResult()`, (中文(简体) ), `stepResult(value)` 非函数值,或 `stepResult(() => { ... })` 而不是标记方法 `async`数字 :
> 
> ```typescript
> @step("Reset the form")
> resetForm(): Promise<void> {
>   this.dirty = false;
>   return stepResult(); // no `async`, no require-await warning
> }
> 
> @step("Build greeting for {{name}}")
> buildGreeting(name: string): Promise<string> {
>   return stepResult(`Hello ${name}`);
> }
> 
> @step("Prepare greeting for {{name}}")
> prepareGreeting(name: string): Promise<string> {
>   return stepResult(() => {
>       const greeting = `Hello ${name}`;
>       return greeting;
>   });
> }
> ```

### 占位符

-   **命名参数**数字 : `{{param}}` 替换为命名参数的值 `param`。命名的占位符支持标识符参数、默认值和休息参数.
-   **嵌入式财产**数字 : `{{param.prop}}` 替换为财产价值 `prop` 参数 `param`。 。 。 .
-   **基于索引**数字 : `[[0]]`, (中文(简体) ), `[[1]]`,, , , , , , , , . 替换为给定索引中的参数.
-   **数值选择器**数字 : `__key__` (例如 `__0__` 或者说 `__role__`(中文(简体) ) 取而代之的是 `values` 选项。 无 `values`, (中文(简体) ), `__key__` 是文字文本。 见 [数值选择器占位符](https://npmcn.com/package/%40cerios/playwright-step-decorator/#readme-4-value-selector-placeholders)。 。 。 .

当一个占位符对一个对象或数组进行解析时,装饰器在可能时使其成为JSON,因此报告仍然可以读取. 正则表达式,错误, `Map`s 和 `Set`s以可读形式打印出,非常大的对象使用更短,深度有限的形式. 每个占位符在标题上最多添加了1000个字符;较长的值会以如下注释结尾: `… (500 more characters)`。 。 。 .

被嵌入的属性也用于字符串,数字和函数,例如 `{{name.length}}`。 。 。 .

已命名的占位符从方法的来源读取参数名称, 因此保留 `@step` 当与其他装饰器结合时,直接高于方法:

```typescript
class MyTest {
    @retry() // Other decorators go above @step
    @step("Login as {{user.name}}")
    async login(user: { name: string }) {
        // ...
    }
}
```

如果另一个装饰者坐在下面 `@step`, (中文(简体) ), `@step` 可以看到装饰器的包装功能而不是你的参数. 然后一个占位符会因出错而失败,或者如果名称恰好匹配,会读取包装符的参数.

* * *

## 实例

### 1\. 命名和嵌入式占位符

```typescript
class Greeter {
    @step("User: {{user.name}}, Age: {{user.age}}")
    async greet(user: { name: string; age: number }) {
        // ...
    }
}
await new Greeter().greet({ name: "Alice", age: 30 });
// Step description: "User: Alice, Age: 30"
```

### 2\. 索引占位符

```typescript
class Worker {
    @step("First arg is [[0]], second is [[1]]")
    async doSomething(a: string, b: number) {
        // ...
    }
}
await new Worker().doSomething("foo", 42);
// Step description: "First arg is foo, second is 42"
```

### 3\. 混合命名和索引占位符

```typescript
class Example {
    @step("Named: {{name}}, Index: [[1]]")
    async run(name: string, value: number) {
        // ...
    }
}
await new Example().run("Bob", 77);
// Step description: "Named: Bob, Index: 77"
```

### 4\. 数值选择器占位符

使用 `__key__` 当步骤文本需要从参数中计算出某种东西时,例如数组中的一个项目、过滤过的列表或有条件的标签。 每一个关键地图,一个羊肉在 `values` 选项。 羊肉会得到方法的论证 **与真实类型**因此,你的编辑器自动完成它们,编译器检查它们:

```typescript
type Contact = { name: string; email: string; primary: boolean };
type User = { name: string; role: string; contacts: Contact[] };

class ContactsPage {
    @step("Add contacts for __0__ (second: __second__, primary: __primary__)", {
        values: {
            0: user => user.name, // user: User
            second: (_user, contacts) => contacts[1].email, // contacts: Contact[]
            primary: user =>
                user.contacts
                    .filter(c => c.primary)
                    .map(c => c.name)
                    .join(", "),
        },
    })
    async addContacts(user: User, contacts: Contact[]) {
        // ...
    }
}
// Step description: "Add contacts for Alice (second: carol@example.com, primary: Bob, Dave)"
```

`__key__` 占位符仅在您通过时激活 `values` 选项。 没有它,文本例如 `__NEXT_DATA__` 指纹如是.

当你通过 `values` 带有字面描述的编译器执行:

-   每个 `__key__` 在描述中有一个选择器在 `values`, (中文(简体) ),
-   `values` 包含没有在描述中的密钥,
-   每个羊肉达的参数与被装饰方法的参数相匹配. 明确说明,例如: `(user: User) => ...` 被允许,但他们必须匹配.

注释:

-   键可以是数字( E)`__0__` → `{ 0: ... }`或名称(`__role__` → `{ role: ... }`) (中文(简体) ). 密钥是介于 `__` 财务报告和审定财务报表 `__` 没有空白、括号或方括号。 其他跨度,例如 `a __ b __ c` 或者说 `report__{{date}}__final`,保留为文字文本.
-   要打印文字 `__text__` 在同时使用的描述中 `values`,从选择器返回它: `{ literal: () => "__text__" }`。包含完整 `__key__`,例如 `{{a__b__c}}`,不能同时使用 `values`,因此使用索引占位符.
-   Lambdas收到的论据与通过的论点完全相同;省略的任择论据是: `undefined`。 。 。 .
-   Lambdas必须是同步的,因为它们在步骤开始前会跑. 羊肉达能还原承诺会造成错误.
-   回来的羊肉 `null` 或者说 `undefined` 指纹 `null` 或者说 `undefined`对于无效参数,使用可选的链条(`user => user?.name`),编译器在参数类型允许时要求的 `null` 或者说 `undefined`。 。 。 .
-   返回的值与其他任何占位符(字符串为-is,对象为JSON)一样格式化.
-   如果描述是普通的 `string` 变量而不是字元,在编译时无法检查密钥。 缺少选择器, 然后在运行时丢出 .

* * *

## 报告中准确的来源位置

装饰者自动捕捉您装饰方法的呼叫站点位置,并将其传递至 Playwright 的 `test.step()`这意味着:

-   **HTML 报告** 显示使用该方法的正确文件和行号
-   **跟踪查看器** 指向实际测试代码,而不是装饰器执行
-   **日志** 显示准确的源位置以方便调试

此功能使用 Playwright 内置 [`location` 参数](https://playwright.dev/docs/api/class-test#test-step-option-location) 尽可能确保报告各步骤位置有所帮助。 如果你提供 `location` 在装饰者的第二个论点中,使用的是明示值。 否则,装饰器会自动倒回生成的呼叫站点位置.

### 示例

当你在测试中称装饰方法:

```typescript
// my-test.spec.ts
test("example", async ({ page }) => {
    const loginPage = new LoginPage(page);
    await loginPage.login(user); // Line 10
});
```

Playwright 报告将显示步骤位置为 `my-test.spec.ts:10`,而不是装饰器执行的地点.

* * *

## 处理错误

**当分类被定义时 :** 一旦包含类负载的文件投出就永远无法工作的描述,所以即使方法从未被调用,也会找到打字. 发生于:

-   描述中的命名参数在函数签名中不存在.
-   已命名的占位符使用已解结构或以其他方式不支持的参数语法. 错误建议使用索引占位符 .
-   索引占位符超出了已宣布的参数。 使用休息参数的方法 `arguments` 改为在呼叫时检查.
-   A 类 `__key__` 占位符没有选择器 `values`。这也是文字描述的编译时间错误.

由于类名尚不得而知,这些错误只取出方法名.

**当该方法被称为:** 如果一个描述无法为特定调用解答,被装饰方法还原的允诺会拒绝,步骤也不会开始. 发生于:

-   嵌入式属性在参数上不存在. 如果参数(或中间属性)是 `null` 或者说 `undefined`,占位符打印 `null` 或者说 `undefined` 换句话说 在省略对象默认中丢失的财产也是如此.
-   指数占位符已超出通过的论点.
-   省略的参数有一个默认值,不能被打印出. 文字可以被印刷,包括仅由文字制作的物体和阵列,例如: `{ timeout: 5, tags: ["a"] }`任何需要评估的东西,比如 `Mode.Auto`, (中文(简体) ), `{ timeout: DEFAULT_TIMEOUT }` 或者说 `{ ...base }`。 。 。 .
-   A 类 `values` 选择者投出。 拒绝是一个描述性错误, 原始错误为 `cause`。 。 。 .
-   A 类 `values` 选择者返回一个承诺.

* * *

## 访问步骤上下文`getStepInfo`(中文(简体) )

有时您想要将文件,日志,或元数据附加到您装饰方法内的当前 Playwright 步骤中. 使用 `getStepInfo` 函数访问 [`TestStepInfo`](https://playwright.dev/docs/api/class-teststepinfo) 当前步骤的对象.

### 示例

```typescript
import { step, getStepInfo } from "@cerios/playwright-step-decorator";

class NavbarTest {
    @step("Assert the navbar items are as expected")
    async assertNavbarItems(expectedItems: string[]): Promise<void> {
        const stepInfo = getStepInfo();
        await stepInfo.attach("expected-items.json", {
            body: JSON.stringify(expectedItems),
            contentType: "application/json",
        });
        // ...your assertions...
        await stepInfo.attach("actual-items.json", {
            body: JSON.stringify(await this.navbarItem.allInnerTexts()),
            contentType: "application/json",
        });
    }
}
```

**说明:**

-   `getStepInfo()` 财务报告和审定财务报表 `getStepInfo(this)` 必须在一种用 `@step`。 。 。 .
-   步骤上下文按协同引用进行跟踪,因此同时 `Promise.all(...)` 要求同一机构保持自己的地位 `TestStepInfo`。 。 。 .
-   如果在步骤上下文之外调用, 则丢出错误 .

* * *

## API 密码

### `step(description: string)`

-   **说明**: 步骤描述,支持占位符类似 `{{param}}`, (中文(简体) ), `{{param.prop}}`,或 `[[index]]`。 。 。 .
-   **回返**:用于承诺回放方法的装饰器功能.

### `step(description: string, options)`

-   **选项.box / 选项.timeout / 选项. 位置**: 转发到 Playwright 的 `test.step()`。 。 。 .
-   **选项**: 每个对象映射 `__key__` 对羊肉的描述中的占位符 `(...methodArgs) => unknown`通过它打开 `__key__` 描述的占位符.

### `step(options)`

-   **选项**: Playwright 步骤选项; 该步骤使用默认 `ClassName.methodName` 说明.

导出帮助类型 : `StepOptions`, (中文(简体) ), `StepValueSelector<Args>`, (中文(简体) ), `StepValues<Description, Args>`, (中文(简体) ), `StepOptionsWithValues<Description, Args>`,以及 `ValuePlaceholderKeys<Description>`。 。 。 .

### `getStepInfo()`

-   **回返**: 当前剧作家 `TestStepInfo` 用于激活的装饰方法调用.

### `getStepInfo(instance)`

-   **实例**: 保留与更早的发行相倒相容.
-   **回返**: 当前剧作家 `TestStepInfo` 用于激活的装饰方法调用.

### `stepResult()`

-   **回返**数字 : `Promise<void>` 用于非同步 `@step` 不返回值的方法.

### `stepResult(value)`

-   **价值**: 非函数值需要解决.
-   **回返**数字 : `Promise<Awaited<T>>` 用于非同步 `@step` 返回一个值的方法.

### `stepResult(() => value)`

-   **回调**: 一个零参数的羊肉,在返回一个值之前可以执行多个同步动作.
-   **回返**数字 : `Promise<Awaited<T>>` 带有回调结果,如果回调投出则拒绝.

如果您需要解决一个函数值本身,请以回调形式将其包入: `stepResult(() => actualFunction)`。 。 。 .

* * *

## 许可证

麻省理工学院

* * *

## 作者

罗纳德·韦斯 - Cerios

* * *

## 捐款

欢迎拉出请求! 请先打开一个问题来讨论你想要改变什么.

* * *

## 链接

-   [国家防范机制一揽子计划](https://www.npmjs.com/package/@cerios/playwright-step-decorator)
-   [GitHub 仓库](https://github.com/CeriosTesting/playwright-step-decorator)

## 常见问题

### @cerios/playwright-step-decorator 是什么？

创建步法测试的 Playwright 装饰器

### 如何安装 @cerios/playwright-step-decorator？

在项目目录运行 npm install @cerios/playwright-step-decorator，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@playwright/test（^1\.51\.0）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @cerios/playwright-step-decorator 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @cerios/playwright-step-decorator 支持 ESM 还是 CommonJS？

同时提供 ES Module 与 CommonJS 入口，import 和 require\(\) 都可以使用，打包工具会自动选择合适的版本。

### @cerios/playwright-step-decorator 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js \>=18。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @cerios/playwright-step-decorator 可以商用吗？

@cerios/playwright-step-decorator 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @cerios/playwright-step-decorator 的下载量有多少？

根据 npm 官方下载统计，@cerios/playwright-step-decorator 在 2026/10/10 – 2026/11/08 这 30 天内被下载 4,127 次，日均约 138 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @cerios/playwright-step-decorator 还在维护吗？

最新版本 2\.3\.0 发布于 2026/11/05（3 天前）；至今共发布 13 个版本，其中过去 12 个月发布了 7 个；首次发布于 2025/06/02。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

