赛普拉斯:在第一次失败时中断所有测试

Cypress: interrupt all tests on first failure

如何在第一次测试失败时中断所有 Cypress 测试?

我们正在使用信号量通过赛普拉斯为每个 PR 启动完整的端到端测试。但是太费时间了。

我想在第一次测试失败时中断所有测试。

得到完整的错误是每个开发者在开发时的职责。如果在部署之前出现任何问题,我只想尽快得到通知,而不必等待完整测试完成。

到目前为止,我想到的唯一解决方案是使用 Cypress 中断对当前规范文件的测试。

afterEach(() => {
        if (this.currentTest.state === 'failed') {
            Cypress.runner.end();
        }
    });

但这还不够,因为它只中断位于规范文件的测试,而不是所有其他文件。我今天对这个问题进行了深入的搜索,但它似乎不是 Cypress 上的东西。

所以我正在尝试其他解决方案。

1: 带信号量

fail_fast:
  stop:
    when: "true"

它应该在错误时中断脚本。但它不起作用:测试在出错后保持 运行。我的猜测是只有当所有测试都完成时,Cypress 才会抛出错误。

2:也许用脚本启动赛普拉斯,但我没有想法 现在这是我的脚本

"cy:run": "npx cypress run",
"cy:run:dev": "CYPRESS_env=dev npx cypress run",
"cy:test": "start-server-and-test start http-get://localhost:4202 cy:run"

编辑: 似乎引入了此功能,但它需要 Cypress(商业计划)的付费版本。更多相关信息:Docs, comment in the thread


原回答:

这是 Cypress 长期以来要求的功能,但由于某种原因仍未引入。社区提出了一些解决方法,但不能保证它们会起作用。 Check this thread on Cypress' Github for more details, maybe you will find a workaround that works for your case.

一个对我有用的小技巧

Cypress.Commands.add('interrupt', () => {
  eval("window.top.document.body.querySelector('header button.stop').click()");
});

@user3504541 的解决方案非常棒!万分感谢。我已经开始放弃使用 Cypress,因为这些问题不断出现。但无论如何,这是我的配置:

support/index.ts

declare global {
  // eslint-disable-next-line
  namespace Cypress {
    interface Chainable {
      interrupt: () => void
    }
  }
}

function abortEarly() {
  if (this.currentTest.state === 'failed') {
    return cy.task('shouldSkip', true)
  }
  cy.task('shouldSkip').then(value => {
    if (value) return cy.interrupt()
  })
}

commands/index.ts

Cypress.Commands.add('interrupt', () => {
  eval("window.top.document.body.querySelector('header button.stop').click()")
})

在我的例子中,赛普拉斯测试在 CI(Github 操作工作流程)上无限期地挂起,但通过此修复它们可以正确中断。