Skip to main content

Cypress

Cypress is a powerful and user-friendly end-to-end testing framework designed for modern web applications. It allows developers and QA engineers to write reliable and fast tests for web interfaces.


Key Features

  • Easy Installation: Install Cypress using npm or yarn.
  • Time Travel: Debug tests by replaying snapshots of previous test states.
  • Automatic Waiting: No need for manual waits or retries; Cypress automatically waits for commands and assertions.
  • Real-Time Reloads: Instantly re-runs tests upon saving changes.
  • Cross-Browser Testing: Supports multiple browsers like Chrome, Firefox, and Edge.

Installation

Prerequisites:

  • Node.js (Ensure you have Node.js installed.)

Steps:

  1. Initialize your project:
    npm init -y
  2. Install Cypress:
    npm install cypress --save-dev

Open Cypress:

npx cypress open

This command launches the Cypress Test Runner.


Writing Your First Test

Folder Structure:

Cypress stores tests in the cypress/e2e directory by default.

Example Test:

Create a file named example.cy.js in the cypress/e2e folder:

describe('My First Test', () => {
it('Visits the Cypress website', () => {
cy.visit('https://www.cypress.io');
cy.contains('Get Started').click();
cy.url().should('include', '/getting-started');
});
});

Run the Test:

Execute the test by selecting it in the Cypress Test Runner.


Organizing Tests

Folder Structure

Cypress provides a default folder structure, which you can customize as needed. A well-organized structure ensures your tests are easy to navigate and maintain.

Default Folder Structure:

cypress/
├── e2e/ # Contains your test files
├── fixtures/ # Stores static test data (e.g., JSON files)
├── support/ # Contains reusable commands and configurations
├── downloads/ # Stores files downloaded during tests
├── screenshots/ # Captures screenshots of test failures
└── videos/ # Stores videos of test runs
  • By Feature: Group tests by application features.

    cypress/e2e/
    ├── auth/
    │ ├── login.cy.js
    │ └── signup.cy.js
    ├── dashboard/
    │ ├── view.cy.js
    │ └── edit.cy.js
    └── settings/
    ├── profile.cy.js
    └── preferences.cy.js
  • By Type: Group tests by type (e.g., smoke, regression, integration).

    cypress/e2e/
    ├── smoke/
    │ ├── basic-functionality.cy.js
    ├── regression/
    │ ├── all-tests.cy.js
    └── integration/
    ├── api-tests.cy.js

Page Object Model (POM)

The Page Object Model is a design pattern that promotes reusability and maintainability.

Example:

  • Create a page-objects folder:

    cypress/support/page-objects/
    ├── loginPage.js
    ├── dashboardPage.js
    └── settingsPage.js
  • Define reusable functions in loginPage.js:

    class LoginPage {
    visit() {
    cy.visit('/login');
    }

    enterUsername(username) {
    cy.get('#username').type(username);
    }

    enterPassword(password) {
    cy.get('#password').type(password);
    }

    submit() {
    cy.get('button[type="submit"]').click();
    }
    }

    export default new LoginPage();
  • Use the LoginPage object in your test:

    import LoginPage from '../support/page-objects/loginPage';

    describe('Login Tests', () => {
    it('Logs in successfully', () => {
    LoginPage.visit();
    LoginPage.enterUsername('testUser');
    LoginPage.enterPassword('password123');
    LoginPage.submit();
    cy.url().should('include', '/dashboard');
    });
    });

Custom Commands

Place reusable commands in cypress/support/commands.js to keep tests concise.

Example:

Add a custom command:

Cypress.Commands.add('login', (username, password) => {
cy.visit('/login');
cy.get('#username').type(username);
cy.get('#password').type(password);
cy.get('button[type="submit"]').click();
});

Use the custom command in a test:

describe('Login Tests', () => {
it('Logs in successfully', () => {
cy.login('testUser', 'password123');
cy.url().should('include', '/dashboard');
});
});

Use Tags for Test Categorization

Use tags to categorize and filter tests when running them.

Example:

describe('Smoke Tests', { tags: '@smoke' }, () => {
it('Basic functionality', () => {
// Test code
});
});

Run only tagged tests:

npx cypress run --env TAGS="@smoke"

Fixture Files

Use cypress/fixtures to store static test data like JSON files.

Example:

user.json in cypress/fixtures:

{
"username": "testUser",
"password": "password123"
}

Access fixtures in a test:

describe('Login Tests', () => {
it('Logs in using fixture data', () => {
cy.fixture('user').then((user) => {
cy.visit('/login');
cy.get('#username').type(user.username);
cy.get('#password').type(user.password);
cy.get('button[type="submit"]').click();
cy.url().should('include', '/dashboard');
});
});
});

Best Practices

  1. Use Page Objects: Organize reusable page-specific functions and selectors.
  2. Avoid Flaky Tests: Ensure tests are independent and do not rely on external systems.
  3. Leverage Cypress Commands: Use custom commands for repetitive actions.
  4. Run Tests in CI/CD: Integrate Cypress with CI/CD pipelines for continuous testing.

Resources


Cypress is an essential tool for modern web application testing, offering speed, reliability, and ease of use. Begin your testing journey with Cypress today!