A production-ready Cypress automation framework with Page Object Model, supporting UI, API, and Accessibility testing. Features comprehensive ChatGPT interface testing capabilities.
- TypeScript support with type definitions
- ChatGPT interface testing suite
- Comprehensive accessibility testing
- Page Object Model implementation
- API testing capabilities with custom commands
- Parallel test execution
- CI/CD ready with GitHub Actions
- Environment-based configuration
- Comprehensive reporting
- Built-in retry mechanisms for flaky tests
Advantages | Disadvantages |
---|---|
✅ Real-time reload and time travel debugging | ❌ Single browser tab execution |
✅ Automatic waiting and retry mechanisms | ❌ Limited cross-domain testing |
✅ Consistent and reliable tests | ❌ No support for multiple browser windows |
✅ Built-in screenshots and videos | ❌ Limited iframe support |
✅ Excellent developer experience and debugging | ❌ No native mobile testing support |
✅ Modern JavaScript stack and syntax | ❌ Same-origin policy limitations |
✅ Rich ecosystem of plugins | ❌ CPU/Memory intensive for large suites |
✅ Comprehensive documentation | ❌ Limited support for file downloads |
✅ Active community support | ❌ Requires JavaScript knowledge |
✅ Built-in network stubbing | ❌ Browser support limited to Chrome-family |
✅ Native access to browser APIs | ❌ Not suitable for native mobile apps |
✅ Simple setup and configuration | ❌ Complex iframe handling |
✅ API testing capabilities | ❌ Limited parallel testing in open source |
✅ TypeScript support | ❌ Higher resource usage than Selenium |
✅ Command chaining for better readability | ❌ Learning curve for non-JS developers |
-
Best For:
- Modern web applications
- Single page applications (SPAs)
- Real-time testing feedback
- JavaScript/TypeScript projects
- E2E and Component testing
- API testing
-
Not Ideal For:
- Native mobile testing
- Multi-tab scenarios
- Complex iframe operations
- Cross-browser testing at scale
- Non-JavaScript applications
- Limited resource environments
- Clone and Install
git clone https://github.com/padmarajnidagundi/Cypress-POM-Ready-To-Use
cd Cypress-POM-Ready-To-Use
- Setup Project
npm run presetup # Install all dependencies
npm run setup # Install Cypress
npm run verify # Verify Cypress installation
- Open Cypress
npm run cypress:open # Open Cypress Test Runner
- Run Tests
npm run test:ui # Run UI tests
npm run test:api # Run API tests
npm run test:parallel # Run all tests in parallel
npm run test:ci # Run tests in CI mode
If you encounter the error 'cypress' is not recognized as an internal or external command
, follow these steps:
- Clear npm cache and node_modules:
npm cache clean --force
rm -rf node_modules
rm -rf package-lock.json
- Reinstall dependencies:
npm run presetup
- Verify installation:
npm run verify
- Test Cypress:
npm run cypress:open
- Create Page Objects
// cypress/pageObjects/pages/loginPage.ts
import BasePage from '../basePage'
class LoginPage extends BasePage {
private selectors = {
username: '#username',
password: '#password',
submitBtn: '[data-testid="login-btn"]'
}
login(username: string, password: string) {
this.getElement(this.selectors.username).type(username)
this.getElement(this.selectors.password).type(password)
this.getElement(this.selectors.submitBtn).click()
}
}
- Write Tests
// cypress/e2e/ui/login.cy.ts
import LoginPage from '../../pageObjects/pages/loginPage'
describe('Login Tests', () => {
const loginPage = new LoginPage()
beforeEach(() => {
loginPage.visit('/login')
})
it('should login successfully', () => {
loginPage.login('testuser', 'password')
// assertions
})
})
Our framework supports comprehensive API testing across multiple categories:
- Unit Tests
describe('[Unit] User API Operations', () => {
it('[Unit] should retrieve user with valid data structure', () => {
cy.apiRequest('GET', '/users/1').then((response) => {
expect(response.status).to.eq(200)
expect(response.body.data).to.have.all.keys('id', 'email', 'first_name', 'last_name', 'avatar')
})
})
})
- Integration Tests
describe('[Integration] User Management Workflow', () => {
it('[Integration] should perform complete user CRUD operations', () => {
cy.apiRequest('POST', '/users', {
body: { name: 'Test User', job: 'QA Engineer' }
}).then((response) => {
expect(response.status).to.eq(201)
})
})
})
- Performance Tests
describe('[Performance] API Response Times', () => {
it('[Performance] should meet response time SLA', () => {
cy.apiRequest('GET', '/users').then((response) => {
expect(response.duration).to.be.lessThan(1000)
})
})
})
- Security Tests
describe('[Security] API Authentication', () => {
it('[Security] should enforce authentication', () => {
cy.apiRequest('GET', '/protected', {
headers: { 'Authorization': 'Bearer invalid_token' }
}).then((response) => {
expect(response.status).to.eq(401)
})
})
})
- Validation Tests
describe('[Validation] API Input Validation', () => {
it('[Validation] should enforce required fields', () => {
cy.apiRequest('POST', '/register', {
body: {}
}).then((response) => {
expect(response.status).to.eq(400)
})
})
})
- Interoperability Tests
describe('[Interop] API Compatibility', () => {
it('[Interop] should support multiple formats', () => {
cy.apiRequest('GET', '/users', {
headers: { 'Accept': 'application/json' }
}).then((response) => {
expect(response.headers['content-type']).to.include('application/json')
})
})
})
- Mock Tests
describe('[Mock] API Response Mocking', () => {
it('[Mock] should handle mocked responses', () => {
cy.intercept('GET', '/users', {
fixture: 'users.json'
}).as('getUsers')
cy.apiRequest('GET', '/users').then((response) => {
expect(response.status).to.eq(200)
cy.wait('@getUsers')
})
})
})
cypress/e2e/api/
├── unit-tests/ # Basic API operations
├── integration-tests/ # End-to-end workflows
├── performance-tests/ # Response times & load
├── security-tests/ # Auth & security checks
├── validation-tests/ # Input validation
├── mock-tests/ # Response mocking & stubbing
└── interop-tests/ # Compatibility tests
Our framework provides built-in commands for API testing:
// Make API requests with default configuration
cy.apiRequest(method, path, options)
// Example usage
cy.apiRequest('POST', '/users', {
body: { name: 'Test User' },
headers: { 'Authorization': 'Bearer token' }
})
-
Test Structure
- Use descriptive category prefixes: [Unit], [Integration], etc.
- Group related tests in appropriate folders
- Follow the single responsibility principle
-
Assertions
- Verify status codes and response structure
- Check response times for performance
- Validate security headers and tokens
- Test edge cases and error conditions
-
Data Management
- Use fixtures for test data
- Clean up test data after tests
- Handle environment-specific configurations
-
Selectors
- Use data-testid attributes:
[data-testid="login-button"]
- Store selectors in page objects.
- Use meaningful selector names.
- Use data-testid attributes:
-
Test Organization
cypress/
├── e2e/
│ ├── api/ # API Tests
│ │ ├── users/
│ │ └── auth/
│ └── ui/ # UI Tests
│ ├── login/
│ └── dashboard/
├── pageObjects/
│ ├── components/ # Reusable components
│ └── pages/ # Page specific objects
└── fixtures/ # Test data
- Custom Commands
- Create reusable commands for common operations
- Use TypeScript for better type checking
- Document command parameters
// cypress.config.js
module.exports = {
env: {
apiUrl: 'https://api.dev.example.com',
userRole: 'admin',
featureFlags: {
newUI: true
}
}
}
- GitHub Actions (pre-configured)
npm run test:ci
- Jenkins (sample configuration)
pipeline {
agent any
stages {
stage('Test') {
steps {
sh 'npm ci'
sh 'npm run test:ci'
}
}
}
}
This framework uses Mochawesome for comprehensive HTML reporting. Get detailed insights with screenshots, videos, and test execution metrics.
- Available Report Commands
npm run report:clean # Clean previous reports
npm run report:merge # Merge multiple report JSONs
npm run report:generate # Generate HTML from JSON
npm run test:report # Full test execution with reports
-
Report Features
- Interactive HTML dashboard
- Test execution timeline
- Suite and test-level statistics
- Failure screenshots embedded in report
- Test execution videos
- Performance metrics
- Filter and search capabilities
- Responsive design for mobile viewing
-
Report Structure
cypress/reports/
├── html/ # HTML reports
│ ├── assets/ # Screenshots, videos
│ ├── report.html # Main report
│ └── report.json # Combined results
└── json/ # Individual test JSONs
- Reporter Configuration
Add these options to
cypress.config.js
:
module.exports = defineConfig({
reporter: 'cypress-mochawesome-reporter',
reporterOptions: {
charts: true, // Enable charts
reportPageTitle: 'Test Report', // Custom title
embeddedScreenshots: true, // Inline screenshots
inlineAssets: true, // Inline assets
saveAllAttempts: false, // Save only failures
reportDir: 'cypress/reports/html',
overwrite: false,
html: true,
json: true
}
})
-
Viewing Reports
- Open
cypress/reports/html/report.html
in any browser - Reports are self-contained and can be shared
- Support offline viewing
- Can be hosted on any static server
- Open
-
CI/CD Integration
- name: Generate Test Report
if: always()
run: npm run test:report
- name: Upload Test Report
if: always()
uses: actions/upload-artifact@v4
with:
name: test-report
path: cypress/reports/html
The framework includes visual regression testing capabilities:
// Visual regression test example
describe('Visual Tests', () => {
it('should match homepage screenshot', () => {
cy.visit('/')
cy.matchImageSnapshot('homepage')
})
})
Configuration in cypress.config.js:
- Visual regression path:
cypress/snapshots
- Visual threshold: 0.1
Run visual tests:
npm run test:visual
Built-in accessibility testing with cypress-axe:
describe('Accessibility Tests', () => {
it('should pass accessibility checks', () => {
cy.visit('/')
cy.injectAxe()
cy.checkA11y()
})
})
Run accessibility tests:
npm run test:a11y
Enhanced network mocking capabilities:
// Mock REST API
cy.mockNetworkResponse('GET', '/api/users', { users: [] })
// Mock GraphQL
cy.mockGraphQL('GetUsers', { data: { users: [] } })
Factory pattern for test data generation:
import UserFactory from '../support/factories/userFactory'
describe('User Tests', () => {
it('should create user', () => {
const user = UserFactory.generate()
// Use generated user data in tests
})
it('should create multiple users', () => {
const users = UserFactory.generateMany(3)
// Use generated users data in tests
})
})
New testing capabilities are provided by:
{
"cypress-image-snapshot": "^4.0.1",
"cypress-axe": "^1.5.0",
"@testing-library/cypress": "^10.0.1",
"cypress-real-events": "^1.11.0",
"@faker-js/faker": "^8.0.0"
}
-
Time Travel
- Use Cypress Time Travel feature
- Check screenshots in
cypress/screenshots
- Review videos in
cypress/videos
-
Logging
- Use
cy.log()
for debug information - Enable Chrome DevTools in interactive mode
- Use
We welcome contributions that help improve this Cypress Page Object Model framework! Here's how you can contribute:
-
Page Objects
- New page object implementations
- Improvements to existing page objects
- Utility functions for common actions
-
Test Examples
- UI test examples
- API test examples
- Integration test patterns
-
Documentation
- Usage examples
- Best practices
- Troubleshooting guides
-
Fork and Clone
# Fork this repository on GitHub git clone https://github.com/YOUR_USERNAME/Cypress-POM-Ready-To-Use.git cd Cypress-POM-Ready-To-Use npm install
-
Create a Branch
git checkout -b feature/your-feature-name
-
Make Changes
- Follow the existing code structure
- Add tests for new features
- Update documentation as needed
-
Contribution Guidelines
- Use TypeScript for new files
- Follow the page object pattern
- Add JSDoc comments for methods
- Include test cases for new features
/** * Example of a well-documented page object */ class ExamplePage extends BasePage { private selectors = { submitButton: '[data-testid="submit"]' } /** * Submits the form with given data * @param {string} data - The data to submit * @returns {Cypress.Chainable} */ submitForm(data: string) { return this.getElement(this.selectors.submitButton).click() } }
-
Run Tests
npm run test # Run all tests npm run lint # Check code style npm run build # Ensure build passes
-
Submit PR
- Create a Pull Request against the
main
branch - Provide a clear description of changes
- Reference any related issues
- Wait for review and address feedback
- Create a Pull Request against the
cypress/
├── e2e/ # Add tests here
│ ├── api/ # API test examples
│ └── ui/ # UI test examples
├── pageObjects/ # Add page objects here
│ ├── components/ # Reusable components
│ └── pages/ # Page implementations
└── support/ # Add custom commands here
└── commands/ # Custom command implementations
-
Naming Conventions
- Use PascalCase for page objects:
LoginPage.ts
- Use camelCase for methods:
submitForm()
- Use descriptive test names:
'should successfully submit form'
- Use PascalCase for page objects:
-
File Organization
- One page object per file
- Group related tests in describe blocks
- Keep selectors in a separate object
-
Testing Standards
- Write atomic tests
- Use meaningful assertions
- Avoid hard-coded waits
- Check existing issues
- Join our [Discord community]
- Read our [documentation]
- Documentation: See
docs/
folder - Issues: GitHub Issues
- Community: [Join our Discord]
-
Error with
cypress.config.js
const { defineConfig } = require('cypress')
Solution: Ensure proper configuration setup:
- Install browserify preprocessor:
npm install @cypress/browserify-preprocessor --save-dev
- Use the complete configuration:
const { defineConfig } = require("cypress"); const createBundler = require("@cypress/browserify-preprocessor"); module.exports = defineConfig({ viewportWidth: 1920, viewportHeight: 1080, watchForFileChanges: false, // ... other configurations });
- Install browserify preprocessor:
-
TypeScript Support
- Ensure these dependencies are installed:
{ "devDependencies": { "@cypress/browserify-preprocessor": "^3.0.2", "@types/node": "^20.11.16", "typescript": "^5.3.3" } }
-
Running Tests
- For UI tests:
npm run test:ui
- For API tests:
npm run test:api
- For parallel execution:
npm run test:parallel
- For UI tests:
-
Environment Configuration
- Default environments are:
- API URL:
https://reqres.in
- React App URL:
https://react-redux.realworld.io
- Example URL:
https://example.cypress.io
- API URL:
- Default environments are:
-
Page Object Model
- Keep selectors in page objects
- Use data-testid attributes
- Implement base page for common functions
-
Test Organization
- API tests in
cypress/e2e/api/
- UI tests in
cypress/e2e/ui/
- Integration tests in
cypress/e2e/integration/
- API tests in
-
Performance
- Use
cy.session()
for login state - Enable retries in CI mode
- Implement proper timeouts
- Use
MIT License - feel free to use in your projects
- Author: Padmaraj Nidagundi
- Email: [email protected]
- LinkedIn: https://www.linkedin.com/in/padmarajn/
- NpmJs: https://www.npmjs.com/package/cypress-page-object-model
- GitHub: https://github.com/padmarajnidagundi/Cypress-POM-Ready-To-Use