#javascript #cypress #chai #assertion
#javascript #cypress #чай #утверждение
Вопрос:
В Cypress test мне часто нужно проверить, соответствует ли текст в элементе 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');
Но я не могу найти ни одного документа на официальном сайте об этом. Кто-нибудь поделится каким-нибудь примером?
Ответ №1:
Наконец, я нахожу способ сделать это. Хотя Cypress не предоставляет такой функции, но поскольку Cypress использует Chai, мы можем просто определить методы Chai.
Примечание: определить это невозможно have.text.trimmed
, поскольку метод утверждения text
является методом Chai. вместо цепочечного метода нет способа предоставить trimmed
после него.
Но все еще есть два варианта:
-
Определите метод Chai
textTrimmed
. Это позволяет нам использовать.should('have.textTrimmed', 'sometext')
, что предпочтительнее, поскольку мы можем определить пользовательское сообщение с утверждением и без сложного взлома экземпляров jQuery. -
Определите метод Chai chainable
trimmed
. Это позволяет использовать.should('have.trimmed.text', 'sometext')
, который, кажется, работает, но утверждение определяется методом Chaitext
, что может привести к путанице. Это не рекомендуется.
have.textTrimmed
Это в TypeScript:
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
Ответ №2:
В настоящее время это невозможно из коробки для Cypress. Запрос на функцию заключается в том, чтобы предоставить «Cypress» способ доступа к команде textContent (и / или innerText) — .text() (#630).
Но вы можете обойти это, добавив пользовательские команды в support/commands.js и используйте эти команды в вашем testscript. В конечном итоге вы получите это в commands.js:
Cypress.Commands.add('haveText', function (text) {
cy.get('.cell')
.then($cell => $cell.text().trim())
.should('eq', text)
})
В тестовом скрипте вы получите:
cy.haveText('Hello')
Вместо использования trim()
в command.js вы также могли бы использовать contains()
, это приводит к частичному совпадению, поэтому пробелы не являются проблемой (обратите внимание, что ‘apple pie’ также соответствует требованиям, если вы ищете ‘apple’, если это не проблема, вы можете использовать contains()
. Commands.js будет выглядеть следующим образом:
Cypress.Commands.add('haveText', function (text) {
cy.get('.cell')
.should('contains', text)
})
Но что, вероятно, еще больше соответствует вашим требованиям, так это использование contains()
в сочетании с регулярным выражением. Вам не нужны никакие скрипты в commands.js но только в тестовом скрипте вы можете использовать это:
cy.contains(/^s*Hellos*$/))
s*
Должен соответствовать любому символу пробела ноль или более раз.
^
Заключается в том, чтобы начать сопоставление в начале текста
$
Заключается в том, чтобы завершить сопоставление в конце текста.
Регулярное выражение не может быть использовано в should()
, к сожалению, достаточно.
Комментарии:
1. Спасибо. Использование command — это возможный способ, но для меня это немного тяжеловато. И использование
contains
не полностью соответствует моим требованиям, например, ячейка имеет содержимоеHello world
, которое удовлетворяет.should('contains', 'Hello')
, но это не то, что я хочу2. чек, вот почему я действительно объяснил нечеткость чека. Но, насколько я знаю, вы не можете создавать пользовательские утверждения. Я добавлю еще одно предложение к своему ответу.
3. Спасибо за обновление. Я собираюсь создать проблему в cypress github
4. Еще раз обновил мой ответ, добавив к запросу функции. Не знал, что запрос функции для Cypress уже существует.
5. Я нахожу способ сделать это, пожалуйста, смотрите мой ответ