Answer
Page Object Model in Cypress
Cypress doesn't enforce any structure, but POM keeps tests maintainable by separating selectors and actions from test logic.
Project Structure
CODE
cypress/
├── e2e/
│ ├── login.cy.js
│ └── dashboard.cy.js
├── pages/
│ ├── LoginPage.js
│ ├── DashboardPage.js
│ └── BasePage.js
├── support/
│ └── commands.js
└── fixtures/
└── users.json
Base Page
JavaScript
// cypress/pages/BasePage.js
class BasePage {
visit(path) {
cy.visit(path);
return this;
}
getElement(selector) {
return cy.get(selector);
}
clickElement(selector) {
cy.get(selector).click();
return this;
}
typeInField(selector, text) {
cy.get(selector).clear().type(text);
return this;
}
}
export default BasePage;
Login Page Object
JavaScript
// cypress/pages/LoginPage.js
import BasePage from './BasePage';
class LoginPage extends BasePage {
// Selectors
elements = {
emailInput: () => cy.get('[data-testid="email"]'),
passwordInput: () => cy.get('[data-testid="password"]'),
loginBtn: () => cy.get('[data-testid="login-btn"]'),
errorMsg: () => cy.get('[data-testid="error-message"]'),
};
// Actions
visit() {
return super.visit('/login');
}
enterEmail(email) {
this.elements.emailInput().type(email);
return this;
}
enterPassword(password) {
this.elements.passwordInput().type(password);
return this;
}
clickLogin() {
this.elements.loginBtn().click();
return this;
}
login(email, password) {
return this.visit()
.enterEmail(email)
.enterPassword(password)
.clickLogin();
}
// Assertions
verifyErrorMessage(msg) {
this.elements.errorMsg().should('be.visible').and('contain', msg);
return this;
}
}
export default new LoginPage();
Dashboard Page Object
JavaScript
// cypress/pages/DashboardPage.js
import BasePage from './BasePage';
class DashboardPage extends BasePage {
elements = {
heading: () => cy.get('h1'),
userName: () => cy.get('[data-testid="user-name"]'),
logoutBtn: () => cy.get('[data-testid="logout"]'),
};
verifyUserLoggedIn(name) {
this.elements.heading().should('contain', 'Dashboard');
this.elements.userName().should('contain', name);
return this;
}
logout() {
this.elements.logoutBtn().click();
return this;
}
}
export default new DashboardPage();
Test Using Page Objects
JavaScript
// cypress/e2e/login.cy.js
import LoginPage from '../pages/LoginPage';
import DashboardPage from '../pages/DashboardPage';
describe('Login Tests', () => {
it('should login successfully', () => {
LoginPage
.login('test@automateqa.com', 'Test@123');
DashboardPage
.verifyUserLoggedIn('QA Tester');
});
it('should show error for wrong password', () => {
LoginPage
.visit()
.enterEmail('test@automateqa.com')
.enterPassword('WrongPass')
.clickLogin()
.verifyErrorMessage('Invalid credentials');
});
});
