Playwright的expect断言在Cucumber框架中运行报错如何解决
问题修复方案
根因说明
从@playwright/test包直接导入的expect方法,依赖Playwright内置测试运行器的专属执行上下文。而Cucumber的测试步骤运行在自定义World的独立上下文环境中,无法匹配到Playwright要求的测试执行上下文,因此抛出toHaveAttribute must be called during the test错误。
修复步骤
方法一:直接替换expect导入源
Playwright官方提供了独立的断言包,不依赖内置测试运行器上下文,直接替换导入语句即可:
将原有导入
import { expect } from "@playwright/test";
替换为
import { expect } from "@playwright/test/expect";
修改后原有断言代码无需调整,直接可以在Cucumber步骤中正常运行。
方法二:全局挂载到自定义World(推荐多步骤复用)
如果需要在所有Cucumber步骤中统一使用断言,无需每个步骤文件重复导入,可以直接在你项目里的custom-world.ts(即ICustomWorld对应的实现文件)中全局挂载:
- 导入独立断言并扩展World定义:
import { expect } from "@playwright/test/expect"; import { setWorldConstructor, World, IWorldOptions } from "@cucumber/cucumber"; import { Page } from "@playwright/test"; export interface ICustomWorld extends World { page: Page; // 新增expect类型定义 expect: typeof expect; } class CustomWorld extends World implements ICustomWorld { page: Page; expect: typeof expect; constructor(options: IWorldOptions) { super(options); this.expect = expect; // 这里保留你原有page等属性的初始化逻辑 } } setWorldConstructor(CustomWorld);
- 步骤中直接通过this调用断言即可:
Then( "The Menu Niederlassungsdaten is default", async function (this: ICustomWorld) { const { page, expect } = this; // 注意:locator方法不需要加await,原有await属于冗余写法可以直接去掉 const TitleLabel = page.locator('#app > div.container-fluid > div.row.content.justify-content-center > div > div > div > div.col-12.col-md-3.col-lg-2.tabs > div > a.list-group-item.text-center.router-link-exact-active.active'); await expect(TitleLabel).toHaveAttribute("aria-current","page"); } );
可选优化配置
如果断言经常超时,可以统一设置默认断言超时,和Cucumber的全局步骤超时保持一致即可:
// 在custom-world的构造函数或者初始化逻辑中添加 expect.setDefaultTimeout(30000);
内容的提问来源于stack exchange,提问作者KiritoNG
相关产品推荐
相关产品推荐

