← Back to libraryQuestion 179 of 468
🌲CypressIntermediate

Custom Commands

📌 Definition:

Custom commands extend Cypress's cy.* API with reusable actions defined via Cypress.Commands.add. They reduce duplication for common flows like login, and can be chained like built-in commands.

📖 Detailed Explanation:

In cypress/support/commands.js you write Cypress.Commands.add('login', (user, pass) => {...}), then call cy.login('qa', 'pw') anywhere. Custom commands can be parent commands (start a chain), child commands (chain off a subject, e.g. cy.get(...).customThing()), or dual. They centralize repeated logic (auth, navigation, form filling) and make tests read at a higher level of intent. Overusing them for one-off logic hurts readability; reserve them for genuinely shared, stable flows. TypeScript users add type definitions so custom commands autocomplete.

🔑 Key Points:
  • Cypress.Commands.add defines reusable cy.* commands
  • Parent, child, or dual command types
  • Great for shared flows (login, navigation) — DRY tests
  • Add TS types for autocomplete; don't over-abstract one-offs
🌍 Real-World Example:

cy.login(user, pass) — defined once — replaces 15 lines of form-filling repeated across dozens of specs, and can internally use the fast API login so every test benefits from the optimization in one place.

🎯 Scenario-Based Interview Question:

The team wraps every single cy.get in a custom command 'getEl'. Why can this be an anti-pattern?