Cypress предоставляет мощный механизм расширения стандартного набора команд с помощью пользовательских команд. Они позволяют уменьшить дублирование кода, повысить читаемость тестов и инкапсулировать сложные последовательности действий в одну удобную функцию.
Для создания собственной команды используется функция
Cypress.Commands.add. Она принимает два обязательных
аргумента: название команды и функцию, реализующую её поведение.
Cypress.Commands.add('login', (username, password) => {
cy.get('#username').type(username)
cy.get('#password').type(password)
cy.get('button[type="submit"]').click()
})
После добавления команды она становится доступной в любом тесте:
cy.login('admin', '12345')
Особенности:
cy после вызова пользовательской
команды.Иногда необходимо, чтобы команда возвращала результат выполнения. Для
этого используется return в функции команды:
Cypress.Commands.add('getUserData', (userId) => {
return cy.request(`/api/users/${userId}`).then((response) => {
return response.body
})
})
cy.getUserData(5).then((user) => {
expect(user.name).to.eq('John Doe')
})
Ключевые моменты:
.then() позволяет обрабатывать
результат внутри теста.Пользовательские команды могут принимать объект опций для настройки поведения:
Cypress.Commands.add('fillForm', (data, options = {}) => {
const { clearFields = true } = options
if (clearFields) {
cy.get('#name').clear()
cy.get('#email').clear()
}
cy.get('#name').type(data.name)
cy.get('#email').type(data.email)
})
Применение:
cy.fillForm({ name: 'Alice', email: 'alice@example.com' }, { clearFields: false })
Преимущество: упрощает создание гибких команд, которые можно использовать в разных сценариях без дублирования кода.
Пользовательские команды могут включать асинхронные запросы, работу с API или таймеры:
Cypress.Commands.add('waitForApi', (endpoint) => {
cy.intercept(endpoint).as('apiCall')
cy.wait('@apiCall').then((interception) => {
expect(interception.response.statusCode).to.eq(200)
})
})
Использование в тесте:
cy.waitForApi('/api/data')
Важный момент: использование
cy.intercept и cy.wait внутри команды
позволяет полностью инкапсулировать логику проверки сетевых
запросов.
Пользовательские команды могут быть созданы так, чтобы поддерживать
цепочки Cypress, возвращая cy:
Cypress.Commands.add('selectDropdown', (selector, value) => {
return cy.get(selector).select(value)
})
Цепочка:
cy.selectDropdown('#country', 'USA').get('#submit').click()
Особенность: возвращение cy
обеспечивает совместимость с другими командами и позволяет строить
читаемые тестовые сценарии.
Cypress поддерживает создание команд, привязанных к конкретному
элементу DOM, через Cypress.Commands.add с третьим
параметром { prevSubject: true }. Это полезно для
расширения функционала стандартных команд:
Cypress.Commands.add('highlight', { prevSubject: true }, (subject) => {
subject.css('border', '2px solid red')
return subject
})
Применение:
cy.get('#username').highlight().type('admin')
Примечание: prevSubject: true позволяет
использовать команду на уже выбранном элементе и возвращать его для
дальнейших действий.
cypress/support/commands.js.commands.js.login, fillForm,
navigateTo).cy для интеграции с другими
Cypress-командами..then() для
асинхронных операций.Эффективное использование пользовательских команд делает тесты Cypress более компактными, структурированными и легко расширяемыми, позволяя создавать сложные сценарии с минимальным дублированием кода.