</>

Technology

Cypress

Difficulty

Intermediate

Interview Question

What are Cypress Custom Commands? How do you create and use them?

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)

Follow AutomateQA

Related Topics