Answer
Cypress Custom Commands
Custom commands let you encapsulate reusable test actions as named commands, similar to utility methods in Selenium Page Object Model.
Creating Custom Commands
JavaScript
// cypress/support/commands.js
// ── Login command ──
Cypress.Commands.add('login', (email, password) => {
cy.visit('/login');
cy.get('#email').type(email);
cy.get('#password').type(password);
cy.get('[data-testid="login-btn"]').click();
cy.url().should('include', '/dashboard');
});
// ── Login via API (faster — bypasses UI) ──
Cypress.Commands.add('loginViaApi', (email, password) => {
cy.request({
method: 'POST',
url: '/api/auth/login',
body: { email, password },
}).then((response) => {
// Store token in localStorage
window.localStorage.setItem('authToken', response.body.token);
});
cy.visit('/dashboard');
});
// ── Select dropdown by visible text ──
Cypress.Commands.add('selectByText', (selector, text) => {
cy.get(selector).select(text);
});
// ── Fill a form ──
Cypress.Commands.add('fillContactForm', (name, email, message) => {
cy.get('[data-testid="name"]').type(name);
cy.get('[data-testid="email"]').type(email);
cy.get('[data-testid="message"]').type(message);
});
// ── Drag and drop ──
Cypress.Commands.add('dragTo', { prevSubject: 'element' }, (subject, target) => {
cy.wrap(subject).trigger('mousedown', { which: 1 });
cy.get(target).trigger('mousemove').trigger('mouseup');
});
TypeScript Declarations (cypress/support/index.d.ts)
TypeScript
declare namespace Cypress {
interface Chainable {
login(email: string, password: string): void;
loginViaApi(email: string, password: string): void;
selectByText(selector: string, text: string): void;
fillContactForm(name: string, email: string, message: string): void;
}
}
Using Custom Commands in Tests
JavaScript
// cypress/e2e/dashboard.cy.js
describe('Dashboard Tests', () => {
beforeEach(() => {
// Use custom command — one line instead of 5
cy.login('test@automateqa.com', 'Test@123');
});
it('should show correct user name', () => {
cy.get('[data-testid="user-name"]').should('contain', 'QA Tester');
});
it('should load dashboard widgets', () => {
cy.get('[data-testid="widget"]').should('have.length.greaterThan', 2);
});
});
Overwriting Existing Commands
JavaScript
// Add a screenshot on every cy.visit()
Cypress.Commands.overwrite('visit', (originalFn, url, options) => {
originalFn(url, options);
cy.screenshot(`visit-${url.replace(/\//g, '-')}`);
});
File Location
CODE
cypress/
├── support/
│ ├── commands.js ← define custom commands here
│ └── e2e.js ← imports commands.js (auto-loaded before every test)
