如何在cypress中定义自定义断言运算符?

问题描述 投票:0回答:2

在cypress测试中,我经常需要检查DOM元素中的文本是否与某些预期测试相等。但由于文本周围可能有一些空格,我不能简单地写:

cy.get('.cell')
  .should('have.text', 'Hello')

相反,我必须写:

cy.get('.cell')
  .then($cell => $cell.text().trim())
  .should('eq', 'Hello')

我想定义像have.text.trimmed这样的自定义断言运算符,允许我像这样使用它:

cy.get('.cell')
  .should('have.text.trimmed', 'Hello');

但我在官方网站上找不到任何关于它的文件,有人会和我分享一些例子吗?

cypress assertion
2个回答
2
投票

最后我找到了做到这一点的方法。虽然柏树不提供这样的功能,但由于柏树使用柴,我们可以只定义柴方法。

注意:不可能定义have.text.trimmed,因为断言方法text是一个chai方法,而不是一个可链接的方法,没有办法在它之后提供trimmed

但仍有两种选择:

  1. 定义一个chai方法textTrimmed,允许我们使用.should('have.textTrimmed', 'sometext'),这是首选,因为我们可以定义自定义断言消息,而不是对JQuery实例进行棘手的黑客攻击。
  2. 定义一个chai链式方法trimmed,允许使用.should('have.trimmed.text', 'sometext'),这似乎工作,但断言是由chai方法text决定,这可能是混乱。不建议。

have.textTrimmed

这是打字稿:

chai.Assertion.addMethod('textTrimmed', function (expectedString: string) {
  const $element = this._obj;

  new chai.Assertion($element).to.be.exist;

  const actual = $element.text().trim();
  const expected = expectedString.trim();
  this.assert(
    actual === expected
    , 'expected #{this} to have text #{exp} after trimmed, but the text was #{act} after trimmed'
    , 'expected #{this} not to have text #{exp} after trimmed'
    , expected
    , actual
  );
});

将代码放在cypress/support/index.js中以确保在测试之前运行它。

您可能希望在此处看到完整的演示:https://github.com/freewind-demos/typescript-cypress-add-custom-assertion-method-textTrimmed-demo/blob/master/cypress/support/textTrimmed.ts

have.trimmed.text

chai.use((chai, utils) => {

  chai.Assertion.addChainableMethod("trimmed", () => {
  }, function () {
    const obj = utils.flag(this, 'object')

    const oldText = obj.text.bind(obj);
    obj.text = () => {
      return oldText().trim()
    }
  });
})

正如我所说的那样,因为棘手的黑客和不明确的断言信息而不推荐。

您还可以在这里看到完整的演示:https://github.com/freewind-demos/typescript-cypress-custom-operator-have-trimmed-text-demo/blob/master/cypress/support/index.ts


1
投票

目前,柏树不可能开箱即用。功能请求是https://github.com/cypress-io/cypress/issues/630

但是你可以通过添加自定义命令来支持/ commands.js并在testcript中使用这些命令来解决它。你最终会在commands.js中得到的结果是:

Cypress.Commands.add('haveText', function (text) {
  cy.get('.cell')
  .then($cell => $cell.text().trim())
  .should('eq', text)
})

在测试文档中,您将最终得到:

cy.haveText('Hello')

而不是在command.js中使用trim()你也可以使用contains(),这是一个部分匹配所以空格是没有问题的(注意'苹果派'如果你找'苹果'也符合要求,如果那不是问题你可以使用contains().Commands.js看起来像这样:

Cypress.Commands.add('haveText', function (text) {
  cy.get('.cell')
  .should('contains', text)
})

但更可能满足您的要求的是将contains()与正则表达式结合使用。您在commands.js中不需要任何脚本,但只需在testscript中就可以使用:

cy.contains(/^\s*Hello\s*$/))

\s*用于匹配任何空白字符零次或多次。 ^将在文本的开头开始匹配.$将在文本的末尾结束匹配。

正则表达式不能在should()内使用

© www.soinside.com 2019 - 2024. All rights reserved.