Cypress Ultimate Architecture is a ready-to-use, production-level Cypress test automation framework designed to kick-start your next QA automation project. It provides a clean, scalable structure that you can easily customize and extend according to your projectβs needs.
git clone https://github.com/pkorolyshyn/cypress-ultimate-architecture.git
cd cypress-ultimate-architecture
npm install
npx cypress open
Happy Testing! π
This framework gives you a head-start by providing a scalable and flexible testing foundation, built on widely used best practices. It's designed for real projectsβwhether you're running small personal apps or scaling enterprise applications with thousands of tests.
Instead of struggling to figure out "the best way," youβll immediately benefit from a proven, maintainable Cypress setup.
-
π§© Page Object Model (POM)
Clearly structured, maintainable testsβno messy selectors or repetitive logic.
Explore Pages β -
π― Reusable Cypress Wrappers
Smart element wrappers help keep your tests clean and readable.
Explore Wrappers β -
πΎ Steps Approach
Write high-level, reusable test steps, clearly separating logic from implementation details.
Explore Steps β -
π Allure Test Reporting
Professional, interactive reports that make debugging easy (and your reports beautiful).
Explore Allure Report β -
π Flexible Environment Handling
Easily switch between testing environmentsβlocal, staging, production.
Explore Environment Handling β -
π·οΈ Cypress Grep Support
Run only the tests you need with flexible tagging.
Explore Grep Tags Usage Example β -
π§Ή Modern JavaScript Quality (ESLint + Prettier)
Maintain clean code standards automatically.
Explore ESLint Configuration β
Explore Prettier Configuration β -
πΆ Git Hooks (Husky)
Automatically catch formatting and linting issues before they enter your repo.
Explore Husky pre-commit Hooks β -
π³ Dockerized CI (GitHub Actions)
A ready-to-go CI pipeline, generating reliable and consistent results for every commit.
Explore Dockerfile β
This section explains how the framework is structured, what each folder or file is responsible for, and how it all connects. You can use this as a reference when modifying or extending the project.
ARCHITECTURE
β
βββ .github/ β GitHub Actions workflows (CI, Allure, Pages)
βββ .husky/ β Git hooks for linting/formatting before commits
β
βββ cypress/
β βββ components/ β Reusable UI parts (e.g., dialogs, header)
β βββ core/ β Base classes for POM structure
β β βββ BaseObject.js β Wrapper selector helpers
β β βββ BaseComponent.js β Shared base for components
β β βββ BasePage.js β Abstract class for page objects
β βββ downloads/ β Auto-generated downloaded files (e.g. CSV, PDF)
β βββ e2e/ β Actual Cypress test files
β βββ fixtures/ β Static test data and style constants
β βββ pages/ β Page objects (LoginPage, CalendarPage, etc.)
β βββ steps/ β Reusable high-level test steps
β βββ support/
β βββ elements/ β Reusable element wrappers
β β βββ SingleElement.js
β β βββ InputElement.js
β β βββ MultiElement.js
β βββ utils/ β Test utilities
β β βββ DateUtils.js
β β βββ AllureMetaUtils.js
β βββ e2e.js β Global setup (Allure, grep, log cleanup)
β
βββ cypress.env1.js β Environment-specific config (baseUrl, creds)
βββ cypress.env2.js
βββ .env β Example local secrets (β οΈ Do not commit real data)
βββ Dockerfile β Run Cypress + Allure in a container
βββ eslint.config.js β Code quality rules (Flat config)
βββ .prettierrc β Code formatting rules
βββ package.json β Project scripts, dependencies, metadata
βββ README.md β Project overview and documentation
Contains GitHub-specific configurations, including CI workflows like running Cypress tests, generating Allure reports, and publishing them to GitHub Pages.
This is where CI/CD magic happens.
Git hook configurations using Husky. Runs automatic checks (like linting and formatting) before commits to keep the codebase clean.
This folder contains reusable UI components used inside pages β like dialogs, modals, or headers.
Theyβre composed inside pages/
to represent smaller parts of a full page.
Core base classes shared across the framework.
BaseObject.js
β Provides.select()
and.selectInput()
helpers to return wrapped Cypress elements.BaseComponent.js
β A minimal extension of BaseObject used for common logic component classes.BasePage.js
β The abstract class that all page objects inherit from. All common pages logic should be here.
Your actual test files live here. Each test file corresponds to a feature or page and imports both:
- Page objects (from
pages/
) - Step definitions (from
steps/
)
Static or shared test data. Can be used to store expected results, constants, styles, or mock API responses.
Contains Page Object classes. Each file represents a specific screen or route in the app, exposing elements and composed components for test use.
Examples:
LoginPage.js
CalendarPage.js
SmartTablePage.js
Each page extends BasePage
and defines selectors + UI composition.
Reusable test steps organized by page or feature. They keep your test logic clean by hiding repetitive Cypress calls behind readable actions.
Shared utilities and wrappers that enhance Cypress behavior.
Custom wrappers that add helpful assertion and action methods to elements.
SingleElement.js
β Used for single DOM elements. Wraps Cypress methods.InputElement.js
β Extends SingleElement and adds input-specific helpers like.type()
and.shouldHavePlaceholder()
.MultiElement.js
β Used for collections of elements (e.g., table rows). Wraps Cypress methods for working with multiple elements.
Project-wide helpers.
DateUtils.js
β Formats or returns the current date.AllureMetaUtils.js
β A helper to inject Allure metadata like tags, severity, and ticket links for each test.
β This file is committed only as an example. You should not commit real passwords or secrets.
It's used to demonstrate how you can manage environment-specific variables (like login credentials) locally via dotenv.
Configuration files for switching between environments (env1
, env2
, etc).
Define your baseUrl
, test user credentials, and any custom env values for Cypress.
You can run a specific config with:
npx cypress run --env envName=env2
Defines a complete containerized environment for running Cypress and generating Allure reports in CI. Includes:
- Cypress with browsers
- Java (for Allure)
- All dependencies and commands to run tests + generate reports
Configures ESLint with:
- Prettier integration
- Best practice rules
- Cypress-specific linting
- CI-friendly restrictions (e.g., no
it.only
)
It helps maintain consistent, high-quality code across the framework.
This project uses Allure to generate clean, interactive, and shareable test reports after every Cypress run.
-
After each CI test run, the framework generates an Allure HTML report.
-
The report is attached as a downloadable artifact inside the GitHub Actions pipeline.
-
The same report is also published to the gh-pages branch so itβs viewable online.
import { allureCypress } from 'allure-cypress/reporter';
import os from 'node:os';
export default {
e2e: {
setupNodeEvents(on, config) {
allureCypress(on, config, {
resultsDir: 'allure-results',
environmentInfo: {
os_platform: os.platform(),
os_release: os.release(),
os_version: os.version(),
node_version: process.version,
env: envName,
},
});
return config;
},
},
};
import 'allure-cypress';
Instead of plain test names, each test can include rich metadata like feature name, story, ticket, tags, and severity using the helper utility:
This utility simplifies adding metadata to tests. You just pass an object and call .apply():
import AllureMeta from '../support/utils/AllureMetaUtils';
it('calendar should display the current date as selected', () => {
new AllureMeta({
feature: 'Calendar',
story: 'Default selected date should be today',
ticket: 'CAL-101',
tags: ['calendar', 'ui', 'smoke'],
severity: 'critical',
}).apply();
// Test steps...
});
After running Cypress tests locally, you can manually generate the Allure report with:
npx allure generate --single-file --clean -o allure-report allure-results
This command will create a single HTML file inside the allure-report
directory.
β οΈ Note: You need to have Java version 8 or above installed on your system to generate the report.
-
For Windows-specific setup, ensure Java is installed and added to the PATH, then install Allure via:
scoop install allure
This framework supports running tests across multiple environments (e.g. dev, staging, production) using dynamic configuration files.
-
Create a new environment config file in the project root.
Example:
cypress.myEnv.js
-
Populate it with environment-specific values:
// cypress.myEnv.js
import dotenv from 'dotenv';
dotenv.config();
export default {
baseUrl: 'https://your-environment-url.com',
env: {
email: '[email protected]',
password: process.env.MY_ENV_PASSWORD, // pulled from .env or GitHub Secret
envName: 'myEnv',
// Add any other custom environment variables here
},
};
- Store sensitive credentials like passwords in the
.env
file locally (do not commit them), use GitHub Secrets CI:
# .env
MY_ENV_PASSWORD=yourStrongPasswordHere!
- Access these values anywhere in your test project using
Cypress.env()
:
cy.get('input[type="email"]').type(Cypress.env('email'));
To execute tests using your new config:
npx cypress open --env envName=myEnv
Or run headlessly in CI:
npx cypress run --env envName=myEnv
The system will automatically load the correct baseUrl
and env
values from your cypress.myEnv.js
file.
This project uses @cypress/grep
plugin to filter and run only the tests you care about β based on tags defined in your specs.
Each test (or suite) can be tagged using the tags
object in the test declaration:
describe('Calendar behavior', { tags: '@calendar' }, () => {
it('should display the current date as selected', { tags: '@smoke' }, () => {
// ...
});
});
Use --env grepTags=
to specify which tags you want to run.
Require Both Tags:
npx cypress run --env grepTags=@smoke+@calendar
Runs only tests that are tagged with both @smoke
and @calendar
.
OR Between Tags:
npx cypress run --env grepTags='@smoke @calendar'
Runs tests tagged with either @smoke
or @calendar
.
β οΈ Donβt forget quotes when using OR (space between tags).
Exclude Tags (Invert):
npx cypress run --env grepTags=-@calendar
Skips all tests tagged with @calendar
.
Include and Exclude Tags:
npx cypress run --env grepTags=@smoke+-@calendar
Runs all @smoke
tests excluding those also tagged with @calendar
.
When triggering Cypress via GitHub Actions:
- Go to the projectβs Actions tab.
- Choose the Cypress E2E Tests workflow.
- Click "Run workflow".
- In the "Cypress tags to run" input field, enter your desired grep tag(s) only.
β Example:
@smoke+@calendar
No need to include --env
or any other flags β just the grep string itself.
Cypress logs every XHR, fetch, and new URL request in the command log, which can sometimes make it hard to focus on what actually matters during debugging.
π‘ To reduce noise, this framework provides an easy toggle to hide XHR and request logs from the Cypress UI.
In e2e.js
, this block dynamically injects CSS to hide specific log entries:
if (Cypress.config('hideXHRInCommandLog')) {
const app = window.top;
const doc = app?.document;
if (doc && !doc.head.querySelector('[data-hide-command-log-request]')) {
const style = doc.createElement('style');
style.setAttribute('data-hide-command-log-request', '');
style.textContent = `
.command-name-request,
.command-name-xhr,
.command-name-new-url {
display: none !important;
}
`;
doc.head.appendChild(style);
}
}
π§ͺ This injection only runs if the config flag is explicitly set.
In your cypress.config.js
, set the flag:
hideXHRInCommandLog: true;
π By default, this option is set to false
so you'll see everything.
π§Ό Set it to true
if you want cleaner logs β especially useful for visual debugging.
- Cypress (https://cypress.io/)
- GitHub Actions (https://docs.github.com/en/actions)
- GitHUb Pages (https://docs.github.com/en/pages)
- Dockerfile (https://docs.docker.com/reference/dockerfile/)
- Cypress Grep (https://www.npmjs.com/package/@cypress/grep)
- ESLint (https://eslint.org/)
- Prettier (https://prettier.io/)
- Husky (https://typicode.github.io/husky/)
- lint-staged (https://www.npmjs.com/package/lint-staged)
Contributions are welcome! If youβd like to improve this framework, feel free to fork it, create a branch, and open a pull request.
Some ideas you could help with:
-
Implement Allure history
-
Any advanced documentation
-
Add more extensive tests for Dialog, Calendar, Echarts, Smart Table, or Auth
-
Add MS Teams chat reporting integration
-
Add more data-testid selectors to the E-commerce page: https://github.com/pkorolyshyn/testing-env1
-
Or anything you think will be suitable and useful
Note: Please avoid writing
tests
for the E-commerce section β it is meant as a playground for users to try the framework and write their own tests.
If youβre unsure how to start, feel free to open an issue or discussion.
Check the full contribution guidelines here: CONTRIBUTING.md