Page Object Model (POM) — это шаблон проектирования, направленный на повышение читаемости и поддерживаемости тестов через разделение логики тестов и логики работы с элементами страницы. В контексте Cypress его использование позволяет создавать абстракции над интерфейсом, что сокращает дублирование кода и упрощает внесение изменений при модификации приложения.
1. Инкапсуляция элементов страницы Элементы страницы описываются как свойства класса или объекта. Это позволяет изменять селекторы в одном месте без необходимости правки всех тестов, где они используются.
Пример:
class LoginPage {
get usernameInput() {
return cy.get('#username');
}
get passwordInput() {
return cy.get('#password');
}
get loginButton() {
return cy.get('button[type="submit"]');
}
}
2. Методы взаимодействия Page Object должен содержать методы, которые описывают действия пользователя. Методы не должны дублировать логику тестов, а предоставлять чистые действия над страницей.
login(username, password) {
this.usernameInput.type(username);
this.passwordInput.type(password);
this.loginButton.click();
}
3. Разделение логики теста и логики страницы Тест должен концентрироваться на проверках и сценариях, а не на низкоуровневом взаимодействии с элементами. Page Object берет на себя работу с DOM.
Пример теста с использованием Page Object:
describe('Login tests', () => {
const loginPage = new LoginPage();
it('Успешный вход', () => {
cy.visit('/login');
loginPage.login('user', 'password');
cy.url().should('include', '/dashboard');
});
});
Для крупных проектов рекомендуется разделять Page Objects по функциональным блокам приложения:
cypress/
└─ support/
└─ page_objects/
├─ loginPage.js
├─ dashboardPage.js
└─ settingsPage.js
Каждый файл содержит один класс или объект, полностью инкапсулирующий работу с конкретной страницей. Это облегчает навигацию по проекту и поиск нужного Page Object.
Для повторяющихся действий или комплексных сценариев, которые затрагивают несколько страниц, можно создавать вспомогательные методы внутри Page Object или отдельные утилиты:
export function loginAsUser(username, password) {
const loginPage = new LoginPage();
loginPage.login(username, password);
}
Cypress автоматически ждет элементы на странице, поэтому в Page
Object можно безопасно использовать цепочки команд без явных
wait. Для динамических элементов полезно создавать методы,
принимающие параметры:
class DashboardPage {
menuItem(name) {
return cy.contains('nav li', name);
}
openMenuItem(name) {
this.menuItem(name).click();
}
}
Хотя Page Object не должен содержать сами тестовые сценарии, он может включать методы для проверок состояния элементов. Это особенно удобно для повторяющихся assertion:
class LoginPage {
errorMessage() {
return cy.get('.error-message');
}
verifyError(message) {
this.errorMessage().should('have.text', message);
}
}
visit(url),
getHeader().Структура Page Objects формирует фундамент для масштабируемых, поддерживаемых и устойчивых к изменениям тестов, делая Cypress мощным инструментом автоматизации в больших проектах.