Миграция с Protractor

Основные различия архитектуры

Protractor строился поверх Selenium WebDriver и AngularJS, что подразумевало асинхронное выполнение команд через промисы. Cypress использует собственный движок, работающий внутри браузера, и обеспечивает синхронное выполнение команд в тестах. Это фундаментальное отличие влияет на структуру тестов и подход к их написанию:

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

Переписывание селекторов и команд взаимодействия

В Protractor для поиска элементов использовались element(by.css(...)), element(by.id(...)), element(by.binding(...)). В Cypress аналогичную функциональность обеспечивает команда cy.get(), которая поддерживает любые CSS-селекторы:

// Protractor
element(by.id('login')).click();

// Cypress
cy.get('#login').click();

Особенности при переписывании:

  • Методы .sendKeys() заменяются на .type().
  • .clear() в Protractor также поддерживается в Cypress через .clear().
  • Встроенные ожидания Angular (browser.waitForAngular()) в Cypress не нужны, так как Cypress автоматически ждёт загрузки страницы и завершения сетевых запросов.

Ожидания и тайминги

Protractor активно использовал browser.wait для явных ожиданий:

browser.wait(ExpectedConditions.visibilityOf(element(by.id('submit'))), 5000);

В Cypress это реализуется через встроенные команды с автоматическим ожиданием:

cy.get('#submit', { timeout: 5000 }).should('be.visible');

Cypress повторяет попытки поиска элемента до истечения таймаута, что сокращает количество ручных ожиданий.

Работа с асинхронными действиями

Protractor требовал явной работы с промисами, особенно при обращении к данным элементов:

element(by.id('username')).getText().then((text) => {
  expect(text).toEqual('admin');
});

В Cypress достаточно использовать встроенные утверждения:

cy.get('#username').should('have.text', 'admin');

Все команды Cypress автоматически учитывают асинхронность, что упрощает чтение и поддержку тестов.

Сетевые запросы и мокирование

Protractor не имел встроенных средств для перехвата запросов, использовались сторонние библиотеки. В Cypress перехват запросов реализуется через cy.intercept():

cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');
cy.visit('/users');
cy.wait('@getUsers');

Преимущества Cypress:

  • Возможность задавать фикстуры и перехватывать запросы без дополнительных библиотек.
  • Автоматическая синхронизация теста с завершением сетевых операций.

Структура тестов и хуки

В Protractor тесты писались с использованием describe, it, а хуки были идентичны Jasmine (beforeEach, afterEach). Cypress использует ту же структуру, но с особенностями обработки контекста:

  • Контекст this не рекомендуется использовать в Cypress для хранения состояния между тестами.
  • Для подготовки данных и очистки лучше использовать before, beforeEach, afterEach с Cypress-командами.
beforeEach(() => {
  cy.visit('/login');
});

Миграция специфичных Angular-функций

Protractor поддерживал Angular-специфичные селекторы (by.model, by.binding). В Cypress таких методов нет, поэтому необходимо переписывать их на универсальные CSS или data-* атрибуты:

<input data-cy="username" type="text">
cy.get('[data-cy=username]').type('admin');

Использование data-* атрибутов обеспечивает стабильность тестов при изменениях UI.

Работа с формами и действия пользователя

Protractor использовал методы sendKeys, click, submit. В Cypress эквиваленты:

  • .type() — ввод текста.
  • .click() — клик.
  • .check() / .uncheck() — работа с чекбоксами.
  • .select() — выбор значения из select.

Cypress автоматически скроллит элементы в область видимости перед взаимодействием, что устраняет необходимость явного прокручивания страницы.

Параллельное выполнение и интеграция CI/CD

Protractor поддерживал параллельное выполнение через Selenium Grid, Cypress предлагает встроенное параллельное выполнение и интеграцию с CI/CD:

  • Запуск тестов на разных браузерах и конфигурациях.
  • Автоматическая генерация отчетов с видео и скриншотами.
  • Конфигурация через cypress.config.js вместо protractor.conf.js.

Рекомендации по миграции

  1. Переписать селекторы с Angular-специфичных на CSS или data-*.
  2. Заменить все асинхронные конструкции на синхронные цепочки Cypress.
  3. Использовать cy.intercept для мокирования сетевых запросов.
  4. Переписать проверки состояния элементов через .should() или .and().
  5. Проверить тайминги и удалить явные ожидания там, где их нет необходимости.
  6. Переписать работу с формами через команды Cypress.

Миграция с Protractor на Cypress позволяет упростить архитектуру тестов, повысить стабильность и ускорить выполнение. Ключевым изменением является переход от ручного управления асинхронностью и Angular-спецификой к автоматизированному ожиданию и универсальным инструментам взаимодействия с DOM.