当没有创建承诺时,赛普拉斯检测到承诺

Cypress detected a promise when no promises were created

我有这个 Cypress 命令,我正在检查 .row 中的元素。如果我循环遍历 .row 元素,它工作正常,但如果我传递特定的 .row 元素,它会失败。我不确定如何处理错误消息,因为我没有在任何地方使用 promises。

命令:

Cypress.Commands.add('normalRowCheck', row => {
    cy.wrap(row).find('button').should('have.text', 'X')
    cy.wrap(row).find('form').should('not.exist')
    cy.wrap(row).find('input').should('not.exist')
    cy.wrap(row).should('have.class', 'row')
})

作品:

cy.get('.row').each((row, i) => { 
    cy.wrap(row).find('div').should('have.text', 'Adding Task ' + (i+4))
    cy.normalRowCheck(row)
})

无效:

cy.normalRowCheck(cy.get('.row').last())

错误:首次调用 cy.wrap

时出现

Cypress 检测到您 return 从一个命令中调用了一个 promise,同时还在该 promise 中调用了一个或多个 cy 命令。

return承诺的命令是:

cy.wrap()

您在 promise 中调用的 cy 命令是:

cy.then()

因为 Cypress 命令已经是类似 promise 的,所以您不需要包装它们或 return 您自己的 promise。

无论最终的 Cypress 命令产生什么结果,Cypress 都会解析您的命令。

这是一个错误而不是警告的原因是因为赛普拉斯在内部对命令进行连续排队,而 Promises 在它们被调用时立即执行。尝试调和这将阻止赛普拉斯解决。

  1. 我认为声明 row => 应该是 cy.get('row').last() 是错误的。
  2. 我不认为在您尝试在第二个示例中包装之前,赛普拉斯已经完成了 row 的元素生成。您可以通过多种方式解决此问题,但这里有两个示例。

首先,您可以简单地将生成的元素传递给您的自定义命令可以正确包装的 .then(), which then has a JQuery element

// using a `.then()`
cy.get('.row').last().then(($row) => {
  cy.normalRowCheck($row);
})

您可以将自定义命令修改为自动成为 child command that requires an element,,而不必亲自实际传递该行。

// modifying your custom commands to receive the previously yielded subject
Cypress.Commands.add('normalRowCheck', {prevSubject: 'element'}, (row) => {
    cy.wrap(row).find('button').should('have.text', 'X')
    cy.wrap(row).find('form').should('not.exist')
    cy.wrap(row).find('input').should('not.exist')
    cy.wrap(row).should('have.class', 'row')
});

// using the command
cy.get('.row').last().normalRowCheck();
// using the command with .each()
cy.get('.row').each((row, i) => { 
    cy.wrap(row).find('div').should('have.text', 'Adding Task ' + (i+4))
  cy.wrap(row).normalRowCheck();
});

作为另一点建议,混合变量和赛普拉斯命令通常不会在没有大量测试您的代码将执行并且没有任何竞争条件的情况下起作用。如果可能,请尝试链接您的命令,或消除将某些内容声明为变量的需要。