Skip to main content

Directory Overview

The framework follows a clean, organized structure that separates concerns and promotes maintainability:
cypress/
├── cypress.config.ts         # Base configuration (generic)
├── cypress.config.ui.ts      # UI test configuration
├── cypress.config.api.ts     # API test configuration
├── package.json              # Dependencies and scripts
├── e2e/
   ├── api/                  # API test files
   └── GETSpec.cy.ts
   └── ui/                   # UI test files
       ├── LoginPageSpec.cy.ts
       ├── HomePageSpec.cy.ts
       └── CheckoutPageSpec.cy.ts
├── fixtures/
   ├── users.json            # User test data
   ├── loginPageData.json    # Login page messages
   └── bookings.json         # API test data
├── support/
   ├── commands.ts           # Custom Cypress commands
   ├── e2e.ts                # Global test setup
   ├── pages/                # Page Object classes
   ├── BasePage.ts       # Base page class
   ├── LoginPage.ts      # Login page object
   ├── HomePage.ts       # Home page object
   └── Checkout.ts       # Checkout page object
   └── components/           # Reusable component objects
       └── Navbar.ts         # Navbar component

Configuration Files

UI Configuration

The UI configuration targets web application testing:
cypress.config.ui.ts
import { defineConfig } from "cypress";

export default defineConfig({
  e2e: {
    baseUrl: 'https://www.saucedemo.com/',
    specPattern: 'cypress/e2e/ui/**/*.cy.ts',
    supportFile: 'cypress/support/e2e.ts',
    watchForFileChanges: false,
    setupNodeEvents(on, config) {
      // implement node event listeners here
    },
  },
});
Key Settings:
  • baseUrl: Base URL for all cy.visit() calls in UI tests
  • specPattern: Only runs tests in the ui/ directory
  • watchForFileChanges: Disabled to prevent auto-reloading during development

API Configuration

The API configuration is optimized for REST API testing:
cypress.config.api.ts
import { defineConfig } from "cypress";

export default defineConfig({
  e2e: {
    baseUrl: 'https://restful-booker.herokuapp.com',
    specPattern: 'cypress/e2e/api/**/*.cy.ts',
    supportFile: 'cypress/support/e2e.ts',
    watchForFileChanges: false,
    setupNodeEvents(on, config) {
      // implement node event listeners here
    },
  },
});
Key Differences:
  • baseUrl: Points to the API endpoint
  • specPattern: Only runs tests in the api/ directory
Having separate configurations allows you to maintain different settings for UI and API tests, such as different timeouts, viewport sizes, or environment variables.

Test Directories

UI Tests (e2e/ui/)

Contains all UI-focused test files:
  • LoginPageSpec.cy.ts: Tests for authentication flows
  • HomePageSpec.cy.ts: Tests for home page functionality (sorting, filtering)
  • CheckoutPageSpec.cy.ts: Tests for checkout process
All UI test files follow the naming convention *Spec.cy.ts or *.cy.ts. The .cy.ts extension is required for Cypress to recognize test files.

API Tests (e2e/api/)

Contains all API test files:
  • GETSpec.cy.ts: Tests for GET requests, response validation, and performance
API tests directly use Cypress’s cy.request() command without page objects.

Fixtures Directory

Fixtures store test data as JSON files, providing:
  • Centralized data management: One place to update test data
  • Reusability: Multiple tests can share the same data
  • Separation of concerns: Keep test data separate from test logic

Example: Users Fixture

users.json
{
  "standard": "standard_user",
  "locked": "locked_out_user",
  "problem": "problem_user",
  "performance": "performance_glitch_user",
  "error": "error_user",
  "visual": "visual_user",
  "password": "secret_sauce"
}
Usage in tests:
cy.fixture('users').then((user: any) => {
  loginPage.typeUsername(user.standard)
  loginPage.typePassword(user.password)
})

Example: API Data Fixture

bookings.json
[
  {
    "firstname": "James",
    "lastname": "Brown",
    "totalprice": 111,
    "depositpaid": true,
    "bookingdates": {
      "checkin": "2018-01-01",
      "checkout": "2019-01-01"
    }
  }
]

Support Directory

Page Objects (support/pages/)

Page objects encapsulate page-specific logic:
BasePage.ts
export default class BasePage {
    public inventoryItem: string

    constructor() {
        this.inventoryItem = '[data-test="inventory-item"]'
    }

    protected goToUrl(url: string): void {
        cy.visit(url)
    }
}
All page objects extend BasePage for shared functionality.

Custom Commands (support/commands.ts)

Define reusable Cypress commands for common operations:
Cypress.Commands.add('login', (username: string, password: string) => {
  cy.get('#user-name').type(username)
  cy.get('#password').type(password)
  cy.get('#login-button').click()
})

Global Setup (support/e2e.ts)

Loads before every test file:
e2e.ts
// Import commands.js using ES2015 syntax:
import './commands'
Use this file for:
  • Importing custom commands
  • Global beforeEach hooks
  • Third-party plugin initialization

File Naming Conventions

Test Files

*.cy.ts - Cypress test specification files

Page Objects

PascalCase.ts - Page object class files

Fixtures

camelCase.json - Test data fixture files

Config Files

cypress.config.*.ts - Configuration files

TypeScript Integration

All test files use TypeScript for:
  • Type safety: Catch errors before runtime
  • IntelliSense: Better autocomplete in IDEs
  • Refactoring: Safer code modifications
  • Documentation: Types serve as inline documentation
While TypeScript is used, there’s no tsconfig.json in the root. Cypress uses its own TypeScript configuration internally. You can add a custom tsconfig.json if you need specific compiler options.

Best Practices

  1. Keep tests in appropriate directories: UI tests in ui/, API tests in api/
  2. Use fixtures for test data: Never hardcode test data in test files
  3. One page object per page: Each page should have its own class
  4. Extend BasePage: Inherit common functionality from the base class
  5. Descriptive file names: Names should indicate what’s being tested

Next Steps

Page Object Model

Learn the POM pattern in detail

Configuration

Deep dive into configuration options

Creating Page Objects

Build your own page objects

Using Fixtures

Master test data management

Build docs developers (and LLMs) love