Skip to content

Latest commit

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

Cypress Automation Testing Framework - Zero To Hero 🚀

A comprehensive JavaScript-based Cypress automation testing framework designed to take you from beginner to advanced testing hero. This repository contains complete examples, best practices, and practical guides for mastering Cypress testing.


📋 Table of Contents


Overview

This project is your complete guide to mastering Cypress for automated testing. Whether you're testing web applications or APIs, you'll learn everything from basic setup to advanced frameworks and real-world testing scenarios.

What You'll Learn:

  • Cypress fundamentals and core concepts
  • Web and API testing automation
  • Advanced selector strategies
  • Real-world testing scenarios
  • CI/CD integration (Jenkins, GitHub Actions)
  • Git and GitHub workflows
  • Page Object Model patterns
  • Data-driven testing approaches

Why Cypress?

  • ⚡ Fast, reliable, and intuitive
  • 🎯 Better debugging experience
  • 📱 Responsive testing capabilities
  • 🔄 Excellent CI/CD integration
  • 💪 Strong community and support

Prerequisites

Before you begin, ensure you have the following installed on your system:

System Requirements

  • Node.js (v14.0 or higher) - Download
  • npm (v6.0 or higher) - Comes with Node.js
  • Git (v2.0 or higher) - Download

Required Knowledge

  • Basic JavaScript fundamentals (variables, functions, arrays, objects)
  • Understanding of HTML/CSS selectors
  • Basic command line/terminal usage
  • Familiarity with testing concepts

Recommended Tools

  • Visual Studio Code or any preferred code editor - Download
  • Chrome/Firefox/Edge browser (for testing)
  • Git Bash (for Windows users)
  • Jenkins (for CI/CD examples, optional)

Languages & Technologies

Primary Language

  • JavaScript (100%) - All test scripts and automation code

Core Technologies & Frameworks

TechnologyVersionPurpose
CypressLatestWeb and API automation testing
Node.jsv14+JavaScript runtime environment
npmv6+Package manager
Gitv2+Version control
JenkinsOptionalCI/CD pipeline automation

Testing & Assertion Libraries

  • Mocha - Test framework (built into Cypress)
  • Chai - Assertion library (built into Cypress)
  • Cypress Plugins - Extended functionality

File Structure

Cypress-Automation-Testing-Hero-JavaScript/
│
├── README.md # This file
├── LICENSE # MIT License
├── package.json # Project dependencies and scripts
├── cypress.config.js # Cypress configuration file
│
├── cypress/
│ ├── e2e/ # End-to-end test files
│ │ ├── basic-tests/ # Basic Cypress tests
│ │ ├── advanced-tests/ # Advanced testing scenarios
│ │ └── api-tests/ # API testing examples
│ │
│ ├── support/ # Support files and utilities
│ │ ├── commands.js # Custom Cypress commands
│ │ ├── e2e.js # E2E test setup
│ │ └── helpers.js # Helper functions
│ │
│ ├── fixtures/ # Test data and mock responses
│ │ ├── test-data.json # Sample test data
│ │ └── mock-responses/ # API mock responses
│ │
│ └── pages/ # Page Object Model (POM)
│ ├── base.page.js # Base page class
│ ├── login.page.js # Login page object
│ ├── dashboard.page.js # Dashboard page object
│ └── common.page.js # Common page elements
│
├── config/
│ ├── cypress.env.json # Environment variables
│ ├── dev.config.js # Development configuration
│ └── prod.config.js # Production configuration
│
├── scripts/
│ ├── run-tests.js # Test runner script
│ └── generate-report.js # Report generation
│
├── reports/ # Test reports (generated)
│ └── screenshots/ # Failure screenshots
│
└── .gitignore # Git ignore file

Key Directory Descriptions

cypress/e2e/ - Contains all test files organized by test type
cypress/support/ - Custom commands, hooks, and helper functions
cypress/fixtures/ - Test data files in JSON format
cypress/pages/ - Page Object Model classes for maintaining tests
config/ - Environment-specific configurations
reports/ - Generated test reports and screenshots


Installation & Setup

Step 1: Clone the Repository

git clone https://github.com/BrianGator/Cypress-Automation-Testing-Hero-JavaScript.git
cd Cypress-Automation-Testing-Hero-JavaScript

Step 2: Install Dependencies

npm install

This installs:

  • Cypress
  • Required plugins
  • Testing libraries and dependencies listed in package.json

Step 3: Verify Installation

npx cypress --version

Step 4: Configure Environment Variables

Create a cypress.env.json file in the config/ directory:

{
"baseUrl": "https://example.com",
"apiUrl": "https://api.example.com",
"username": "testuser",
"password": "testpassword",
"env": "staging"
}

Step 5: Open Cypress

npm run cypress:open

How to Use

Running Tests

Open Cypress Test Runner (Interactive Mode)

npm run cypress:open

This opens the Cypress Test Runner GUI where you can select and run tests interactively.

Run All Tests (Headless Mode)

npm run cypress:run

Run Specific Test File

npx cypress run --spec "cypress/e2e/basic-tests/login.cy.js"

Run Tests in Specific Browser

npx cypress run --browser chrome
npx cypress run --browser firefox

Run Tests with Custom Configuration

npx cypress run --config baseUrl=https://staging.example.com

Generate Test Report

npm run report:generate

Example Test Structure

describe('Login Functionality',()=>{beforeEach(()=>{cy.visit('/login');});it('should login with valid credentials',()=>{cy.get('[data-testid="username"]').type('testuser');cy.get('[data-testid="password"]').type('password123');cy.get('button[type="submit"]').click();cy.url().should('include','/dashboard');});it('should display error with invalid credentials',()=>{cy.get('[data-testid="username"]').type('invaliduser');cy.get('[data-testid="password"]').type('wrongpassword');cy.get('button[type="submit"]').click();cy.get('.error-message').should('be.visible');});});

Cypress Methodologies Covered

Selector Strategies

Selecting elements efficiently is crucial for reliable tests. Cypress supports multiple selector strategies:

CSS Selectors

// By element typecy.get('button');// By class namecy.get('.login-button');// By IDcy.get('#username');// By attributecy.get('[data-testid="submit-button"]');// By multiple selectorscy.get('input[type="password"]');cy.get('form .error-message');// Descendant selectorcy.get('.login-form input[type="text"]');

Back to Top

XPath Expressions

// XPath selectorscy.xpath('//button[contains(text(), "Login")]');cy.xpath('//input[@name="email"]');cy.xpath('//div[@class="error"]//span');

Data Attributes (Best Practice)

// Using data-testid (recommended approach)cy.get('[data-testid="username"]').type('testuser');cy.get('[data-testid="password"]').type('password123');cy.get('[data-testid="submit-button"]').click();

Cypress Best Practices for Selectors

// ✅ GOOD: Specific, stable selectorscy.get('[data-testid="login-button"]');cy.get('#userId');cy.get('.primary-button');// ❌ AVOID: Too generic, fragile selectorscy.get('div');cy.get('.container .row .col .btn');cy.xpath('//div[1]/div[2]/div[3]/button[1]');

Back to Top


Command Chaining

Cypress commands can be chained together for efficient test writing. Each command returns a Cypress object for the next command.

Basic Chaining

// Chaining multiple actionscy.get('[data-testid="username"]').type('testuser').should('have.value','testuser').clear().type('newuser');

Chaining with Assertions

// Perform action and verify resultcy.get('button').click().should('have.class','active').should('be.enabled');

Chaining Multiple Elements

// Work with multiple elementscy.get('li').should('have.length',3).first().should('have.text','Item 1').last().should('have.text','Item 3');

Complex Chaining Pattern

describe('Form Submission',()=>{it('should submit form successfully',()=>{cy.visit('/contact').get('[data-testid="name"]').type('John Doe').get('[data-testid="email"]').type('john@example.com').get('[data-testid="message"]').type('Hello World').get('button[type="submit"]').click().get('.success-message').should('contain','Form submitted successfully');});});

Back to Top


Waiting & Synchronization

Cypress automatically waits for elements and commands, but sometimes explicit waits are needed for asynchronous operations.

Implicit Waits

// Cypress waits automatically (default 4000ms)cy.get('[data-testid="element"]');// Waits up to 4 seconds// Configure default timeoutcy.get('[data-testid="slow-element"]',{timeout: 10000});

Explicit Waits

// Wait for specific conditioncy.get('button[type="submit"]').click();cy.get('.loader').should('not.exist');cy.get('.success-message').should('be.visible');

Waiting for Network Requests

// Wait for API responsecy.intercept('GET','/api/users').as('getUsers');cy.visit('/users');cy.wait('@getUsers').then((interception)=>{expect(interception.response.statusCode).to.equal(200);});

Waiting for Element States

// Wait for element to be enabledcy.get('button').should('be.enabled');// Wait for element to be visiblecy.get('.modal').should('be.visible');// Wait for text to appearcy.get('.status').should('contain','Processing complete');// Wait for attribute valuecy.get('input').should('have.value','expected-value');

Complex Async Operations

describe('Async Operations',()=>{it('should handle async data loading',()=>{cy.visit('/dashboard');// Intercept the API callcy.intercept('GET','/api/dashboard').as('loadDashboard');// Trigger action that makes API callcy.get('[data-testid="refresh"]').click();// Wait for the API responsecy.wait('@loadDashboard');// Verify data is displayedcy.get('.dashboard-content').should('be.visible');cy.get('.card').should('have.length.greaterThan',0);});});

Back to Top


Page Object Model (POM)

The Page Object Model is a design pattern for creating reusable, maintainable test code by encapsulating page elements and actions.

Base Page Class

// cypress/pages/base.page.jsexportclassBasePage{constructor(){this.timeout=10000;}visit(url){cy.visit(url);returnthis;}getElement(selector){returncy.get(selector);}clickElement(selector){this.getElement(selector).click();returnthis;}typeText(selector,text){this.getElement(selector).type(text);returnthis;}verifyText(selector,text){this.getElement(selector).should('contain',text);returnthis;}verifyElementVisible(selector){this.getElement(selector).should('be.visible');returnthis;}verifyElementNotVisible(selector){cy.get(selector).should('not.be.visible');returnthis;}}

Login Page Object

// cypress/pages/login.page.jsimport{BasePage}from'./base.page';exportclassLoginPageextendsBasePage{constructor(){super();}// Element selectorsusernameInput='[data-testid="username"]';passwordInput='[data-testid="password"]';loginButton='button[type="submit"]';errorMessage='.error-message';rememberMeCheckbox='[data-testid="remember-me"]';// Page actionsnavigate(){this.visit('/login');returnthis;}enterUsername(username){this.typeText(this.usernameInput,username);returnthis;}enterPassword(password){this.typeText(this.passwordInput,password);returnthis;}clickLoginButton(){this.clickElement(this.loginButton);returnthis;}toggleRememberMe(){this.clickElement(this.rememberMeCheckbox);returnthis;}login(username,password){this.enterUsername(username);this.enterPassword(password);this.clickLoginButton();returnthis;}verifyErrorMessage(expectedMessage){this.getElement(this.errorMessage).should('be.visible').should('contain',expectedMessage);returnthis;}verifySuccessfulLogin(){cy.url().should('include','/dashboard');returnthis;}}

Dashboard Page Object

// cypress/pages/dashboard.page.jsimport{BasePage}from'./base.page';exportclassDashboardPageextendsBasePage{constructor(){super();}// Element selectorswelcomeMessage='.welcome-message';userProfile='[data-testid="user-profile"]';logoutButton='[data-testid="logout"]';navigationMenu='[data-testid="nav-menu"]';dashboardTitle='.dashboard-title';// Page actionsverifyUserLoggedIn(username){this.verifyElementVisible(this.welcomeMessage);this.getElement(this.welcomeMessage).should('contain',`Welcome, ${username}`);returnthis;}navigateTo(menuItem){this.getElement(this.navigationMenu).contains(menuItem).click();returnthis;}logout(){this.clickElement(this.logoutButton);returnthis;}verifyDashboardLoaded(){this.verifyElementVisible(this.dashboardTitle);returnthis;}}

Using Page Objects in Tests

// cypress/e2e/basic-tests/login.cy.jsimport{LoginPage}from'../../pages/login.page';import{DashboardPage}from'../../pages/dashboard.page';describe('Login Feature',()=>{letloginPage;letdashboardPage;beforeEach(()=>{loginPage=newLoginPage();dashboardPage=newDashboardPage();loginPage.navigate();});it('should login successfully with valid credentials',()=>{loginPage.enterUsername('testuser').enterPassword('password123').clickLoginButton();dashboardPage.verifyUserLoggedIn('Test User').verifyDashboardLoaded();});it('should display error with invalid credentials',()=>{loginPage.login('invaliduser','wrongpassword').verifyErrorMessage('Invalid username or password');});it('should remember user when checkbox is selected',()=>{loginPage.toggleRememberMe().login('testuser','password123');dashboardPage.verifyUserLoggedIn('Test User');});});

Back to Top


Assertions & Validations

Assertions verify that the application behaves as expected. Cypress uses Chai assertion library with BDD syntax.

Basic Assertions

// Equality assertionscy.get('[data-testid="count"]').should('have.text','5');cy.get('input').should('have.value','expected-value');cy.get('button').should('have.class','active');// Visibility assertionscy.get('.modal').should('be.visible');cy.get('.hidden-element').should('not.be.visible');// Enable/Disable assertionscy.get('button').should('be.enabled');cy.get('input[disabled]').should('be.disabled');

Text Assertions

// Exact text matchcy.get('h1').should('have.text','Dashboard');// Partial text matchcy.get('h1').should('contain','Dashboard');// Case-insensitive matchcy.get('h1').invoke('text').then(text=>{expect(text.toLowerCase()).to.include('dashboard');});

Array/Collection Assertions

// Check number of elementscy.get('li').should('have.length',5);cy.get('.item').should('have.length.greaterThan',0);// Check first/last elementscy.get('li').first().should('contain','Item 1');cy.get('li').last().should('contain','Item 5');// Filter and checkcy.get('li').contains('Item 3').should('exist');

URL and Navigation Assertions

// Check URLcy.url().should('include','/dashboard');cy.url().should('eq','https://example.com/dashboard');// Check location pathnamecy.location('pathname').should('eq','/dashboard');

Custom Assertions

// Chain multiple assertionscy.get('[data-testid="error"]').should('be.visible').should('have.class','error-message').should('contain','Error occurred');// Assertion with callbackcy.get('.count').then($el=>{expect(parseInt($el.text())).to.be.greaterThan(0);});

Advanced Assertion Patterns

describe('Advanced Assertions',()=>{it('should validate form submission',()=>{// Submit formcy.get('form').submit();// Multiple assertionscy.url().should('include','/success');cy.get('.success-message').should('be.visible').should('contain','Form submitted successfully');cy.get('.confirmation-number').should('exist');});it('should validate API response data',()=>{cy.intercept('GET','/api/users').as('getUsers');cy.visit('/users');cy.wait('@getUsers').then((interception)=>{// Validate response structureexpect(interception.response.statusCode).to.equal(200);expect(interception.response.body).to.have.property('data');expect(interception.response.body.data).to.be.an('array');});});});

Back to Top


API Testing

Test APIs directly using Cypress's cy.request() and cy.intercept() commands.

Basic API Requests

// GET requestcy.request('GET','/api/users').then((response)=>{expect(response.status).to.equal(200);expect(response.body).to.have.property('data');});// POST requestcy.request('POST','/api/users',{name: 'John Doe',email: 'john@example.com'}).then((response)=>{expect(response.status).to.equal(201);expect(response.body).to.have.property('id');});// PUT requestcy.request('PUT','/api/users/1',{name: 'Jane Doe'}).then((response)=>{expect(response.status).to.equal(200);});// DELETE requestcy.request('DELETE','/api/users/1').then((response)=>{expect(response.status).to.equal(204);});

API Testing with Headers

cy.request({method: 'GET',url: '/api/protected-resource',headers: {'Authorization': 'Bearer token123','Content-Type': 'application/json'}}).then((response)=>{expect(response.status).to.equal(200);});

Handling API Errors

// Expect error responsecy.request({method: 'POST',url: '/api/users',body: {email: 'invalid-email'},failOnStatusCode: false}).then((response)=>{expect(response.status).to.equal(400);expect(response.body).to.have.property('error');});

Mocking API Responses

// Intercept and mock API responsecy.intercept('GET','/api/users',{statusCode: 200,body: {data: [{id: 1,name: 'User 1'},{id: 2,name: 'User 2'}]}}).as('getUsers');cy.visit('/users');cy.wait('@getUsers');cy.get('.user-item').should('have.length',2);

API Testing Scenarios

describe('API Testing',()=>{beforeEach(()=>{cy.visit('/api-test');});it('should fetch users list',()=>{cy.intercept('GET','/api/users').as('getUsers');cy.get('[data-testid="load-users"]').click();cy.wait('@getUsers').then((interception)=>{expect(interception.response.statusCode).to.equal(200);expect(interception.response.body).to.be.an('array');});});it('should create user via API',()=>{constnewUser={name: 'John Doe',email: 'john@example.com',role: 'user'};cy.request('POST','/api/users',newUser).then((response)=>{expect(response.status).to.equal(201);expect(response.body.id).to.exist;expect(response.body.name).to.equal('John Doe');});});it('should validate API error handling',()=>{cy.request({method: 'POST',url: '/api/users',body: {email: 'invalid'},failOnStatusCode: false}).then((response)=>{expect(response.status).to.equal(400);expect(response.body.errors).to.exist;});});});

Back to Top


Fixtures & Test Data

Use fixtures to load test data from JSON files for data-driven testing.

Creating Fixture Files

// cypress/fixtures/users.json
{
"validUser": {
"username": "testuser",
"password": "password123",
"email": "test@example.com"
},
"invalidUser": {
"username": "invaliduser",
"password": "wrongpassword"
},
"users": [
{ "id": 1, "name": "User 1", "email": "user1@example.com" },
{ "id": 2, "name": "User 2", "email": "user2@example.com" }
]
}

Loading and Using Fixtures

describe('Using Fixtures',()=>{beforeEach(()=>{// Load fixture before each testcy.fixture('users.json').as('userData');});it('should login with fixture data',function(){cy.visit('/login');cy.get('[data-testid="username"]').type(this.userData.validUser.username);cy.get('[data-testid="password"]').type(this.userData.validUser.password);cy.get('button[type="submit"]').click();cy.url().should('include','/dashboard');});it('should display error with invalid fixture user',function(){cy.visit('/login');cy.get('[data-testid="username"]').type(this.userData.invalidUser.username);cy.get('[data-testid="password"]').type(this.userData.invalidUser.password);cy.get('button[type="submit"]').click();cy.get('.error-message').should('be.visible');});});

Data-Driven Testing

describe('Data-Driven Testing',()=>{consttestCases=[{username: 'user1',password: 'pass1',expected: 'success'},{username: 'user2',password: 'pass2',expected: 'success'},{username: 'invalid',password: 'wrong',expected: 'error'}];testCases.forEach(testCase=>{it(`should handle login for ${testCase.username}`,()=>{cy.visit('/login');cy.get('[data-testid="username"]').type(testCase.username);cy.get('[data-testid="password"]').type(testCase.password);cy.get('button[type="submit"]').click();if(testCase.expected==='success'){cy.url().should('include','/dashboard');}else{cy.get('.error-message').should('be.visible');}});});});

Back to Top


Environment Variables

Configure environment-specific settings for different environments (dev, staging, production).

Environment Configuration File

// config/cypress.env.json
{
"baseUrl": "https://example.com",
"apiUrl": "https://api.example.com",
"username": "testuser",
"password": "testpassword",
"env": "staging"
}

Cypress Configuration

// cypress.config.jsimport{defineConfig}from'cypress';exportdefaultdefineConfig({e2e: {baseUrl: process.env.CYPRESS_BASE_URL||'https://example.com',apiUrl: process.env.CYPRESS_API_URL||'https://api.example.com',env: {environment: process.env.CYPRESS_ENV||'staging',username: process.env.CYPRESS_USERNAME||'testuser',password: process.env.CYPRESS_PASSWORD||'testpassword'}}});

Using Environment Variables in Tests

describe('Environment Configuration',()=>{it('should use environment variables',()=>{// Access via cy.config()constbaseUrl=Cypress.config('baseUrl');constapiUrl=Cypress.env('apiUrl');expect(baseUrl).to.include('example.com');expect(apiUrl).to.include('api');});it('should login to correct environment',()=>{constusername=Cypress.env('username');constpassword=Cypress.env('password');cy.visit('/login');cy.get('[data-testid="username"]').type(username);cy.get('[data-testid="password"]').type(password);cy.get('button[type="submit"]').click();});});

Running Tests with Different Environments

# Development environment
npx cypress run --env baseUrl=https://dev.example.com
# Staging environment
npx cypress run --env baseUrl=https://staging.example.com
# Production environment (for smoke tests)
npx cypress run --env baseUrl=https://example.com

Back to Top


Debugging & Troubleshooting

Learn various techniques for debugging and troubleshooting Cypress tests.

Using Debug Commands

describe('Debugging Techniques',()=>{it('should debug test execution',()=>{cy.visit('/dashboard');// Pause execution for inspectioncy.pause();cy.get('[data-testid="user-profile"]')// Output to browser console.debug().click();// Step through executioncy.step('Check dashboard content');});});

Browser DevTools Integration

it('should leverage browser devtools',()=>{cy.visit('/dashboard');// Open DevTools (in headed mode)cy.get('body').then(()=>{debugger;// This pauses in Chrome DevTools});});

Screenshot and Video Recording

describe('Screenshots and Videos',()=>{it('should capture screenshots',()=>{cy.visit('/dashboard');cy.get('.important-element').screenshot('dashboard-view');cy.screenshot('full-page-screenshot');});afterEach(function(){// Automatically capture screenshot on failureif(this.currentTest.state==='failed'){cy.screenshot('failure-screenshot');}});});

Console Logging

describe('Console Logging',()=>{it('should log information',()=>{cy.visit('/dashboard');cy.get('h1').then(($heading)=>{// Log to Cypress command logcy.log('Heading text: '+$heading.text());// Log to browser consoleconsole.log('Element found:',$heading);});});});

Testing in Debug Mode

# Run tests with extended debugging
npm run cypress:run:debug
# Or with specific debug flags
DEBUG=cypress:* npm run cypress:run

Back to Top


CI/CD Integration

Integrate Cypress tests into CI/CD pipelines for automated testing.

GitHub Actions Workflow

# .github/workflows/cypress-tests.ymlname: Cypress Testson: [push, pull_request]jobs:
test:
runs-on: ubuntu-lateststeps:
- uses: actions/checkout@v2
- name: Setup Node.jsuses: actions/setup-node@v2with:
node-version: '16'
- name: Install dependenciesrun: npm install
- name: Run Cypress testsrun: npm run cypress:run
- name: Upload artifactsif: always()uses: actions/upload-artifact@v2with:
name: cypress-screenshotspath: cypress/screenshots

Jenkins Pipeline

pipeline {
agent any
stages {
stage('Setup') {
steps {
sh 'npm install'
}
}
stage('Run Tests') {
steps {
sh 'npm run cypress:run'
}
}
stage('Generate Report') {
steps {
sh 'npm run report:generate'
}
}
}
post {
always {
junit 'cypress/results/*.xml'
archiveArtifacts artifacts: 'cypress/screenshots/**'
}
}
}

Docker Integration

FROM cypress/base:latest
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "run", "cypress:run"]

Back to Top


Advanced Features

Explore advanced Cypress features for complex testing scenarios.

Custom Commands

// cypress/support/commands.jsCypress.Commands.add('login',(username,password)=>{cy.visit('/login');cy.get('[data-testid="username"]').type(username);cy.get('[data-testid="password"]').type(password);cy.get('button[type="submit"]').click();cy.url().should('include','/dashboard');});Cypress.Commands.add('selectDropdown',(selector,value)=>{cy.get(selector).click();cy.contains(value).click();});// Usage in testsdescribe('Custom Commands',()=>{it('should use custom commands',()=>{cy.login('testuser','password123');cy.selectDropdown('[data-testid="role-dropdown"]','Admin');});});

Handling iframes

describe('iframe Handling',()=>{it('should interact with iframe content',()=>{cy.visit('/page-with-iframe');// Get iframe elementcy.get('iframe[id="myFrame"]').then($iframe=>{const$body=$iframe.contents().find('body');cy.wrap($body).find('[data-testid="button"]').click();});});});

Shadow DOM Testing

describe('Shadow DOM Testing',()=>{it('should interact with shadow DOM elements',()=>{cy.get('custom-element').shadow().find('button').click();});});

File Uploads and Downloads

describe('File Operations',()=>{it('should upload file',()=>{cy.visit('/upload');cy.get('input[type="file"]').selectFile('cypress/fixtures/test-file.csv');cy.get('[data-testid="upload-btn"]').click();cy.get('.success-message').should('be.visible');});it('should verify file download',()=>{cy.visit('/download');cy.get('[data-testid="download-btn"]').click();cy.readFile('cypress/downloads/report.pdf').should('exist');});});

Back to Top


Best Practices

Follow these best practices for writing maintainable, reliable tests.

Test Organization

// ✅ GOOD: Well-organized test structuredescribe('Login Feature',()=>{beforeEach(()=>{cy.visit('/login');});describe('Valid Credentials',()=>{it('should login successfully',()=>{// Test implementation});it('should remember user when checkbox is selected',()=>{// Test implementation});});describe('Invalid Credentials',()=>{it('should display error message',()=>{// Test implementation});it('should not navigate to dashboard',()=>{// Test implementation});});});

Avoiding Flaky Tests

// ❌ AVOID: Flaky test with arbitrary waitsit('should load data',()=>{cy.get('button').click();cy.wait(2000);// Arbitrary wait - unreliablecy.get('.data').should('be.visible');});// ✅ GOOD: Explicit wait for specific conditionit('should load data',()=>{cy.get('button').click();cy.get('.loader').should('not.exist');// Wait for loader to disappearcy.get('.data').should('be.visible');});

Performance Optimization

// ✅ GOOD: Efficient selector usagecy.get('[data-testid="submit"]').click();// ❌ AVOID: Inefficient selectorscy.get('div').get('.container').get('form').get('button').click();

Security Considerations

// ✅ GOOD: Use environment variables for sensitive dataconstusername=Cypress.env('testUsername');constpassword=Cypress.env('testPassword');// ❌ AVOID: Hardcoding credentialsconstusername='admin';constpassword='admin123';

DRY Principle (Don't Repeat Yourself)

// ✅ GOOD: Extract common logicconstloginSteps=(username,password)=>{cy.get('[data-testid="username"]').type(username);cy.get('[data-testid="password"]').type(password);cy.get('button[type="submit"]').click();};describe('Login Tests',()=>{it('should login successfully',()=>{cy.visit('/login');loginSteps('testuser','password123');cy.url().should('include','/dashboard');});it('should show error with invalid credentials',()=>{cy.visit('/login');loginSteps('invalid','wrong');cy.get('.error-message').should('be.visible');});});

Back to Top


Key Features

Comprehensive Examples - From basic to advanced testing scenarios
Page Object Model - Well-structured, maintainable tests
API Testing - Complete guide to testing APIs with Cypress
CI/CD Ready - Jenkins and GitHub Actions configurations
Environment Configuration - Easy switching between dev, staging, production
Real-World Scenarios - Practical examples you can use immediately
Custom Commands - Reusable test utilities
Data-Driven Tests - Parameterized testing with fixtures
Detailed Reports - Comprehensive test reporting
Best Practices - Industry-standard patterns and conventions
Advanced Features - iframes, Shadow DOM, file operations


Getting Started

Quick Start (5 minutes)

  1. Clone the repository

    git clone https://github.com/BrianGator/Cypress-Automation-Testing-Hero-JavaScript.git
    cd Cypress-Automation-Testing-Hero-JavaScript
  2. Install dependencies

    npm install
  3. Open Cypress

    npm run cypress:open
  4. Run your first test

    • Select a test file from the Test Runner
    • Watch it execute in real-time

Next Steps


npm Scripts

{
"scripts": {
"cypress:open": "cypress open",
"cypress:run": "cypress run",
"cypress:run:headed": "cypress run --headed",
"cypress:run:debug": "cypress run --headed --browser chrome --no-exit",
"report:generate": "cypress run && node scripts/generate-report.js",
"test": "cypress run"
}
}

Troubleshooting

Cypress Won't Install

# Clear npm cache and reinstall
npm cache clean --force
npm install

Tests Timing Out

  • Increase timeout in cypress.config.js: defaultCommandTimeout: 10000
  • Use explicit waits: cy.get('selector', { timeout: 15000 })
  • Check Waiting & Synchronization section

Selector Not Found

  • Use Cypress Selector Playground (highlighted in Test Runner)
  • Verify element exists and is visible
  • Check for dynamic IDs or class names
  • Review Selector Strategies section

API Requests Failing

Test Failures and Debugging

  • Enable debug mode: npm run cypress:run:debug
  • Check Debugging & Troubleshooting section
  • Review test videos and screenshots in cypress/screenshots/

Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Resources

Cypress Resources

Learning Resources


License

This project is licensed under the MIT License - see the LICENSE file for details.

Copyright © 2024 Packt


Support & Contact

For issues, questions, or feedback:


Happy Testing! 🎉

Transform yourself into a Cypress Automation Testing Hero! Start with the basics and master advanced techniques step by step. Use the table of contents to navigate to specific topics and expand your testing expertise.

About

Cypress Automation Testing Framework Hero w JavaScript

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages