What is Cypress?
Cypress allows you to write tests that run directly in the browser, mimicking how a real user interacts with your site. Unlike Selenium, it operates in the same run-loop as your application, making debugging much easier.
Installation
In your JavaScript project, run the below command to add Cypress to it (any framework like Frappe, ReactJS, NextJS, etc.):
npm install cypress --save-dev
- Now you just have to run npx cypress open.
- Once opened, Cypress will create a folder named cypress/ with:
- e2e/ β for your test files
- support/ β custom commands and support logic
- fixtures/ β test data
- cypress.config.js β configuration file
- If you want to run tests in headless mode, you have to run npx cypress run.
Your First Test
Create a test file:
cypress/e2e/sample_test.cy.js
describe('My First Test', () => {
it('Visits the Portfolio website', () => {
cy.visit('https://kunj.pages.dev')
cy.contains('Kunj').should('exist')
})
})
Run this test by running any of the below commands:
npx cypress open
npx cypress run # for headless mode
Common Cypress Commands
Command | Description |
---|---|
cy.visit() | Opens a webpage |
cy.get() | Selects an element (like jQuery) |
cy.contains() | Finds elements by text |
cy.click() | Clicks an element |
cy.type() | Types into input fields |
cy.should() | Asserts something (like .should('be.visible')) |
Cypress In-Depth Commands Guide
Here's a deep-dive Cypress Command Guide with detailed usage examples, so you can confidently write advanced and production-grade end-to-end tests.
π 1. Visiting Pages
cy.visit(url, options?)
Loads a web page in the browser.
cy.visit('https://kunj.dev')
With options:
cy.visit('/login', {
timeout: 10000,
onBeforeLoad: (win) => {
// stub or modify window object
}
})
π 2. Querying Elements
cy.get(selector)
Gets one or more DOM elements.
cy.get('button') // All buttons
cy.get('.btn-primary') // Class selector
cy.get('[data-cy=login-button]') // Best practice!
cy.contains(text)
Find element with specific text.
cy.contains('Submit') // Finds "Submit" text
cy.contains('button', 'Save') // Finds button with text "Save"
cy.find(selector)
Chained version of .get() used with parent element.
cy.get('.form').find('input[type="text"]')
βοΈ 3. Interactions
cy.click()
Clicks on an element.
cy.get('[data-cy=submit-button]').click()
cy.type(text)
Types text into an input.
cy.get('[data-cy=email]').type('kunj@gmail.com')
cy.get('[data-cy=password]').type('Secret123', { log: false }) // hides logs
cy.select(value)
Selects a value from a dropdown.
cy.get('select').select('India')
cy.check() / cy.uncheck()
Checks or unchecks a checkbox or radio input.
cy.get('#terms').check()
cy.get('#subscribe').uncheck()
π§ͺ 4. Assertions
should()
Used for assertions.
cy.get('h1').should('contain', 'Welcome')
cy.get('[data-cy=error]').should('not.exist')
cy.url().should('include', '/dashboard')
Common assertions:
.should('be.visible')
.should('be.enabled')
.should('have.value', 'Kunj')
.should('have.length', 3)
β³ 5. Waiting & Timing
cy.wait(time)
Pauses test execution for specified ms (not recommended unless needed).
cy.wait(2000) // waits for 2 seconds
cy.wait('@alias')
Waits for a specific network request.
cy.intercept('POST', '/api/login').as('login')
cy.get('form').submit()
cy.wait('@login').its('response.statusCode').should('eq', 200)
π‘ 6. Network Requests
cy.intercept(method, url)
Intercepts (mocks or spies) a network request.
β Example: spying a login API
cy.intercept('POST', '/api/login').as('login')
cy.get('[data-cy=submit]').click()
cy.wait('@login').its('response.statusCode').should('eq', 200)
β Example: mocking (stubbing) a GET response
cy.intercept('GET', '/api/user', {
statusCode: 200,
body: { name: 'Kunj', role: 'Admin' },
}).as('getUser')
π¦ 7. Custom Commands
You can write reusable commands in cypress/support/commands.js:
Cypress.Commands.add('login', (email, password) => {
cy.get('[data-cy=email]').type(email)
cy.get('[data-cy=password]').type(password)
cy.get('[data-cy=submit]').click()
})
Usage:
cy.login('kunj@gmail.com', 'Password123')
π§ͺ 8. Fixtures (Mock Data)
Fixtures help you load external static JSON.
Create: cypress/fixtures/user.json
{
"email": "kunj@gmail.com",
"password": "secret123"
}
Use in test:
cy.fixture('user').then((user) => {
cy.get('[data-cy=email]').type(user.email)
cy.get('[data-cy=password]').type(user.password)
})
π 9. Aliases
as() to create aliases for reuse
cy.get('[data-cy=email]').as('emailInput')
cy.get('@emailInput').type('kunj@gmail.com')
π§Ό 10. State Management
cy.reload() β Reloads the page
cy.clearCookies() β Clears cookies
cy.clearLocalStorage() β Clears local storage
cy.scrollTo() β Scrolls element or window
cy.scrollTo('bottom')
cy.get('.chat-box').scrollTo('top')
π 11. Test Structure & Hooks
describe('Login Flow', () => {
before(() => {
// Runs once before all tests
})
beforeEach(() => {
// Runs before each test
cy.visit('/login')
})
it('Should login with valid credentials', () => {
// Test case
})
afterEach(() => {
// Cleanup if needed
})
after(() => {
// Runs once after all tests
})
})
π§ 12. Tips & Best Practices
Tip | Why |
---|---|
Use data-cy attributes | More stable than CSS or IDs |
Avoid .wait() unless necessary | Use cy.intercept() instead |
Write atomic, independent tests | Easier to debug and maintain |
Use beforeEach() to reset state | Ensures clean start |
Donβt test implementation details | Test user behavior |
π Learning Resources
- Cypress Docs: https://docs.cypress.io
- Real-world examples: https://github.com/cypress-io/cypress-realworld-app