How to Create Reusable Functions in Cypress for Efficient Testing
In Cypress, you create reusable functions by defining custom commands using
Cypress.Commands.add or by writing plain JavaScript functions in support files. These functions help you avoid repeating code and keep tests clean and easy to maintain.Syntax
Reusable functions in Cypress can be created as custom commands or plain JavaScript functions.
- Custom Command: Use
Cypress.Commands.add('name', callback)to define a new command accessible in tests. - Plain Function: Define a JavaScript function in a support file and import it where needed.
javascript
Cypress.Commands.add('login', (username, password) => { cy.get('#username').type(username) cy.get('#password').type(password) cy.get('button[type="submit"]').click() })
Example
This example shows how to create a reusable custom command login and use it in a test to log into a website.
javascript
// cypress/support/commands.js Cypress.Commands.add('login', (username, password) => { cy.get('#username').type(username) cy.get('#password').type(password) cy.get('button[type="submit"]').click() }) // cypress/e2e/login_spec.cy.js describe('Login Test', () => { it('logs in with valid credentials', () => { cy.visit('/login') cy.login('user1', 'pass123') cy.url().should('include', '/dashboard') }) })
Output
Test passes if the user is redirected to /dashboard after login.
Common Pitfalls
Common mistakes when creating reusable functions in Cypress include:
- Not adding custom commands in the
cypress/support/commands.jsfile, so they are not loaded automatically. - Using selectors that are too generic or brittle, causing tests to fail when the UI changes.
- Not returning Cypress chains or promises, which can break test flow.
Always ensure your reusable functions use stable selectors and return Cypress commands when needed.
javascript
// Wrong: Custom command defined inside a test file and not loaded globally Cypress.Commands.add('wrongLogin', () => { cy.get('input').type('user') // too generic selector }) // Right: Defined in support/commands.js with specific selectors Cypress.Commands.add('correctLogin', (username) => { return cy.get('#username').type(username) // returns chain })
Quick Reference
| Concept | Usage | Notes |
|---|---|---|
| Custom Command | Cypress.Commands.add('name', callback) | Reusable in all tests after import |
| Plain Function | function myFunc() { ... } | Import and call where needed |
| Selectors | Use stable IDs or data-* attributes | Avoid brittle selectors |
| Return Chains | return cy.get(...) | Maintain Cypress command chain |
| File Location | support/commands.js | Auto-loaded by Cypress |
Key Takeaways
Create reusable functions as custom commands with Cypress.Commands.add for easy use in tests.
Place custom commands in cypress/support/commands.js to load them automatically.
Use stable and specific selectors to avoid flaky tests.
Return Cypress command chains in reusable functions to keep test flow intact.
Plain JavaScript functions can also be reused by importing them into test files.