Skip to content

Commit 2b92bef

Browse files
feat: setup for e2e tests with cypress
1 parent d79192e commit 2b92bef

File tree

18 files changed

+2707
-37
lines changed

18 files changed

+2707
-37
lines changed

client/.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,8 @@ dist-ssr
2222
*.njsproj
2323
*.sln
2424
*.sw?
25+
26+
# Cypress
27+
cypress.env.json
28+
cypress/videos/
29+
cypress/screenshots/

client/cypress.config.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { defineConfig } from "cypress";
2+
3+
export default defineConfig({
4+
e2e: {
5+
baseUrl: "http://localhost:3000",
6+
supportFile: "cypress/support/e2e.ts",
7+
specPattern: "cypress/e2e/**/*.cy.{js,jsx,ts,tsx}",
8+
viewportWidth: 1280,
9+
viewportHeight: 720,
10+
video: false,
11+
screenshotOnRunFailure: true,
12+
defaultCommandTimeout: 10000,
13+
requestTimeout: 10000,
14+
responseTimeout: 10000,
15+
setupNodeEvents(on, config) {
16+
// implement node event listeners here
17+
},
18+
},
19+
component: {
20+
devServer: {
21+
framework: "react",
22+
bundler: "vite",
23+
},
24+
supportFile: "cypress/support/component.ts",
25+
specPattern: "cypress/component/**/*.cy.{js,jsx,ts,tsx}",
26+
indexHtmlFile: "cypress/support/component-index.html",
27+
},
28+
env: {
29+
// Add any environment variables here
30+
apiUrl: "http://localhost:8080", // Adjust based on your backend URL
31+
},
32+
});

client/cypress/README.md

Lines changed: 305 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,305 @@
1+
# Cypress Testing Setup
2+
3+
This directory contains the end-to-end (E2E) and component tests for the Meet@Mensa React application using Cypress.
4+
5+
## Structure
6+
7+
```
8+
cypress/
9+
├── e2e/ # End-to-end tests
10+
│ ├── authentication.cy.ts
11+
│ ├── match-requests.cy.ts
12+
│ └── navigation.cy.ts
13+
├── component/ # Component tests
14+
│ └── MatchRequestCard.cy.tsx
15+
├── support/ # Support files
16+
│ ├── commands.ts # Custom Cypress commands
17+
│ ├── e2e.ts # E2E test configuration
18+
│ ├── component.ts # Component test configuration
19+
│ ├── component-index.html
20+
│ └── index.d.ts # TypeScript declarations
21+
├── fixtures/ # Test data (if needed)
22+
└── downloads/ # Downloaded files (if any)
23+
```
24+
25+
## Getting Started
26+
27+
### Prerequisites
28+
29+
1. Make sure your development server is running on `http://localhost:3000`
30+
2. Ensure your backend API is running on `http://localhost:8080`
31+
3. Set up test credentials in `cypress.env.json`
32+
33+
### Running Tests
34+
35+
#### E2E Tests
36+
37+
```bash
38+
# Open Cypress Test Runner (interactive mode)
39+
npm run cypress:open
40+
41+
# Run E2E tests in headless mode
42+
npm run cypress:run:e2e
43+
44+
# Run E2E tests with dev server (recommended)
45+
npm run test:e2e
46+
47+
# Run E2E tests with dev server in interactive mode
48+
npm run test:e2e:open
49+
```
50+
51+
#### Component Tests
52+
53+
```bash
54+
# Run component tests in headless mode
55+
npm run cypress:run:component
56+
57+
# Open Cypress Test Runner for component tests
58+
npm run cypress:open --component
59+
```
60+
61+
#### All Tests
62+
63+
```bash
64+
# Run all Cypress tests
65+
npm run cypress:run
66+
```
67+
68+
## Configuration
69+
70+
### Environment Variables
71+
72+
Create a `cypress.env.json` file in the client directory with your test credentials:
73+
74+
```json
75+
{
76+
"TEST_USER_EMAIL": "[email protected]",
77+
"TEST_USER_PASSWORD": "your-test-password",
78+
"API_BASE_URL": "http://localhost:8080",
79+
"AUTH0_DOMAIN": "your-auth0-domain",
80+
"AUTH0_CLIENT_ID": "your-auth0-client-id"
81+
}
82+
```
83+
84+
### Test Data
85+
86+
For consistent test data, you can create fixtures in `cypress/fixtures/`:
87+
88+
```json
89+
// cypress/fixtures/match-requests.json
90+
{
91+
"validMatchRequest": {
92+
"title": "Test Match Request",
93+
"description": "This is a test match request",
94+
"location": "Mensa Arcisstraße",
95+
"date": "2024-12-25",
96+
"time": "12:00",
97+
"maxParticipants": 4
98+
}
99+
}
100+
```
101+
102+
## Custom Commands
103+
104+
The following custom commands are available in your tests:
105+
106+
### Authentication
107+
108+
- `cy.login(email, password)` - Login with Auth0
109+
- `cy.logout()` - Logout from the application
110+
- `cy.isAuthenticated()` - Check if user is authenticated
111+
112+
### Match Requests
113+
114+
- `cy.createMatchRequest(data)` - Create a new match request
115+
- `cy.joinMatchRequest(matchId)` - Join an existing match request
116+
117+
### Navigation
118+
119+
- `cy.navigateTo(page)` - Navigate to a specific page
120+
121+
### Forms
122+
123+
- `cy.fillForm(formData)` - Fill form fields with data
124+
- `cy.selectFromDropdown(dropdownId, option)` - Select from dropdown
125+
126+
### Utilities
127+
128+
- `cy.waitForApi(method, url)` - Wait for API requests to complete
129+
- `cy.checkToast(message, type)` - Check for toast notifications
130+
- `cy.uploadFile(inputId, filePath)` - Upload a file
131+
132+
## Writing Tests
133+
134+
### E2E Test Example
135+
136+
```typescript
137+
describe('Match Requests', () => {
138+
beforeEach(() => {
139+
cy.login(Cypress.env('TEST_USER_EMAIL'), Cypress.env('TEST_USER_PASSWORD'));
140+
cy.visit('/dashboard');
141+
});
142+
143+
it('should create a new match request', () => {
144+
const testRequest = {
145+
title: 'Test Match Request',
146+
description: 'This is a test match request',
147+
location: 'Mensa Arcisstraße',
148+
date: '2024-12-25',
149+
time: '12:00',
150+
maxParticipants: 4,
151+
};
152+
153+
cy.get('[data-testid="create-match-button"]').click();
154+
cy.fillForm({
155+
'match-title': testRequest.title,
156+
'match-description': testRequest.description,
157+
'match-location': testRequest.location,
158+
'match-date': testRequest.date,
159+
'match-time': testRequest.time,
160+
'match-max-participants': testRequest.maxParticipants.toString(),
161+
});
162+
163+
cy.get('[data-testid="submit-match-request"]').click();
164+
cy.checkToast('Match request created successfully');
165+
});
166+
});
167+
```
168+
169+
### Component Test Example
170+
171+
```typescript
172+
import React from 'react'
173+
import { MatchRequestCard } from '../../src/components/MatchRequestCard'
174+
175+
describe('MatchRequestCard.cy.tsx', () => {
176+
const mockMatchRequest = {
177+
id: '1',
178+
title: 'Test Match Request',
179+
description: 'This is a test match request',
180+
location: 'Mensa Arcisstraße',
181+
date: '2024-12-25',
182+
time: '12:00',
183+
maxParticipants: 4,
184+
currentParticipants: 2,
185+
creator: { id: 'user1', name: 'John Doe', email: '[email protected]' },
186+
participants: [
187+
{ id: 'user1', name: 'John Doe' },
188+
{ id: 'user2', name: 'Jane Smith' }
189+
],
190+
createdAt: '2024-12-20T10:00:00Z'
191+
}
192+
193+
it('should render match request information correctly', () => {
194+
cy.mount(<MatchRequestCard matchRequest={mockMatchRequest} onJoin={() => {}} onDelete={() => {}} />)
195+
196+
cy.get('[data-testid="match-title"]').should('contain', mockMatchRequest.title)
197+
cy.get('[data-testid="match-description"]').should('contain', mockMatchRequest.description)
198+
});
199+
});
200+
```
201+
202+
## Best Practices
203+
204+
### Data Attributes
205+
206+
Use `data-testid` attributes for reliable element selection:
207+
208+
```tsx
209+
<button data-testid="create-match-button">Create Match</button>
210+
```
211+
212+
### Test Isolation
213+
214+
- Clear localStorage and cookies before each test
215+
- Use unique test data for each test
216+
- Avoid dependencies between tests
217+
218+
### API Mocking
219+
220+
For faster tests, you can mock API responses:
221+
222+
```typescript
223+
cy.intercept('GET', '/api/match-requests', {
224+
statusCode: 200,
225+
body: mockMatchRequests,
226+
}).as('getMatchRequests');
227+
```
228+
229+
### Error Handling
230+
231+
Handle uncaught exceptions gracefully:
232+
233+
```typescript
234+
Cypress.on('uncaught:exception', (err, runnable) => {
235+
console.log('Uncaught exception:', err.message);
236+
return false;
237+
});
238+
```
239+
240+
## CI/CD Integration
241+
242+
### GitHub Actions Example
243+
244+
```yaml
245+
name: E2E Tests
246+
on: [push, pull_request]
247+
jobs:
248+
cypress-run:
249+
runs-on: ubuntu-latest
250+
steps:
251+
- uses: actions/checkout@v3
252+
- uses: actions/setup-node@v3
253+
with:
254+
node-version: '18'
255+
- run: npm ci
256+
- run: npm run test:e2e
257+
```
258+
259+
### Environment Variables in CI
260+
261+
Set these environment variables in your CI/CD platform:
262+
263+
- `TEST_USER_EMAIL`
264+
- `TEST_USER_PASSWORD`
265+
- `API_BASE_URL`
266+
- `AUTH0_DOMAIN`
267+
- `AUTH0_CLIENT_ID`
268+
269+
## Troubleshooting
270+
271+
### Common Issues
272+
273+
1. **Tests failing due to Auth0 redirects**
274+
275+
- Ensure test credentials are correct
276+
- Check Auth0 domain configuration
277+
278+
2. **Element not found errors**
279+
280+
- Verify `data-testid` attributes are present
281+
- Check if elements are conditionally rendered
282+
283+
3. **API timeout errors**
284+
285+
- Ensure backend server is running
286+
- Check API base URL configuration
287+
288+
4. **Component test failures**
289+
- Verify component imports are correct
290+
- Check for missing dependencies
291+
292+
### Debug Mode
293+
294+
Run tests in debug mode for more detailed output:
295+
296+
```bash
297+
DEBUG=cypress:* npm run cypress:run
298+
```
299+
300+
## Resources
301+
302+
- [Cypress Documentation](https://docs.cypress.io/)
303+
- [Cypress Best Practices](https://docs.cypress.io/guides/references/best-practices)
304+
- [Cypress Component Testing](https://docs.cypress.io/guides/component-testing/introduction)
305+
- [Cypress Custom Commands](https://docs.cypress.io/api/cypress-api/custom-commands)

0 commit comments

Comments
 (0)