cypress/
├── e2e/ # Test specification files
│ ├── login.cy.js # Example test file
│ └── dashboard.cy.js
├── support/ # Support files and custom commands
│ ├── commands.js # Custom commands added with Cypress.Commands.add()
│ ├── e2e.js # Support file loaded before tests
│ └── index.js # Entry point for support files
├── fixtures/ # Test data files (JSON, etc.)
│ └── user.json
└── plugins/ # Plugins for extending Cypress
└── index.js
cypress.config.js # Cypress configuration file
Cypress.Commands.add() - Framework Patterns
- Test Specs (e2e/): Contains test scripts that use Cypress commands to automate UI actions and assertions.
- Custom Commands (support/commands.js): Extend Cypress with reusable commands using
Cypress.Commands.add()to simplify tests and avoid repetition. - Fixtures (fixtures/): Store static test data like user info or test inputs in JSON files for easy reuse.
- Plugins (plugins/): Add or modify Cypress behavior, e.g., for tasks like file system access or environment setup.
- Configuration (cypress.config.js): Define environment settings, base URLs, browser options, and test timeouts.
Use cypress.config.js to manage settings like base URL, test retries, and browser preferences.
Manage environments by defining env variables in the config or via CLI, e.g., cypress run --env environment=staging.
Store sensitive data like credentials in environment variables or cypress.env.json (excluded from version control) to keep secrets safe.
Example snippet from cypress.config.js:
export default defineConfig({
e2e: {
baseUrl: 'https://example.com',
env: {
username: 'testuser',
password: 'secret'
},
retries: 2,
setupNodeEvents(on, config) {
// plugin code here
}
}
})
Use built-in Cypress reporters or add plugins like mochawesome for detailed HTML and JSON reports.
Configure reporters in cypress.config.js or via CLI options.
Integrate Cypress tests into CI/CD pipelines (GitHub Actions, Jenkins, GitLab CI) by running cypress run commands and collecting reports as artifacts.
Example GitHub Actions step:
- name: Run Cypress Tests
uses: cypress-io/github-action@v5
with:
browser: chrome
headless: true
- Keep commands simple and focused: Each custom command should do one clear task to keep tests readable.
- Use commands to abstract repetitive UI actions: For example, create a
logincommand to reuse login steps across tests. - Chain commands properly: Return Cypress chainables from commands to allow smooth chaining in tests.
- Document custom commands: Add comments explaining what each command does for easy maintenance.
- Store commands in
support/commands.js: This keeps the framework organized and commands automatically loaded.
Where in this folder structure would you add a new custom command named fillForm that types data into a form?
Practice
Cypress.Commands.add() in Cypress testing?Solution
Step 1: Understand the function of Cypress.Commands.add()
This method allows you to define your own commands that you can reuse in tests.Step 2: Identify the benefit of reusable commands
Reusable commands help keep test code clean and avoid repetition.Final Answer:
To create reusable custom commands for cleaner test code -> Option CQuick Check:
Reusable commands = Cleaner code [OK]
- Thinking it adds test cases automatically
- Confusing it with test report generation
- Assuming it changes browser settings
login in Cypress?Solution
Step 1: Recall the correct method name
The correct method to add commands isCypress.Commands.add().Step 2: Check the syntax format
The first argument is the command name as a string, the second is a function.Final Answer:
Cypress.Commands.add('login', () => { /* code */ }) -> Option DQuick Check:
Correct method and syntax = Cypress.Commands.add('login', () => { /* code */ }) [OK]
- Using Cypress.addCommand instead of Commands.add
- Omitting Cypress.Commands prefix
- Using create instead of add
cy.login() is called in a test? Cypress.Commands.add('login', (username, password) => {
cy.get('#user').type(username)
cy.get('#pass').type(password)
cy.get('#submit').click()
})
// In test
cy.login('user1', 'pass1')Solution
Step 1: Analyze the custom command parameters
The command takes username and password and types them into respective fields.Step 2: Follow the command actions
It types username into '#user', password into '#pass', then clicks '#submit'.Final Answer:
Types 'user1' in #user, 'pass1' in #pass, then clicks #submit -> Option AQuick Check:
Parameters map to correct fields = Types 'user1' in #user, 'pass1' in #pass, then clicks #submit [OK]
- Assuming no parameters are needed
- Mixing up username and password fields
- Ignoring the click action
Cypress.Commands.add('clickButton', () => {
cy.get('#button')
cy.click()
})Solution
Step 1: Review the command chaining
cy.get('#button')returns an element, butcy.click()is called separately, not chained.Step 2: Understand correct chaining
Click should be chained to the element:cy.get('#button').click().Final Answer:
Missing chaining ofclick()tocy.get()-> Option AQuick Check:
Method chaining required = Missing chaining ofclick()tocy.get()[OK]
- Calling cy.click() separately
- Changing command name unnecessarily
- Using cy.find() instead of cy.get() without reason
fillForm that fills multiple fields and submits a form. Which approach correctly uses Cypress.Commands.add() to accept an object with field values and perform the actions?Solution
Step 1: Understand parameter passing
Using a single object parameterdatawith named properties is clear and flexible.Step 2: Check usage of object properties
Accessingdata.nameanddata.emailmatches the object keys.Final Answer:
Cypress.Commands.add('fillForm', (data) => { cy.get('#name').type(data.name) cy.get('#email').type(data.email) cy.get('#submit').click() }) -> Option BQuick Check:
Object parameter with named fields = Cypress.Commands.add('fillForm', (data) => { cy.get('#name').type(data.name) cy.get('#email').type(data.email) cy.get('#submit').click() }) [OK]
- Using undefined variables without parameters
- Passing multiple parameters instead of one object
- Accessing object fields by index instead of name
Ready to prove it?
Pass the test and this pattern moves unknown
