Test Automation

From Zero to Cypress Framework: How to Build a Test Automation Setup That Scales

From zero to a Cypress framework that scales — build a test automation setup that survives real projects. POM, structure, CI/CD and maintainability.

4 min read
From Zero to Cypress Framework: How to Build a Test Automation Setup That Scales
Advertisement
What You Will Learn
Step 1: Initialize the Project
Step 2: Add TypeScript Support
Step 3: Linting + Code Quality
Step 4: Pre-Commit Hooks (Prevent Bad Commits)

If you’ve ever started a new automation project, you know the first few weeks feel magical — everything works locally, your first few tests pass, and you think, “This is easy.”

But fast forward a few months, and things start to fall apart:
⚙️ Inconsistent results.
🧩 Messy folder structures.
🐛 Flaky tests.
📉 CI pipeline chaos.

This happens because most teams treat Cypress as a tool, not a framework.
Let’s change that.

In this guide, we’ll go end-to-end — from project setup to a scalable, CI-ready Cypress framework with TypeScript, linting, reporting, and pre-commit hooks.

Step 1: Initialize the Project

Start from a clean workspace.

mkdir cypress-framework
cd cypress-framework
npm init -y
npm install cypress --save-dev
npx cypress open

This creates the default structure:

cypress/
├── e2e/
├── fixtures/
├── support/
cypress.config.js

Run your first sample test to make sure Cypress boots up correctly.

Step 2: Add TypeScript Support

Cypress supports TypeScript out of the box, but we’ll set it up properly for scalability.

npm install typescript ts-node @types/node --save-dev

Create a tsconfig.json:

{
"compilerOptions": {
"target": "es2018",
"lib": ["es2018", "dom"],
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"types": ["cypress"]
},
"include": ["cypress/**/*.ts"]
}

Rename your .js files under /e2e and /support to .ts.

✅ Benefit: Strong typing for commands, utilities, and fixtures.
✅ Prevents silly runtime errors.

Step 3: Linting + Code Quality

Good frameworks enforce standards.

npm install eslint eslint-plugin-cypress --save-dev

Create .eslintrc.js:

module.exports = {
env: {
browser: true,
es2021: true,
'cypress/globals': true,
},
extends: ['eslint:recommended', 'plugin:cypress/recommended'],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
},
plugins: ['cypress'],
rules: {
semi: ['error', 'always'],
quotes: ['error', 'single'],
},
};

Run lint:

npx eslint cypress/**/*.ts

Step 4: Pre-Commit Hooks (Prevent Bad Commits)

Install Husky and lint-staged to enforce quality before every git commit.

npm install husky lint-staged --save-dev
npx husky install
npm set-script prepare "husky install"

Add a pre-commit hook:

npx husky add .husky/pre-commit "npx lint-staged"

Now configure lint-staged in your package.json:

"lint-staged": {
"*.ts": "eslint --fix"
}

✅ Ensures no one pushes broken code.
✅ Keeps your repo clean and consistent.

Step 5: Framework Folder Structure

Let’s make it maintainable.

cypress/
├── e2e/
│ ├── auth/
│ │ ├── login.cy.ts
│ │ ├── signup.cy.ts
│ ├── dashboard/
│ ├── analytics.cy.ts
│ ├── reports.cy.ts

├── support/
│ ├── commands/
│ │ ├── login.ts
│ │ ├── api.ts
│ ├── utils/
│ │ ├── dateHelper.ts
│ │ ├── intercepts.ts
│ ├── e2e.ts

├── fixtures/
│ ├── users.json
│ ├── products.json

├── config/
│ ├── dev.json
│ ├── staging.json
│ ├── prod.json

├── plugins/
│ ├── index.ts

├── reports/
├── screenshots/
├── videos/

✅ Domain-based separation
✅ Easy scalability
✅ Clear ownership

Step 6: Reporting Integration (Allure / Mochawesome)

Example using Mochawesome:

npm install mochawesome mochawesome-merge mochawesome-report-generator --save-dev

Add reporter to config:

// cypress.config.ts
import { defineConfig } from 'cypress'

export default defineConfig({
e2e: {
reporter: 'mochawesome',
reporterOptions: {
reportDir: 'cypress/reports',
overwrite: false,
html: false,
json: true,
},
},
});

Merge + generate report:

npx mochawesome-merge cypress/reports/*.json > cypress/reports/output.json
npx marge cypress/reports/output.json

Boom 💥 — a clean HTML report for management.

Step 7: Parallel Execution in CI/CD

Use GitHub Actions or GitLab CI to parallelize tests by folders:

jobs:
cypress-run:
runs-on: ubuntu-latest
strategy:
matrix:
group: [auth, dashboard, api]
steps:
- uses: actions/checkout@v3
- uses: cypress-io/github-action@v6
with:
spec: cypress/e2e/${{ matrix.group }}/**
record: true

✅ Parallel runs
✅ Auto artifacts
✅ Consistent pipelines

Bonus: Auto Retry Flaky Tests

npm install cypress-retries --save-dev
// cypress.config.ts
import 'cypress-retries';
// Example usage
it('should load dashboard', { retries: 2 }, () => {
cy.visit('/dashboard');
cy.contains('Analytics');
});

🧠 Final Thoughts

The difference between test scripts and a test framework is engineering.

If you want your automation to scale like your app does:

  • Use TypeScript for type safety
  • Use linting and hooks for quality
  • Use proper reporting for visibility
  • Design like a developer, test like an engineer

💬 Pro tip: Don’t aim for “tests that pass.”
Aim for a system that sustains — clean, maintainable, and production-ready.

Advertisement
Found this helpful? Clap to let Shahnawaz know — you can clap up to 50 times.