Skip to content

Add test

Add test #63

Workflow file for this run

name: E2E Tests with Cypress
on:
push:
branches: [ "feature/**", "develop/**", "release/**" ]
paths:
- 'frontend/**'
- 'backend/**'
- 'docker-compose.test.yml'
- '.github/workflows/e2e-tests.yml'
pull_request:
branches: [ main, develop, feature/**, release/** ]
types: [ opened, synchronize, reopened ]
workflow_dispatch: # Manual trigger for testing
env:
DOCKER_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
jobs:
cypress-e2e:
runs-on: ubuntu-latest
name: Run Cypress E2E Tests
steps:
# 1. Checkout code
- name: Checkout code
uses: actions/checkout@v4
# 2. Set up Node.js for Cypress
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: 'frontend/package-lock.json'
# 3. Install Cypress dependencies
- name: Install Cypress dependencies
working-directory: ./frontend
run: |
npm ci
npm install -D cypress-mochawesome-reporter mochawesome mochawesome-merge mochawesome-report-generator
# 4. Log in to Docker Hub (for pulling backend image)
- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ env.DOCKER_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
# 5. Pull Backend Docker Image
- name: Pull Backend Docker Image
run: |
echo "Pulling backend image from Docker Hub..."
docker pull ${{ env.DOCKER_USERNAME }}/apartment-backend:latest
echo "✅ Backend image pulled successfully"
# 6. Tag backend image for dev compose
- name: Tag Backend Image for Dev Compose
run: |
echo "Tagging backend image for development..."
docker tag ${{ env.DOCKER_USERNAME }}/apartment-backend:latest apartment-backend:dev
echo "✅ Backend image tagged"
# 7. Create test environment file
- name: Create .env file for testing
run: |
cat > .env << EOF
DOCKER_USERNAME=${{ env.DOCKER_USERNAME }}
MYSQL_ROOT_PASSWORD=dev_root_password
MYSQL_DATABASE=apartment_db
MYSQL_USER=apartment
MYSQL_PASSWORD=dev_password
JWT_SECRET_DEV=dGVzdC1zZWNyZXQta2V5LWZvci1qd3QtdG9rZW4tZ2VuZXJhdGlvbi1pbi10ZXN0LWVudmlyb25tZW50
JWT_EXPIRATION=86400000
CORS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:80,http://localhost:8080
ADMIN_USERNAME=apartment_admin
ADMIN_PASSWORD=Admin@2024!Secure
ADMIN_EMAIL=admin@apartment.local
VILLAGER_USERNAME=villager
VILLAGER_PASSWORD=villager123
VILLAGER_EMAIL=villager@apartment.local
TEST_USERNAME=testuser
TEST_PASSWORD=test123
TEST_EMAIL=testuser@apartment.local
EOF
# 8. Start Application Stack with Docker Compose (Dev Mode)
- name: Start Application Stack
run: |
echo "Starting services with Docker Compose (Dev Mode)..."
docker compose -f docker-compose.dev.yml up --build -d
echo "Waiting for MySQL to be ready..."
timeout 120s bash -c 'until docker compose -f docker-compose.dev.yml exec -T db mysqladmin ping -h localhost --silent; do echo "Waiting for MySQL..."; sleep 5; done'
echo "✅ MySQL is ready"
echo "Waiting for Backend to be ready..."
timeout 120s bash -c 'until curl -f http://localhost:8080/health 2>/dev/null; do echo "Waiting for Backend..."; sleep 5; done'
echo "✅ Backend is ready"
echo "Waiting for Frontend to be ready..."
timeout 90s bash -c 'until curl -f http://localhost:5173 2>/dev/null; do echo "Waiting for Frontend..."; sleep 5; done'
echo "✅ Frontend is ready"
# Additional wait for Vite dev server to fully initialize
echo "Waiting 15 seconds for Vite dev server to fully initialize..."
sleep 15
echo "🎉 All services are up and running!"
# 9. Display running containers for debugging
- name: Show running containers
if: always()
run: docker compose -f docker-compose.dev.yml ps
# 10. Run Cypress E2E Tests
- name: Run Cypress E2E Tests
working-directory: ./frontend
run: |
echo "🧪 Running Cypress E2E Tests..."
npm run cypress:ci
echo "✅ Cypress tests completed"
# 11. Generate combined test report
- name: Generate Combined Report
if: always()
working-directory: ./frontend
run: |
if [ -f cypress/results/index.json ]; then
echo "📊 Generating combined test report..."
cp cypress/results/index.json combined-report.json
echo "✅ Combined report generated"
else
echo "⚠️ No test results found, creating empty report"
echo '{"stats":{"tests":0,"passes":0,"failures":0,"pending":0,"duration":0}}' > combined-report.json
fi
# 12. Upload test videos
- name: Upload Test Videos
if: always()
uses: actions/upload-artifact@v4
with:
name: cypress-videos
path: frontend/cypress/videos/
retention-days: 7
if-no-files-found: ignore
# 13. Upload test screenshots (for failed tests)
- name: Upload Test Screenshots
if: failure()
uses: actions/upload-artifact@v4
with:
name: cypress-screenshots
path: frontend/cypress/screenshots/
retention-days: 7
if-no-files-found: ignore
# 14. Upload HTML test report
- name: Upload HTML Test Report
if: always()
uses: actions/upload-artifact@v4
with:
name: cypress-html-report
path: frontend/cypress/results/
retention-days: 30
if-no-files-found: warn
# 15. Upload JSON test results
- name: Upload JSON Test Results
if: always()
uses: actions/upload-artifact@v4
with:
name: cypress-json-results
path: frontend/combined-report.json
retention-days: 30
if-no-files-found: warn
# 16. Comment test results on PR
- name: Comment Test Results on PR
if: github.event_name == 'pull_request' && always()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
let reportData;
try {
const report = fs.readFileSync('frontend/combined-report.json', 'utf8');
reportData = JSON.parse(report);
} catch (error) {
console.log('Could not read test results, posting generic comment');
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '⚠️ Cypress E2E tests encountered an error. Please check the workflow logs.'
});
return;
}
const stats = reportData.stats;
const passed = stats.passes;
const failed = stats.failures;
const pending = stats.pending;
const total = stats.tests;
const duration = (stats.duration / 1000).toFixed(2);
const passRate = ((passed / total) * 100).toFixed(1);
const emoji = failed === 0 ? '✅' : '❌';
const status = failed === 0 ? '**All tests passed!**' : '**Some tests failed!**';
const body = `
## ${emoji} Cypress E2E Test Results
${status}
| Metric | Count |
|--------|-------|
| 📊 Total Tests | ${total} |
| ✅ Passed | ${passed} |
| ❌ Failed | ${failed} |
| ⏭️ Skipped | ${pending} |
| ⏱️ Duration | ${duration}s |
| 📈 Pass Rate | ${passRate}% |
${failed > 0 ? '### ⚠️ Failed Tests\n\nPlease review the test artifacts for details:\n- Videos: Check workflow artifacts\n- Screenshots: Available for failed tests\n- HTML Report: Full detailed report in artifacts\n' : '### 🎉 Excellent!\n\nAll E2E tests passed successfully. The application is working as expected.\n'}
---
*View full report in [workflow artifacts](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }})*
`;
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
});
# 17. Display test summary
- name: E2E Test Summary
if: always()
run: |
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "🧪 Cypress E2E Test Execution Complete"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""
if [ -f frontend/combined-report.json ]; then
echo "📊 Test Results:"
cat frontend/combined-report.json | jq -r '.stats | "Total: \(.tests)\nPassed: \(.passes)\nFailed: \(.failures)\nSkipped: \(.pending)\nDuration: \(.duration)ms"'
else
echo "⚠️ Test results not available"
fi
echo ""
echo "📦 Artifacts uploaded:"
echo " - Videos (all tests)"
echo " - Screenshots (failures only)"
echo " - HTML Report"
echo " - JSON Results"
echo ""
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
# 18. Show container logs on failure
- name: Show Container Logs on Failure
if: failure()
run: |
echo "📋 Backend Logs:"
docker compose -f docker-compose.dev.yml logs backend --tail=100
echo ""
echo "📋 Frontend Logs:"
docker compose -f docker-compose.dev.yml logs frontend --tail=100
echo ""
echo "📋 MySQL Logs:"
docker compose -f docker-compose.dev.yml logs db --tail=50
# 19. Cleanup - Teardown environment
- name: Teardown Environment
if: always()
run: |
echo "🧹 Cleaning up test environment..."
docker compose -f docker-compose.dev.yml down -v
echo "✅ Cleanup complete"