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.
- Overview
- Prerequisites
- Languages & Technologies
- File Structure
- Installation & Setup
- How to Use
- Cypress Methodologies Covered
- Key Features
- Getting Started
- npm Scripts
- Troubleshooting
- Contributing
- Resources
- License
- Support & Contact
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
Before you begin, ensure you have the following installed on your system:
- Node.js (v14.0 or higher) - Download
- npm (v6.0 or higher) - Comes with Node.js
- Git (v2.0 or higher) - Download
- Basic JavaScript fundamentals (variables, functions, arrays, objects)
- Understanding of HTML/CSS selectors
- Basic command line/terminal usage
- Familiarity with testing concepts
- 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)
- JavaScript (100%) - All test scripts and automation code
| Technology | Version | Purpose |
|---|---|---|
| Cypress | Latest | Web and API automation testing |
| Node.js | v14+ | JavaScript runtime environment |
| npm | v6+ | Package manager |
| Git | v2+ | Version control |
| Jenkins | Optional | CI/CD pipeline automation |
- Mocha - Test framework (built into Cypress)
- Chai - Assertion library (built into Cypress)
- Cypress Plugins - Extended functionality
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
cypress/e2e/ - Contains all test files organized by test typecypress/support/ - Custom commands, hooks, and helper functionscypress/fixtures/ - Test data files in JSON formatcypress/pages/ - Page Object Model classes for maintaining testsconfig/ - Environment-specific configurationsreports/ - Generated test reports and screenshots
git clone https://github.com/BrianGator/Cypress-Automation-Testing-Hero-JavaScript.git
cd Cypress-Automation-Testing-Hero-JavaScriptnpm installThis installs:
- Cypress
- Required plugins
- Testing libraries and dependencies listed in
package.json
npx cypress --versionCreate a cypress.env.json file in the config/ directory:
{
"baseUrl": "https://example.com",
"apiUrl": "https://api.example.com",
"username": "testuser",
"password": "testpassword",
"env": "staging"
}npm run cypress:opennpm run cypress:openThis opens the Cypress Test Runner GUI where you can select and run tests interactively.
npm run cypress:runnpx cypress run --spec "cypress/e2e/basic-tests/login.cy.js"npx cypress run --browser chrome
npx cypress run --browser firefoxnpx cypress run --config baseUrl=https://staging.example.comnpm run report:generatedescribe('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');});});Selecting elements efficiently is crucial for reliable tests. Cypress supports multiple selector strategies:
// 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"]');// XPath selectorscy.xpath('//button[contains(text(), "Login")]');cy.xpath('//input[@name="email"]');cy.xpath('//div[@class="error"]//span');// 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();// ✅ 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]');Cypress commands can be chained together for efficient test writing. Each command returns a Cypress object for the next command.
// Chaining multiple actionscy.get('[data-testid="username"]').type('testuser').should('have.value','testuser').clear().type('newuser');// Perform action and verify resultcy.get('button').click().should('have.class','active').should('be.enabled');// Work with multiple elementscy.get('li').should('have.length',3).first().should('have.text','Item 1').last().should('have.text','Item 3');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');});});Cypress automatically waits for elements and commands, but sometimes explicit waits are needed for asynchronous operations.
// 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});// Wait for specific conditioncy.get('button[type="submit"]').click();cy.get('.loader').should('not.exist');cy.get('.success-message').should('be.visible');// 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);});// 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');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);});});The Page Object Model is a design pattern for creating reusable, maintainable test code by encapsulating page elements and actions.
// 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;}}// 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;}}// 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;}}// 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');});});Assertions verify that the application behaves as expected. Cypress uses Chai assertion library with BDD syntax.
// 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');// 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');});// 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');// Check URLcy.url().should('include','/dashboard');cy.url().should('eq','https://example.com/dashboard');// Check location pathnamecy.location('pathname').should('eq','/dashboard');// 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);});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');});});});Test APIs directly using Cypress's cy.request() and cy.intercept() commands.
// 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);});cy.request({method: 'GET',url: '/api/protected-resource',headers: {'Authorization': 'Bearer token123','Content-Type': 'application/json'}}).then((response)=>{expect(response.status).to.equal(200);});// 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');});// 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);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;});});});Use fixtures to load test data from JSON files for data-driven testing.
// 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" }
]
}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');});});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');}});});});Configure environment-specific settings for different environments (dev, staging, production).
// config/cypress.env.json
{
"baseUrl": "https://example.com",
"apiUrl": "https://api.example.com",
"username": "testuser",
"password": "testpassword",
"env": "staging"
}// 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'}}});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();});});# 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.comLearn various techniques for debugging and troubleshooting Cypress tests.
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');});});it('should leverage browser devtools',()=>{cy.visit('/dashboard');// Open DevTools (in headed mode)cy.get('body').then(()=>{debugger;// This pauses in Chrome DevTools});});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');}});});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);});});});# Run tests with extended debugging
npm run cypress:run:debug
# Or with specific debug flags
DEBUG=cypress:* npm run cypress:runIntegrate Cypress tests into CI/CD pipelines for automated testing.
# .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/screenshotspipeline {
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/**'
}
}
}FROM cypress/base:latest
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "run", "cypress:run"]Explore advanced Cypress features for complex testing scenarios.
// 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');});});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();});});});describe('Shadow DOM Testing',()=>{it('should interact with shadow DOM elements',()=>{cy.get('custom-element').shadow().find('button').click();});});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');});});Follow these best practices for writing maintainable, reliable tests.
// ✅ 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});});});// ❌ 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');});// ✅ GOOD: Efficient selector usagecy.get('[data-testid="submit"]').click();// ❌ AVOID: Inefficient selectorscy.get('div').get('.container').get('form').get('button').click();// ✅ GOOD: Use environment variables for sensitive dataconstusername=Cypress.env('testUsername');constpassword=Cypress.env('testPassword');// ❌ AVOID: Hardcoding credentialsconstusername='admin';constpassword='admin123';// ✅ 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');});});✅ 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
Clone the repository
git clone https://github.com/BrianGator/Cypress-Automation-Testing-Hero-JavaScript.git cd Cypress-Automation-Testing-Hero-JavaScriptInstall dependencies
npm install
Open Cypress
npm run cypress:open
Run your first test
- Select a test file from the Test Runner
- Watch it execute in real-time
- Explore example tests in
cypress/e2e/ - Learn the Page Object Model in Page Object Model section
- Customize
cypress.env.jsonwith your test URLs - Write your first custom test!
- Review Best Practices section for code quality tips
{
"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"
}
}# Clear npm cache and reinstall
npm cache clean --force
npm install- Increase timeout in
cypress.config.js:defaultCommandTimeout: 10000 - Use explicit waits:
cy.get('selector', { timeout: 15000 }) - Check Waiting & Synchronization section
- 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
- Check network tab in Chrome DevTools
- Verify baseUrl and API endpoints in Environment Variables
- Check for CORS issues
- Review API Testing section
- Enable debug mode:
npm run cypress:run:debug - Check Debugging & Troubleshooting section
- Review test videos and screenshots in
cypress/screenshots/
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Copyright © 2024 Packt
For issues, questions, or feedback:
- Open an issue on GitHub
- Check existing issues for solutions
- Review the Cypress documentation
- Refer to troubleshooting section
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.