|
|
|
@@ -0,0 +1,226 @@
|
|
|
|
|
# E2E Testing Infrastructure
|
|
|
|
|
|
|
|
|
|
This directory contains end-to-end testing infrastructure for the Aeroflot Flights web application, including Cypress tests and visual regression testing with BackstopJS.
|
|
|
|
|
|
|
|
|
|
## Directory Structure
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
e2e/
|
|
|
|
|
├── cypress/
|
|
|
|
|
│ ├── integration/ # E2E test files organized by feature
|
|
|
|
|
│ │ ├── accessibility/ # Accessibility tests
|
|
|
|
|
│ │ ├── components/ # Component-level tests
|
|
|
|
|
│ │ ├── error-handling/ # Error handling tests
|
|
|
|
|
│ │ ├── flight-details/ # Flight details page tests
|
|
|
|
|
│ │ ├── flights-map/ # Flight map tests
|
|
|
|
|
│ │ ├── i18n/ # Internationalization tests
|
|
|
|
|
│ │ ├── integration/ # Cross-feature integration tests
|
|
|
|
|
│ │ ├── navigation/ # Navigation flow tests
|
|
|
|
|
│ │ ├── online-board/ # Online board tests
|
|
|
|
|
│ │ ├── performance/ # Performance tests
|
|
|
|
|
│ │ ├── responsive/ # Responsive design tests
|
|
|
|
|
│ │ ├── schedule/ # Schedule tests
|
|
|
|
|
│ │ └── search-history/ # Search history tests
|
|
|
|
|
│ └── support/
|
|
|
|
|
│ ├── index.ts # Global test setup and hooks
|
|
|
|
|
│ └── commands.ts # Custom Cypress commands
|
|
|
|
|
├── backstop/ # Visual regression testing config
|
|
|
|
|
├── cypress.config.ts # Cypress configuration
|
|
|
|
|
├── package.json # E2E dependencies
|
|
|
|
|
├── tsconfig.json # TypeScript configuration
|
|
|
|
|
└── scripts/ # Test utility scripts
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Test File Naming
|
|
|
|
|
|
|
|
|
|
All test files must follow the naming pattern: `*.spec.ts`
|
|
|
|
|
|
|
|
|
|
Example test files:
|
|
|
|
|
- `cypress/integration/search-history/search-history-filtering.spec.ts`
|
|
|
|
|
- `cypress/integration/flight-details/flight-details-display.spec.ts`
|
|
|
|
|
|
|
|
|
|
## Setup
|
|
|
|
|
|
|
|
|
|
### Install Dependencies
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npm install
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Environment Configuration
|
|
|
|
|
|
|
|
|
|
The test suite uses the following configuration from `cypress.config.ts`:
|
|
|
|
|
- **Base URL**: `http://localhost:3000` (React development server)
|
|
|
|
|
- **Viewport**: 1440x900 (desktop)
|
|
|
|
|
- **Timeouts**: 10 seconds for requests, responses, and commands
|
|
|
|
|
- **Screenshots**: Enabled on test failure
|
|
|
|
|
- **Videos**: Disabled (can be enabled in cypress.config.ts if needed)
|
|
|
|
|
|
|
|
|
|
## Running Tests
|
|
|
|
|
|
|
|
|
|
### Open Cypress Test Runner (Interactive Mode)
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npm run cypress:open
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This opens the Cypress test runner UI where you can:
|
|
|
|
|
- View and run individual tests
|
|
|
|
|
- Debug with browser DevTools
|
|
|
|
|
- See real-time test execution
|
|
|
|
|
- Inspect elements and network calls
|
|
|
|
|
|
|
|
|
|
### Run Tests Headlessly
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npm run cypress:run
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This runs all tests in headless mode and generates a test report.
|
|
|
|
|
|
|
|
|
|
### Run Specific Test Suite
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npx cypress run --spec "cypress/integration/search-history/*.spec.ts"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Run Tests with Specific Browser
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npx cypress run --browser chrome
|
|
|
|
|
npx cypress run --browser firefox
|
|
|
|
|
npx cypress run --browser edge
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Custom Commands
|
|
|
|
|
|
|
|
|
|
### getByTestId(id: string, timeout?: number)
|
|
|
|
|
|
|
|
|
|
Select elements by test ID attribute for more reliable element selection.
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
cy.getByTestId('search-button').click()
|
|
|
|
|
cy.getByTestId('flight-results', 5000).should('exist')
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### forbidGeolocation()
|
|
|
|
|
|
|
|
|
|
Mock the geolocation API to return an error, useful for testing geolocation-denied scenarios.
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
cy.forbidGeolocation()
|
|
|
|
|
// Now geolocation calls will fail
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Test Hooks
|
|
|
|
|
|
|
|
|
|
### afterEach Hook
|
|
|
|
|
|
|
|
|
|
Automatically clears browser localStorage after each test to ensure test isolation and prevent state leakage between tests.
|
|
|
|
|
|
|
|
|
|
```typescript
|
|
|
|
|
// Automatically runs after every test
|
|
|
|
|
afterEach(() => {
|
|
|
|
|
cy.window().then(win => {
|
|
|
|
|
win.localStorage.clear()
|
|
|
|
|
})
|
|
|
|
|
})
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Visual Regression Testing (BackstopJS)
|
|
|
|
|
|
|
|
|
|
The e2e folder includes BackstopJS for visual regression testing.
|
|
|
|
|
|
|
|
|
|
### Create Reference Screenshots
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npm run backstop:reference
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This creates baseline screenshots using the Angular version (`backstop/backstop-angular.json`).
|
|
|
|
|
|
|
|
|
|
### Run Visual Tests
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npm run backstop:test
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
This compares current React version screenshots against the Angular baseline (`backstop/backstop-react.json`).
|
|
|
|
|
|
|
|
|
|
## Test Best Practices
|
|
|
|
|
|
|
|
|
|
1. **Use data-testid attributes**: Always add `data-testid` to elements you want to test
|
|
|
|
|
```html
|
|
|
|
|
<button data-testid="search-button">Search</button>
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
2. **Avoid brittle selectors**: Don't rely on class names or IDs that change frequently
|
|
|
|
|
|
|
|
|
|
3. **Use meaningful test names**: Describe what the test verifies
|
|
|
|
|
```typescript
|
|
|
|
|
it('should filter search results when filter is applied', () => {
|
|
|
|
|
// test code
|
|
|
|
|
})
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
4. **Test user workflows**: Write tests that simulate real user interactions
|
|
|
|
|
```typescript
|
|
|
|
|
cy.getByTestId('destination-input').type('Moscow')
|
|
|
|
|
cy.getByTestId('search-button').click()
|
|
|
|
|
cy.getByTestId('flight-results').should('be.visible')
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
5. **Keep tests independent**: Each test should be able to run in any order
|
|
|
|
|
- Use `afterEach` to clean up state (already configured)
|
|
|
|
|
- Don't depend on data from other tests
|
|
|
|
|
|
|
|
|
|
6. **Handle async operations**: Use proper timeouts and waits
|
|
|
|
|
```typescript
|
|
|
|
|
cy.getByTestId('loading-spinner', 10000).should('not.exist')
|
|
|
|
|
cy.getByTestId('results-list').should('have.length.greaterThan', 0)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
7. **Mock API responses when appropriate**: Use Cypress intercept for predictable tests
|
|
|
|
|
```typescript
|
|
|
|
|
cy.intercept('GET', '/api/flights/*', { fixture: 'flights.json' })
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Validation Script
|
|
|
|
|
|
|
|
|
|
Run the full validation suite (includes e2e tests):
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npm run validate
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Troubleshooting
|
|
|
|
|
|
|
|
|
|
### Tests timing out
|
|
|
|
|
- Increase timeout values in `cypress.config.ts`
|
|
|
|
|
- Check if the application is running on http://localhost:3000
|
|
|
|
|
- Verify network connectivity to backend API
|
|
|
|
|
|
|
|
|
|
### Element not found errors
|
|
|
|
|
- Ensure `data-testid` attributes exist in the React components
|
|
|
|
|
- Wait for elements to be visible: `cy.getByTestId('element').should('be.visible')`
|
|
|
|
|
- Check browser console for JavaScript errors
|
|
|
|
|
|
|
|
|
|
### localStorage not clearing between tests
|
|
|
|
|
- The `afterEach` hook should handle this automatically
|
|
|
|
|
- Verify the hook is not being overridden in individual test files
|
|
|
|
|
|
|
|
|
|
## CI/CD Integration
|
|
|
|
|
|
|
|
|
|
For CI/CD pipelines, use:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
npm run cypress:run # Headless test execution
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Ensure the React development server is running on port 3000 before executing tests.
|
|
|
|
|
|
|
|
|
|
## Additional Resources
|
|
|
|
|
|
|
|
|
|
- [Cypress Documentation](https://docs.cypress.io)
|
|
|
|
|
- [BackstopJS Documentation](https://garris.github.io/BackstopJS/)
|
|
|
|
|
- [Testing Best Practices](https://docs.cypress.io/guides/references/best-practices)
|