What if you could fix one line and update hundreds of tests instantly?
Why custom commands reduce duplication in Cypress - The Real Reasons
Imagine testing a website where you must log in before every test. You write the same steps to enter username, password, and click login in every test file.
Typing the same login steps repeatedly wastes time and makes your tests hard to update. If the login process changes, you must fix every test manually, risking mistakes and delays.
Custom commands let you write the login steps once and reuse them everywhere. This keeps your tests clean, easy to read, and simple to update if the login changes.
cy.get('#user').type('name') cy.get('#pass').type('secret') cy.get('#login').click()
cy.login('name', 'secret')
Custom commands unlock faster test writing and easier maintenance by removing repeated code.
A team testing an online store uses a custom command for login. When the login page updates, they change the command once, and all tests keep working smoothly.
Manual repetition slows testing and causes errors.
Custom commands bundle repeated steps into one reusable action.
This saves time and makes tests easier to update and understand.
Practice
Solution
Step 1: Understand what duplication means in tests
Duplication means writing the same code multiple times, which makes tests harder to maintain.Step 2: Role of custom commands in Cypress
Custom commands let you write a common action once, like logging in, and reuse it everywhere, reducing repeated code.Final Answer:
They let you write common actions once and reuse them in many tests. -> Option CQuick Check:
Reuse common actions = less duplication [OK]
- Thinking custom commands speed up test execution
- Believing custom commands remove the need for assertions
- Assuming custom commands automatically fix bugs
Solution
Step 1: Recall Cypress syntax for custom commands
The correct method to add a custom command is Cypress.Commands.add.Step 2: Check each option's syntax
Only Cypress.Commands.add('login', () => { cy.visit('/login') }) uses Cypress.Commands.add correctly with the command name and function.Final Answer:
Cypress.Commands.add('login', () => { cy.visit('/login') }) -> Option DQuick Check:
Correct method is Cypress.Commands.add [OK]
- Using cy.Commands instead of Cypress.Commands
- Using createCommand or addCommand which don't exist
- Mixing up method names and object names
Cypress.Commands.add('login', (user) => { cy.get('#username').type(user.name); cy.get('#password').type(user.pass); cy.get('#submit').click(); }); What will happen when you run this test code?
cy.login({name: 'alice', pass: '1234'}); cy.url().should('include', '/dashboard'); Solution
Step 1: Understand the custom command behavior
The 'login' command types the username and password from the passed object and clicks submit.Step 2: Analyze the test code execution
Calling cy.login with user data runs the command, then the test asserts the URL includes '/dashboard'.Final Answer:
The test types username and password, clicks submit, then checks URL includes '/dashboard'. -> Option AQuick Check:
Custom command with args runs actions then assertion passes [OK]
- Thinking custom commands can't accept parameters
- Assuming missing return causes syntax error
- Believing some steps are skipped automatically
Cypress.Commands.add('clickButton', () => { cy.get('button.submit').click(); }); But your tests fail with "Cannot read property 'click' of undefined". What is the likely problem?
Solution
Step 1: Understand the error message
"Cannot read property 'click' of undefined" means cy.get did not find the element, so it returned undefined.Step 2: Check possible causes
If the selector does not match any element, cy.get returns nothing, causing the error when calling click.Final Answer:
The selector 'button.submit' does not match any element on the page. -> Option BQuick Check:
Selector missing element = click fails [OK]
- Assuming cy.get can't be used in custom commands
- Forgetting to visit the page (may cause no elements)
- Thinking command names are reserved keywords
fillForm that fills multiple fields on a page. Which approach best reduces duplication and improves test readability?Solution
Step 1: Consider duplication and readability
Copy-pasting code (Copy and paste the samecy.get().type()lines in every test needing the form filled.) causes duplication and harder maintenance.Step 2: Evaluate options for custom commands
Creating one command that accepts an object and fills all fields (CreatefillFormto accept an object with field names and values, then fill each field inside the command.) centralizes logic and improves readability.Step 3: Analyze other options
Separate commands (Write separate commands for each field and call them one by one in tests.) increase calls and complexity; cy.exec (Usecy.exec()to run external scripts that fill the form.) is not for UI actions.Final Answer:
Create fillForm to accept an object with field names and values, then fill each field inside the command. -> Option AQuick Check:
One command with params reduces duplication best [OK]
- Writing many small commands instead of one flexible one
- Copy-pasting code in tests instead of reusing commands
- Using cy.exec for UI interactions
Ready to prove it?
Pass the test and this pattern moves unknown
