Overwrite существующих команд

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


Основы переопределения команд

Для переопределения команд используется метод Cypress.Commands.overwrite. Его синтаксис следующий:

Cypress.Commands.overwrite('названиеКоманды', (оригинальнаяФункция, ...аргументы) => {
  // Логика нового поведения
});
  • названиеКоманды — строка с именем команды, которую необходимо переопределить. Например, 'click', 'type' или 'visit'.
  • оригинальнаяФункция — функция, которая представляет собой исходную реализацию команды. Её можно вызвать внутри новой логики, если необходимо сохранить базовое поведение.
  • …аргументы — все аргументы, которые передаются команде при вызове в тесте.

Пример базового переопределения команды click:

Cypress.Commands.overwrite('click', (originalFn, subject, options) => {
  cy.log('Элемент кликается с кастомной логикой');
  return originalFn(subject, options);
});

В этом примере каждый вызов cy.get('selector').click() будет дополнительно выводить лог перед выполнением стандартного клика.


Добавление логирования к существующим командам

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

Cypress.Commands.overwrite('type', (originalFn, element, text, options) => {
  cy.log(`Ввод текста "${text}" в элемент`, element);
  return originalFn(element, text, options);
});

Таким образом, каждый ввод текста через cy.type() будет автоматически логироваться, без необходимости добавлять cy.log() в каждом тесте.


Изменение поведения команды visit

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

Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
  const customOptions = {
    ...options,
    headers: {
      ...options?.headers,
      'X-Custom-Header': 'TestHeader'
    }
  };
  cy.log(`Переход на URL: ${url}`);
  return originalFn(url, customOptions);
});

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


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

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

Cypress.Commands.overwrite('click', (originalFn, subject, options) => {
  cy.wrap(subject).should('be.visible').then(el => {
    cy.log('Элемент видим, выполняем клик');
    return originalFn(el, options);
  });
});

Такое переопределение повышает стабильность тестов на динамически подгружаемых страницах.


Переопределение пользовательских команд

Не только встроенные команды можно переопределять. Любую собственную команду, созданную через Cypress.Commands.add, также можно изменить:

Cypress.Commands.add('login', (username, password) => {
  cy.get('#username').type(username);
  cy.get('#password').type(password);
  cy.get('#login-btn').click();
});

Cypress.Commands.overwrite('login', (originalFn, username, password) => {
  cy.log('Вход с логированием');
  return originalFn(username, password);
});

Переопределение позволяет внедрять дополнительные шаги без изменения тестов, использующих команду cy.login().


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

  • Вызывать оригинальную функцию (originalFn) всегда, если требуется сохранить стандартное поведение команды.
  • Минимизировать побочные эффекты: переопределение должно быть предсказуемым и не ломать цепочки Cypress.
  • Использовать cy.log для дебага: логирование внутри переопределённых команд помогает отслеживать выполнение тестов.
  • Учитывать параметры по умолчанию: при передаче options нужно сохранять существующие свойства через spread-оператор (...options).
  • Проверять асинхронность: при использовании then или cy.wrap возвращаемое значение должно быть цепочкой Cypress, чтобы не нарушать flow теста.

Типовые сценарии использования

  1. Централизованное логирование действий пользователя — click, type, select.
  2. Автоматическая авторизация перед visit — добавление токенов или заголовков.
  3. Обработка ошибок и ретраи — повторный клик или ввод при временных сбоях.
  4. Дополнительная проверка состояния элементов — видимость, доступность, готовность к взаимодействию.

Использование Cypress.Commands.overwrite позволяет создавать гибкие и поддерживаемые тесты, снижать дублирование кода и повышать стабильность автоматизации. Правильная организация переопределённых команд делает тестовую базу более предсказуемой и легко расширяемой.