Developer: Sakharam Thorat
Develop an automated test suite for the Sauce Labs demo website. The test suite should automate the customer flow of selecting three random items from the inventory, adding them to the cart, and completing the checkout process. The automation should ensure thorough coverage of this flow, validating key functionalities and user interactions throughout the process.
- Introduction
- Project Structure
- Setup Instructions
- Test Flow
- Assertions
- Reporting
- Page Object Model
- Running the Tests
- Writing New Test Cases
- CI/CD Using GitHub Actions
This project comprises an automated test suite developed for the Sauce Labs demo website. Its primary objective is to automate the customer journey of selecting three random items from the inventory, adding them to the cart, and completing the checkout process. The tests are implemented using Cypress with TypeScript, ensuring a robust and maintainable codebase.
Key features of this project include:
- Design Pattern - Page Object Model (POM): Enhances code maintainability and readability by organizing test interactions in separate classes for different pages.
- ESLint and Prettier Integration: Ensures code quality and consistency. ESLint helps in identifying and fixing problems in the JavaScript code, while Prettier automatically formats the code to maintain a consistent style.
- Cross-browser Testing: The CI workflow supports running test cases on four browsers: Chrome, Firefox, Edge, and Electron.
.
├── .eslintrc.js # ESLint configuration
├── .github/ # GitHub workflows for CI/CD
│ └── workflows/
│ ├── quality.yml # Workflow for code quality checks
│ └── up-e2e-ui-cypress.yml # Workflow for E2E tests with Cypress
├── .gitignore # Git ignore file
├── .nvmrc # Node version manager configuration
├── .prettierrc # Prettier configuration
├── README.md # Project documentation
├── cypress/ # Cypress tests and configurations
│ ├── downloads/ # Directory for downloaded files during tests
│ ├── e2e/ # E2E test specifications
│ │ └── sauce-demo.cy.ts # Main test file for Sauce Labs demo
│ ├── fixtures/ # Test data and network request mocks
│ │ ├── example.json # Example fixture file
│ │ └── networkRequests.json # Network requests data
│ ├── page-objects/ # Page Object Model classes
│ │ ├── base-page.ts # Base page with common methods
│ │ ├── cart-page.ts # Page object for the cart page
│ │ ├── checkout-page.ts # Page object for the checkout page
│ │ ├── inventory-page.ts # Page object for the inventory page
│ │ └── login-page.ts # Page object for the login page
│ ├── reports/ # Test reports
│ │ ├── chrome/ # Chrome browser reports
│ │ │ ├── chrome-ats-report.html # Chrome test report
│ │ │ └── videos/ # Videos recorded during Chrome tests
│ │ │ └── sauce-demo.cy.ts.mp4 # Test video
│ │ ├── edge/ # Edge browser reports
│ │ │ ├── edge-ats-report.html # Edge test report
│ │ │ └── videos/ # Videos recorded during Edge tests
│ │ │ └── sauce-demo.cy.ts.mp4 # Test video
│ │ ├── electron/ # Electron browser reports
│ │ │ ├── electron-ats-report.html # Electron test report
│ │ │ └── videos/ # Videos recorded during Electron tests
│ │ │ └── sauce-demo.cy.ts.mp4 # Test video
│ │ └── firefox/ # Firefox browser reports
│ │ ├── firefox-ats-report.html # Firefox test report
│ │ └── videos/ # Videos recorded during Firefox tests
│ ├── screenshots/ # Screenshots taken during tests
│ ├── support/ # Support files and custom commands
│ │ ├── commands.ts # Custom Cypress commands
│ │ ├── e2e.ts # E2E test setup and teardown
│ │ ├── index.d.ts # TypeScript definitions
│ │ └── index.ts # Support file initialization
│ ├── tsconfig.json # TypeScript configuration for Cypress
│ └── videos/ # Videos recorded during tests
│ └── sauce-demo.cy.ts.mp4 # Test video
├── cypress.config.ts # Cypress configuration
├── package-lock.json # NPM lock file
├── package.json # NPM dependencies and scripts
└── tsconfig.json # TypeScript configuration
- .eslintrc.js, .prettierrc: Configuration files for ESLint and Prettier.
- .github/workflows/: GitHub Actions workflows for quality checks and CI.
- .gitignore: Git ignore rules to exclude certain files and folders.
- .nvmrc: Node version manager configuration for consistent Node.js version.
- cypress/: Cypress test automation framework setup.
- package.json, package-lock.json: Node.js dependencies and lock file.
- tsconfig.json: TypeScript configuration for compiling TypeScript code.
git clone https://github.com/srthorat/sauce-lab-ats-cypress-typescript.git
cd sauce-lab-ats-cypress-typescript npm install npx cypress openThe test suite automates the following flow:
- Login to the Sauce Labs demo website.
- Navigate to the inventory page.
- Select three random items from the inventory.
- Add selected items to the cart.
- Proceed to checkout.
- Fill in the checkout information.
- Verify the prices and complete the checkout.
The test suite includes assertions to verify:
- The prices of the selected items.
- The total price and tax on the checkout page.
- The successful completion message after checkout.
Reporting The project uses Cypress with Mochawesome reporter to generate detailed reports and videos:
-
HTML Reports: Detailed test execution reports for each browser are stored in the following directories:
- Chrome: cypress/reports/chrome
- Firefox: cypress/reports/firefox
- Edge: cypress/reports/edge
- Electron: cypress/reports/electron
Each browser directory contains HTML reports named according to the browser and test suite (chrome-ats-report.html, firefox-ats-report.html, etc.).
-
Videos: Videos of test executions for each browser are recorded and stored in the respective browser's report directories under cypress/reports//videos.
-
Logs: Detailed logs for debugging purposes are also available, providing insights into test execution and any errors encountered.
Note: There is all redy existing issue with firefox for screenshot and recording cypress-io/cypress#18415 - Video functionality is not working on Firefox 93 and above
The Page Object Model (POM) design pattern is implemented to enhance code maintainability and readability. Key page objects include:
- BasePage: Contains common methods used by other page objects.
- LoginPage: Methods to interact with the login page.
- InventoryPage: Methods to interact with the inventory page.
- CartPage: Methods to interact with the cart page.
- CheckoutPage: Methods to interact with the checkout page.
// cypress/page-objects/login-page.ts
/// <reference types="cypress" />
import BasePage from './base-page';
class LoginPage extends BasePage {
private userNameInput = '#user-name';
private passwordInput = '#password';
private loginButton = '#login-button';
// Method to login with credentials
public login(username: string, password: string) {
this.type(this.userNameInput, username);
this.type(this.passwordInput, password);
this.click(this.loginButton);
cy.logAndReport(`==> Successfully logged in with username: ${username}`);
}
public verifyPageTitleDisplayedCorrectly(titleContains: string) {
cy.title().should('contain', titleContains);
cy.logAndReport(
`==> Sucessfully verified Page title displayed, it contains - ${titleContains}`,
);
}
}
export default LoginPage;The following npm scripts are defined to run tests:
"scripts": {
"cypress:run": "cypress run --config-file ./cypress.config.ts",
"cypress:open": "cypress open --config-file ./cypress.config.ts",
"cypress:run:chrome": "cypress run --browser chrome --headless --config-file ./cypress.config.ts --reporter cypress-mochawesome-reporter --reporter-options reportDir=cypress/reports/chrome,reportFilename=chrome-ats-report",
"cypress:run:firefox": "cypress run --browser firefox --headless --config-file ./cypress.config.ts --reporter cypress-mochawesome-reporter --reporter-options reportDir=cypress/reports/firefox,reportFilename=firefox-ats-report",
"cypress:run:edge": "cypress run --browser edge --headless --config-file ./cypress.config.ts --reporter cypress-mochawesome-reporter --reporter-options reportDir=cypress/reports/edge,reportFilename=edge-ats-report",
"cypress:run:electron": "cypress run --browser electron --headless --config-file ./cypress.config.ts --reporter cypress-mochawesome-reporter --reporter-options reportDir=cypress/reports/electron,reportFilename=electron-ats-report",
"cypress:run:all": "npm run cypress:run:chrome && npm run cypress:run:firefox && npm run cypress:run:edge && npm run cypress:run:electron"
}-
Set Environment Variables: This is must do step else all test will fail
export CYPRESS_username=username export CYPRESS_password=password
Note: Replace username and password with your actual credentials.
or
To run tests with environment variables:
CYPRESS_username=username CYPRESS_password=password npm run cypress:run:all
-
Run All Tests: This will run test on all four browser sequentially
npm run cypress:run:all -
Run Tests in Specific Browser:
npm run cypress:run:chrome npm run cypress:run:firefox npm run cypress:run:edge npm run cypress:run:electron
These scripts utilize Cypress with Mochawesome reporter for generating detailed HTML reports in respective directories (cypress/reports/chrome, cypress/reports/firefox, cypress/reports/edge, cypress/reports/electron). The --headless flag ensures tests run without launching a browser window, suitable for automated CI/CD pipelines.
When writing new test cases, follow these steps:
- Create a New Spec File: Add a new .ts file in the cypress/e2e directory.
- Use Page Objects: Leverage existing page objects to interact with the application.
- Add Assertions: Ensure appropriate assertions are in place to validate the test flow.
- Run and Validate: Execute the test locally to ensure it works as expected.
// cypress/e2e/new-test.cy.ts
import LoginPage from '../page-objects/login-page';
import InventoryPage from '../page-objects/inventory-page';
import CartPage from '../page-objects/cart-page';
import CheckoutPage from '../page-objects/checkout-page';
describe('New Test Suite', () => {
const loginPage = new LoginPage();
const inventoryPage = new InventoryPage();
const cartPage = new CartPage();
const checkoutPage = new CheckoutPage();
it('should complete a new test flow', () => {
cy.visit('/');
loginPage.login('standard_user', 'secret_sauce');
inventoryPage.addThreeRandomItemsToCart();
cartPage.proceedToCheckout();
checkoutPage.fillInCheckoutInformation('First', 'Last', '12345');
checkoutPage.completeCheckout();
cy.contains('Thank you for your order').should('be.visible');
});
});This project uses GitHub Actions for Continuous Integration and Continuous Deployment (CI/CD) to ensure that the automated tests run smoothly and efficiently with every code change.
GitHub Actions are defined in YAML files located in the .github/workflows/ directory. The workflows are triggered on specific events, such as pushes to the repository or pull requests.
- Go to your GitHub repository.
- Navigate to Settings > Secrets and variables > Actions.
- Click on New repository secret and add the following secrets:
- username: Your Sauce Labs demo website username.
- password: Your Sauce Labs demo website password.
Note: I have all redy addy in my GitHub Repo
The quality.yml workflow ensures code quality by running linting and formatting checks using ESLint and Prettier.
name: Quality Checks
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '18.x'
- name: Install dependencies
run: npm install
- name: Run ESLint
run: npm run lint
- name: Run Prettier
run: npm run formatThe sauce-demo-ui-cypress.yml workflow runs the Cypress end-to-end tests across multiple browsers.
name: Sauce Demo UI Cypress Tests
on:
workflow_dispatch:
pull_request:
branches:
- develop
jobs:
sauce-demo-ui-cypress:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup NodeJS 18
uses: actions/setup-node@v3
with:
node-version: 18
- name: Install
run: npm ci
- name: Run Sauce Demo UI Cypress Tests
run: CYPRESS_username=${{ secrets.USERNAME }} CYPRESS_password=${{ secrets.PASSWORD }} npm run cypress:run:all
- name: Upload Cypress Videos
if: always()
uses: actions/upload-artifact@v2
with:
name: cypress-videos
path: cypress/videos
- name: Upload Cypress Screenshots
if: always()
uses: actions/upload-artifact@v2
with:
name: cypress-screenshots
path: cypress/screenshots
- name: Upload Cypress Reports
if: always()
uses: actions/upload-artifact@v2
with:
name: cypress-reports
path: cypress/reports- Triggers: The workflow runs on any push or pull request to the develop branch.
- Environment Variables: The CYPRESS_username and CYPRESS_password environment variables are set using the secrets added to the GitHub repository.
- Checkout: The code is checked out from the repository.
- Setup Node.js: Node.js version 18.7.0 is set up.
- Install Dependencies: The required dependencies are installed using npm install.
- Run Cypress Tests: The Cypress tests are executed across all specified browsers using the npm run cypress:run:all script.
- No Need to Clone: There is no need to clone the code and run it - on your computer. You can directly go to the repository and run the GitHub Action.
- Run the Action: Once the action is completed, go to the workflow run tab.
- Download Reports: Download the report to see the results.
Environment variables for your tests can be set up in the GitHub Actions workflow file to securely manage sensitive information such as usernames and passwords.
The workflows are automatically triggered based on the events specified. You can also manually trigger workflows from the GitHub Actions tab in your repository.
By integrating GitHub Actions into your CI/CD pipeline, you ensure that your test suite is executed consistently with every change, maintaining code quality and reliability.