then() и wrap()

Cypress предоставляет мощные инструменты для управления асинхронным кодом и работы с цепочками команд. Основными механизмами для этого являются методы then() и wrap(), которые позволяют контролировать поток выполнения тестов, обрабатывать значения и интегрировать произвольные функции.


Метод then()

Метод then() используется для выполнения произвольных действий с результатом предыдущей команды Cypress после того, как она завершилась. Это позволяет работать с асинхронными операциями так, будто они синхронны, сохраняя цепочку команд.

Синтаксис:

cy.get('selector').then((element) => {
  // обработка элемента
});

Особенности использования:

  1. then() получает результат предыдущей команды в качестве аргумента.
  2. Можно возвращать новые значения или промисы для последующих команд.
  3. Любые исключения внутри then() будут автоматически обработаны Cypress, что обеспечивает надёжность теста.

Пример с обработкой данных из DOM:

cy.get('.user-name').then(($el) => {
  const username = $el.text();
  expect(username).to.contain('John');
});

Здесь then() извлекает текст элемента .user-name и позволяет выполнить проверку с использованием expect.

Возврат новых команд из then():

cy.get('.list-item').then(($items) => {
  return $items.length;
}).then((count) => {
  expect(count).to.be.greaterThan(0);
});

Возврат значения в then() позволяет передать его в следующую цепочку, сохраняя синхронность теста.

Работа с промисами внутри then():

cy.get('.api-data').then(() => {
  return fetch('/api/items')
    .then(res => res.json());
}).then((data) => {
  expect(data).to.have.length.above(5);
});

Метод then() автоматически “ждёт” завершения промиса, что упрощает интеграцию Cypress с асинхронными API.


Метод wrap()

Метод wrap() используется для преобразования обычных объектов, массивов, функций или промисов в цепочку команд Cypress. Это позволяет применять к ним все команды и методы проверки Cypress, даже если они не связаны напрямую с DOM.

Синтаксис:

cy.wrap(object).then((wrappedObject) => {
  // работа с обёрнутым объектом
});

Особенности:

  1. Оборачивает любые значения, позволяя использовать их внутри цепочки Cypress.
  2. Работает с промисами и асинхронными функциями, поддерживая ожидание результатов.
  3. Позволяет комбинировать Cypress-команды с чистым JavaScript-кодом.

Пример с объектом:

const user = { name: 'Alice', age: 25 };

cy.wrap(user).should('have.property', 'name', 'Alice');

wrap() превращает обычный объект в Cypress-цепочку, что позволяет использовать встроенные проверки should() и and().

Пример с промисом:

const getData = () => Promise.resolve([1, 2, 3]);

cy.wrap(getData()).then((data) => {
  expect(data).to.include(2);
});

Метод wrap() обеспечивает синхронизацию асинхронного кода с Cypress, предотвращая проблемы с таймингами.


Отличия then() и wrap()

Особенность then() wrap()
Основная цель Обработка результата предыдущей команды Оборачивание значения в Cypress-цепочку
Возвращаемое значение Передаётся в следующую then() в цепочке Позволяет применять Cypress-команды к объекту
Работа с промисами Автоматически ждёт завершения Позволяет обернуть промис и интегрировать
Использование Для асинхронной логики и вычислений Для интеграции обычных объектов и промисов

Практические комбинации

Часто then() и wrap() используются вместе для более сложных сценариев:

cy.get('.user-list').then(($list) => {
  const names = $list.map((i, el) => Cypress.$(el).text()).get();
  return names;
}).then((names) => {
  cy.wrap(names).should('include', 'Alice');
});

Здесь then() извлекает текст из элементов списка, а wrap() позволяет использовать встроенные проверки Cypress для обычного массива.


Особенности отладки

  • Внутри then() можно использовать console.log для просмотра значений без нарушения цепочки команд.
  • wrap() позволяет сохранять консистентность теста при переходе от чистого JavaScript к Cypress-командам.
  • Любые ошибки внутри then() автоматически прерывают тест, что упрощает выявление проблем.

then() и wrap() являются ключевыми инструментами Cypress для управления асинхронностью и интеграции произвольного кода в цепочки команд, обеспечивая гибкость и стабильность автоматизированного тестирования.