/// <reference types="cypress" />
// cypress/support/pageObjects/LoginPage.js
export class LoginPage {
emailInput() {
return cy.get('#email');
}
passwordInput() {
return cy.get('#password');
}
loginButton() {
return cy.get('button[type="submit"]');
}
visit() {
cy.visit('/login');
}
login(email, password) {
this.emailInput().clear().type(email);
this.passwordInput().clear().type(password);
this.loginButton().click();
}
}
// cypress/support/pageObjects/DashboardPage.js
export class DashboardPage {
heading() {
return cy.get('h1').contains('Dashboard');
}
}
// cypress/e2e/login.spec.js
import { LoginPage } from '../support/pageObjects/LoginPage';
import { DashboardPage } from '../support/pageObjects/DashboardPage';
describe('Login Test Suite', () => {
const loginPage = new LoginPage();
const dashboardPage = new DashboardPage();
it('should login successfully and show dashboard', () => {
loginPage.visit();
loginPage.login('user@example.com', 'Password123');
cy.url().should('include', '/dashboard');
dashboardPage.heading().should('be.visible');
});
});This test uses the Page Object pattern to keep selectors and actions organized in separate classes. LoginPage handles all login page elements and actions, while DashboardPage handles dashboard elements.
The test visits the login page, performs login with given credentials, then asserts the URL contains '/dashboard' and the dashboard heading is visible. This separation makes the test easier to maintain and scale as the application grows.
Using Cypress commands ensures reliable interaction and assertions. Selectors are stored in page objects to avoid duplication and make updates easier.