Cucumber JS - 是否可以在 setDefinitionFunction Wrapper 中以编程方式设置默认超时值?

Cucumber JS - Is it possible to programatically set defaultTimeout value in setDefinitionFunctionWrapper?

开箱即用的 Cucumber 提供了一种方法来设置每个步骤的默认超时,或者所有步骤将通过使用 setDefaultTimeout(value).

使用的 'global' 超时

但是,没有办法让场景级别超时,即整个场景应该在 X 毫秒后超时。

我现在的情况是我需要确保任何给定的场景不会 运行 超过 X 分钟,但我还需要这个过程用任何 After hooks 干净地结束 运行宁好像测试失败了。我的想法是做这样的事情:

const MAX_DURATION = 2 * 60 * 1000;
let startTime: number | undefined;
let endTime: number | undefined;

setDefinitionFunctionWrapper(function(func: Function) {
  return async function(this: any, ...args: any[]) {
    if(startTime && endTime) {
      setDefaultTimeout(Math.max(endTime - Date.now(), 0));
    }

    return await func.apply(this, args);
  };
});

Before(() => {
  startTime = Date.now();
  endTime = startTime + 1000;
});

理论是,在每个场景之前,我现在抓住时间,计算出超时时间,然后在每个步骤之前将默认超时设置为 endTime 值减去现在时间。

虽然这不起作用。我假设当在 Cucumber 库中构建步骤时,超时是在每个步骤级别计算的并且无法更改。

我不能简单地使用 setTimeout 并抛出错误,因为这会导致未处理的 promise 异常并且 Cucumber 会退出。

有没有人尝试过类似的东西,或者对如何实现有任何想法?

所以我重新考虑了我的方法,类似这样的方法似乎可以解决问题:

setDefinitionFunctionWrapper(function (func: Function) {
  return async function (this: any, ...args: []) {
    if (!maxEndTime) return await func.apply(this, args);

    let id: NodeJS.Timeout | undefined;
    const execution = func.apply(this, args);
    const timeout = new Promise((resolve) => {
      id = global.setTimeout(() => {
        hasTimedOut = true;
        resolve('skipped');
      }, Math.max(maxEndTime - Date.now(), 0));
    });

    const res = await Promise.race([execution, timeout]);
    if (id) clearTimeout(id);

    return res;
  };
});

这会创建两个承诺 - 一个在指定的超时后解决,一个测试步骤完成。然后我和他们比赛,谁先解决谁就赢!

然后我在别处处理 hasTimedOut 值以针对该结果做适当的事情。