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

如何在TestCafe中实现可链式调用的自定义测试动作?

实现TestCafe链式自定义动作方案

要实现你想要的链式调用风格,核心思路是用建造者模式封装断言逻辑:先通过链式方法收集验证条件,最后用done()触发实际的TestCafe动作并返回符合要求的TestControllerPromise,无缝接入原有动作链。

具体实现代码

import { Selector, t } from 'testcafe';

// 定义链式动作建造器类
class DialogActionBuilder {
  constructor(testController) {
    this.t = testController;
    this.dialogSelector = Selector('.dialog'); // 替换为你的实际弹窗选择器
    this.conditions = [];
  }

  // 初始化弹窗查找逻辑
  toFindOneDialogElement() {
    this.conditions.push(() => this.t.expect(this.dialogSelector.exists).ok('目标弹窗未找到'));
    return this; // 返回自身,支持链式调用
  }

  // 添加标题精确匹配条件
  withExactTitle(title) {
    const titleSelector = this.dialogSelector.find('.dialog-title');
    this.conditions.push(() => this.t.expect(titleSelector.textContent).eql(title, `弹窗标题不匹配:期望"${title}"`));
    return this;
  }

  // 语法糖方法,仅提升可读性,直接返回自身
  and() {
    return this;
  }

  // 添加内容精确匹配条件
  withExactBodyText(bodyText) {
    const bodySelector = this.dialogSelector.find('.dialog-body');
    this.conditions.push(() => this.t.expect(bodySelector.textContent).eql(bodyText, `弹窗内容不匹配:期望"${bodyText}"`));
    return this;
  }

  // 执行所有收集的条件,返回TestControllerPromise以接入动作链
  async done() {
    // 依次执行所有断言
    for (const condition of this.conditions) {
      await condition();
    }
    // 返回TestController实例,确保动作链可继续
    return this.t;
  }
}

// 将customActions挂载到TestController原型上
Object.defineProperty(t.constructor.prototype, 'customActions', {
  get() {
    return new DialogActionBuilder(this);
  }
});

使用方式(与你期望的完全一致)

await t
  .click(Selector('#open-dialog-btn'))
  .customActions
    .toFindOneDialogElement()
    .withExactTitle("My Title")
    .and()
    .withExactBodyText("My content")
    .done()
  .click(Selector('#close-dialog-btn'));

关键原理说明

  1. 链式调用的实现:所有中间方法(toFindOneDialogElement、withExactTitle等)都返回建造器实例本身,因此无需await即可连续调用,完全贴合你要的语法风格。这些方法仅收集验证逻辑,不立即执行断言。
  2. 适配TestCafe动作链规则:只有done()方法会执行实际的异步断言,并返回TestController实例(或其Promise),TestCafe的动作链会自动处理该返回值,无需额外await就能继续后续的.click()等内置动作。
  3. 隔离性与扩展性:每次访问customActions都会创建新的建造器实例,避免不同测试用例的条件互相干扰;你可以轻松添加更多链式方法(如withPartialTitle、withCloseButtonEnabled等),只需在conditions数组中追加对应断言逻辑即可。

内容的提问来源于stack exchange,提问作者Investor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:22:46