You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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对应的实现文件)中全局挂载:

  1. 导入独立断言并扩展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);
  1. 步骤中直接通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 02:54:06