使用 cypress-cucumber-preprocessor 重复 cy.session 之前的每个步骤

BeforeEach step is repeated with cy.session using cypress-cucumber-preprocessor

我有一个 Cypress 项目,我在其中使用 Cypress 会话 API 在整个功能中维护一个会话。

现在我尝试从已弃用的 Klaveness Cypress Cucumber Preprocessor to the replacement, Badeball's Cypress Cucumber Preprocessor 切换。但是我 运行 遇到了问题;在测试开始之前,我进行身份验证的 beforeEach() 步骤会重复多次。最终,赛普拉斯“跳出它”并开始 运行 实际测试 - 但显然这是非常耗费资源和时间的,出了点问题。

我的设置:

依赖关系:

    "cypress": "^9.6.1",
    "@badeball/cypress-cucumber-preprocessor": "^9.1.3",

index.ts:

beforeEach(() => {
  let isAuthInitialized = false;
  function spyOnAuthInitialized(window: Window) {
    window.addEventListener('react:authIsInitialized', () => {
      isAuthInitialized = true;
    });
  }

  login();
  cy.visit('/', { onBeforeLoad: spyOnAuthInitialized });
  cy.waitUntil(() => isAuthInitialized, { timeout: 30000 });
});

登录()函数:

export function login() {
  cy.session('auth', () => {
    cy.authenticate();
  });
}

据我所知,我几乎完全按照 cy.session 的文档进行操作。

我的身份验证命令只有特定于应用程序的步骤,它包含 cy.visit('/') - 之后我的应用程序被重定向到登录服务(不同的域)然后继续。

问题

cy.session 工作正常,它会在第一次尝试时创建一个会话 - 随后每次它都会记录有效会话的成功恢复。但是多次出现这种情况,好像卡在了一个循环里。

截图:

在我看来 cy.visit() 又以某种方式触发了 beforeEach()。也许清除了一些导致我的身份验证重定向再次发生的会话数据(本地存储?) - 或者以某种方式让赛普拉斯认为测试重新开始。但是当然 beforeEach() 每个功能应该只发生一次。

我正在查看我的代码更改的差异,除了预处理器更改之外,唯一的区别是:

我是否在查看预处理器中的错误?我做错了吗?或者别的什么?

带有预处理器的 Cypress + Cucumber 有两个方面可能会造成混淆

  1. 赛普拉斯“运行 所有规格”行为

正如 Gleb Bahmutov PhD's 很棒的博客 post 中所展示的那样,如果您不配置 Cypress 做其他事情,运行 宁所有规范 运行 s 每个测试前的每个钩子。他提出的解决方案是不使用“运行 所有规格”按钮,我觉得这太过分了——因为有办法解决这个问题;请参阅下面的 Cucumber 预处理器的工作解决方案。

  1. Cucumber 预处理器配置

Cypress Cucumber 预处理器建议不要使用配置选项 nonGlobalStepDefinitions,而是配置特定路径,例如 (source):

  "stepDefinitions": [
    "cypress/integration/[filepath]/**/*.{js,ts}",
    "cypress/integration/[filepath].{js,ts}",
    "cypress/support/step_definitions/**/*.{js,ts}",
  ]
}

但它没有明确说明的是,如果您不希望包含您的钩子的文件(在我的例子中 index.ts)应该从这些路径中排除 运行 每次测试!我可以看出人们可能认为这是显而易见的,但很容易意外地将您的挂钩文件包含在此文件路径配置中。

TLDR:如果我从我的 stepDefinitions 配置中排除包含我的钩子的 index.ts 文件,我可以按预期使用“运行 所有规格”- beforeEach() 运行每次测试前只打一次。