Cypress предоставляет гибкий и мощный инструмент для автоматизации тестирования, где кастомные команды играют ключевую роль в повышении читаемости и повторного использования кода. Кастомные команды позволяют инкапсулировать сложные действия или последовательности взаимодействий с приложением, минимизируя дублирование и упрощая сопровождение тестов.
Кастомная команда создаётся с помощью метода
Cypress.Commands.add. Синтаксис выглядит следующим
образом:
Cypress.Commands.add('имяКоманды', (аргументы) => {
// Логика команды
});
Пример: команда для авторизации пользователя на сайте:
Cypress.Commands.add('login', (username, password) => {
cy.get('#username').type(username);
cy.get('#password').type(password);
cy.get('#loginButton').click();
});
После этого команду можно использовать во всех тестах:
cy.login('admin', '123456');
Кастомные команды могут принимать любое количество аргументов, а также объект конфигурации для гибкой настройки поведения:
Cypress.Commands.add('fillForm', ({ name, email, subscribe = false }) => {
cy.get('#name').type(name);
cy.get('#email').type(email);
if (subscribe) {
cy.get('#subscribe').check();
}
cy.get('#submit').click();
});
Такой подход позволяет создавать универсальные команды, которые адаптируются под разные сценарии тестирования.
Ключевая особенность Cypress — это цепочки команд, где каждая команда
возвращает объект типа Chainable. Кастомные команды должны
сохранять эту цепочку для возможности последующего вызова других
команд:
Cypress.Commands.add('search', (query) => {
return cy.get('#searchInput')
.type(query)
.get('#searchButton')
.click();
});
Возврат cy.get или другой Cypress-команды гарантирует
совместимость с цепочкой cy.
Для поддерживаемости проекта кастомные команды размещаются в
отдельном файле, обычно cypress/support/commands.js. Это
позволяет централизованно управлять всеми командами, избегая
дублирования и облегчая рефакторинг.
// cypress/support/commands.js
Cypress.Commands.add('logout', () => {
cy.get('#logoutButton').click();
});
В cypress/support/e2e.js или
cypress/support/index.js необходимо импортировать файл
команд:
import './commands';
Cypress.PromiseИногда требуется вернуть результат действия для последующей обработки
в тесте. Для асинхронных операций можно использовать
Cypress.Promise:
Cypress.Commands.add('getUserId', (username) => {
return new Cypress.Promise((resolve) => {
cy.request(`/api/users?username=${username}`)
.then((response) => {
resolve(response.body.id);
});
});
});
Использование:
cy.getUserId('admin').then((id) => {
cy.log(`ID пользователя: ${id}`);
});
Кастомные команды часто строятся на уже существующих Cypress-командах. Это позволяет комбинировать базовые действия в более сложные сценарии:
Cypress.Commands.add('addItemToCart', (itemName) => {
cy.get('.product-list')
.contains(itemName)
.click();
cy.get('#addToCart').click();
});
Для больших проектов рекомендуется разделять команды по типам действий, например:
login, logout)fillForm,
submitForm)getUserId, createOrder)Такое разделение облегчает навигацию по коду и ускоряет поддержку тестов.
Можно создавать команды, которые сохраняют контекст между действиями:
Cypress.Commands.add('selectCategory', (category) => {
cy.get('.category-list')
.contains(category)
.click();
return cy.get('.product-list'); // Возвращаем новый контекст
});
Это позволяет выстраивать гибкие и читаемые цепочки:
cy.selectCategory('Electronics')
.contains('Laptop')
.click();
Важно проверять корректность кастомных команд отдельными тестами, особенно если они включают сложные взаимодействия с DOM или API. Для этого создаются небольшие тестовые сценарии, которые изолированно проверяют поведение команды.
Организация кастомных команд в Cypress значительно повышает структурированность тестового кода, снижает дублирование и упрощает поддержку проекта. Правильное использование аргументов, цепочек команд и структуры файлов обеспечивает гибкость и масштабируемость тестового фреймворка.