Основная проблема c заключается в том, что команды Cypress запускаются асинхронно из тестового кода, который их создает. Это можно увидеть, если вы поместите консольные журналы в свой код,
var myID;
cy.get('#MYID')
.then(($txt) => {
myID= $txt.text();
console.log('1', myID);
})
.should('not.equal', null);
console.log('2', myID);
Это напечатает
2 undefined
1 myText
Вы можете использовать псевдоним, чтобы преодолеть это и передать значение по цепочке команд .
См. Этот раздел документации , в котором показан аналогичный код, который вы используете в примере НЕ ИСПОЛЬЗУЙТЕ.
НО псевдонимы очищаются между тестами, поэтому вы должны установить beforeEach()
для получения новой копии требуемого идентификатора для каждого теста.
Существует другая проблема с способом получения текстового значения.
Без оператора возврата команда .then()
передает объект, который она получает, следующей команде. См. then- Yields
Кроме того, результат последней команды Cypress в функции обратного вызова будет передан как новый субъект и передан следующей команде если нет возврата .
Таким образом, .should('not.equal', null)
проверяет, что элемент не нулевой, а не то, что текст не нулевой.
Лучший способ - .invoke('text')
, что эквивалентно $txt.text()
и возвращает текстовое значение для .should()
.
Также .should('not.equal', null)
не будет проверять наличие содержимого, так как пустое элемент возвращает пустую строку из element.text()
. Вместо этого используйте .should('not.equal', '')
.
Сохранение с помощью псевдонима
describe('grabbing ID for use in multiple tests', () => {
beforeEach(() => {
cy.visit('my-page-1.html')
cy.get('#MYID')
.invoke('text')
.as('mySavedID')
})
it('ID should not be null', () => {
cy.get('@mySavedID')
.should('not.equal', '')
})
it('ID should be found in table', () => {
cy.visit('app/navigate-to-new-page-2.html');
cy.get('@mySavedID').then(myID => {
cy.get('#myTable').find('td').contains(myID);
})
})
})
Сохранение путем постановки в очередь установки переменной
Шаблон псевдонима может быть не идеальным, если посещение страницы №1 занимает много времени.
В этом случае вы можете сохранить переменную с помощью специальной команды. Разница в том, что код, который вы имели внутри .then()
, перемещается в команду, находящуюся в очереди, поэтому проблема asyn c не возникает.
describe('grabbing ID for use in multiple tests', () => {
let savedVariable;
Cypress.Commands.add("saveVariable", {prevSubject: true}, (value) => {
savedVariable = value;
});
it('id should not be null', () => {
cy.visit('my-page-1')
cy.get('#someId')
.invoke('text')
.should('not.equal', '')
.saveVariable()
// OR test the variable separately like this
cy.wrap(savedVariable)
.should('not.equal', '')
})
it('id should be found in table', () => {
cy.visit('my-page-2');
cy.get('#myTable').find('td').contains(savedVariable);
})
})
NOTE
Вышеуказанное действительно, если две страницы находятся в одном домене, например, две страницы SPA. В противном случае тестовый организатор сбрасывает себя, когда встречается новый домен, и все javascript переменные теряются.