Comprehensive integration and E2E tests for Job Scanner application.
This testing project provides:
- Integration Tests: Test real API endpoints and file operations
- E2E Tests: Test complete user workflows with Playwright
- Real Server Testing: Tests run against actual running backend and frontend
- File Verification: Validates job_tracking.json and CSV updates
Servers must be running before tests:
-
Backend:
cd backend && python api.py- Should be accessible at http://localhost:5000
- Health check: http://localhost:5000/api/health
-
Frontend:
cd frontend && npm run dev- Should be accessible at http://localhost:5173
- Should display login page
cd testing
npm install
npx playwright installtesting/
├── integration/ # Integration tests
│ ├── job-status-api.test.ts # API endpoint tests
│ ├── file-persistence.test.ts # File I/O tests
│ ├── status-transitions.test.ts # Status transition tests
│ └── helpers/
│ ├── api-client.ts # API client for backend
│ ├── file-helpers.ts # File operation helpers
│ └── test-data.ts # Test data fixtures
├── e2e/ # E2E tests
│ ├── favorite-workflow.spec.ts # Favorite functionality
│ ├── apply-workflow.spec.ts # Apply functionality
│ ├── archive-workflow.spec.ts # Archive functionality
│ ├── status-transitions.spec.ts # Status transitions
│ └── fixtures/
│ ├── jobs.json # Test job data
│ └── auth.json # Test credentials
├── global-setup.ts # Pre-test setup
├── global-teardown.ts # Post-test cleanup
├── playwright.config.ts # Playwright configuration
└── package.json # Dependencies and scripts
# Run all integration tests
npm run test:integration
# Run specific integration test
npm run test:integration integration/job-status-api.test.tsWhat's tested:
- API endpoints (PUT /api/jobs/{job_key}/status)
- File updates (job_tracking.json)
- CSV exports (job_applications.csv)
- Status transitions (all ↔ favorite ↔ applied ↔ archive)
# Run all E2E tests (headless)
npm run test:e2e
# Run with UI (interactive)
npm run test:e2e:ui
# Run in headed mode (see browser)
npm run test:headed
# Run specific test file
npm run test:e2e e2e/favorite-workflow.spec.ts
# Debug mode
npm run test:e2e:debugWhat's tested:
- Complete user workflows
- Form interactions
- Status filtering
- Toast notifications
- Button state changes
# Run everything (integration + E2E)
npm run test:allAfter running E2E tests:
npm run reportThis opens the Playwright HTML report with:
- Test results (passed/failed)
- Screenshots on failure
- Videos on failure
- Trace viewer for debugging
- ✅ API Endpoints: All status update operations
- ✅ File Operations: job_tracking.json CRUD
- ✅ CSV Export: job_applications.csv updates
- ✅ Status Transitions: All valid transitions
- ✅ Favorite Workflow: Add, update, remove favorites
- ✅ Apply Workflow: Mark as applied, update details, return to opportunities
- ✅ Archive Workflow: Archive with reason, update reason
- ✅ Status Transitions: Complex multi-step workflows
- Username:
admin - Password:
admin123
Tests use these job keys:
google|senior backend engineeramazon|staff engineermicrosoft|principal engineer
Note: Test data is cleaned up after tests via global-teardown.ts
Create .env file (or copy from .env.example):
BACKEND_URL=http://localhost:5000
BACKEND_API_URL=http://localhost:5000/api
FRONTEND_URL=http://localhost:5173
TEST_USERNAME=admin
TEST_PASSWORD=admin123Edit playwright.config.ts to customize:
- Test timeout
- Number of retries
- Browser selection (chromium, firefox, webkit)
- Screenshot/video capture settings
Problem: Integration/E2E tests fail immediately
Solution:
cd backend
python api.py
# Should see: Running on http://localhost:5000Verify: http://localhost:5000/api/health
Problem: E2E tests fail with navigation errors
Solution:
cd frontend
npm run dev
# Should see: Local: http://localhost:5173Verify: Open http://localhost:5173 in browser
Problem: Tests hang or timeout
Diagnosis:
# Check if servers are responding
curl http://localhost:5000/api/health
curl http://localhost:5173/
# Check if ports are in use
lsof -i :5000
lsof -i :5173Solution:
- Increase timeout in
playwright.config.ts - Check backend logs for slow API calls
- Verify database connections are working
- Check network tab for slow requests
Problem: Integration tests can't find job_tracking.json
Diagnosis:
# Check if output directory exists
ls -la ../backend/output/
# Check file paths in file-helpers.ts
cat integration/helpers/file-helpers.tsSolution:
- Ensure
backend/output/directory exists - Check permissions on output directory
- Run backend at least once to create files
Problem: Tests fail with 401 Unauthorized
Diagnosis:
# Check test credentials
cat e2e/fixtures/auth.json
# Test login manually
curl -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"username":"admin","password":"admin123"}'Solution:
- Verify test credentials match backend users
- Check JWT token expiration settings
- Ensure auth endpoints are working
Problem: Tests pass sometimes, fail other times
Common causes:
- Race conditions (files not written yet)
- Network delays
- Timing issues
Solutions:
- Increase
waitForTimeoutvalues - Use
waitForFileUpdatehelper - Add
await page.waitForLoadState('networkidle') - Use explicit waits instead of fixed timeouts
// ✅ GOOD: Wait for file updates
await apiClient.updateJobStatus(jobKey, 'favorite');
await new Promise(resolve => setTimeout(resolve, 500)); // Wait for file write
const tracking = getJobFromTracking(jobKey);
assert.ok(tracking);
// ❌ BAD: No wait, file might not be written yet
await apiClient.updateJobStatus(jobKey, 'favorite');
const tracking = getJobFromTracking(jobKey); // Might fail// ✅ GOOD: Wait for element visibility
await expect(page.locator('[data-testid="form"]')).toBeVisible();
await page.fill('input[name="field"]', 'value');
// ❌ BAD: No wait, element might not be ready
await page.fill('input[name="field"]', 'value'); // Might fail// ✅ GOOD: Each test is independent
test('should favorite job', async () => {
// Setup: ensure clean state
// Action: favorite job
// Assert: verify favorited
});
// ❌ BAD: Tests depend on each other
test('should favorite job', async () => { /* ... */ });
test('should update favorite', async () => {
// Assumes previous test ran!
});name: E2E Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: Install dependencies
run: |
cd backend && pip install -r requirements.txt
cd frontend && npm install
cd testing && npm install
npx playwright install --with-deps
- name: Start backend
run: cd backend && python api.py &
- name: Start frontend
run: cd frontend && npm run dev &
- name: Wait for servers
run: |
sleep 10
curl http://localhost:5000/api/health
curl http://localhost:5173/
- name: Run tests
run: cd testing && npm run test:all
- name: Upload test results
if: always()
uses: actions/upload-artifact@v3
with:
name: playwright-report
path: testing/playwright-report/-
Integration test:
cd testing/integration # Create new-feature.test.ts npm run test:integration integration/new-feature.test.ts
-
E2E test:
cd testing/e2e # Create new-workflow.spec.ts npm run test:e2e:ui # Use UI mode for development
# E2E debugging
npm run test:e2e:debug e2e/favorite-workflow.spec.ts
# This opens Playwright Inspector:
# - Step through test
# - Inspect page elements
# - View network requests
# - See console logs# Run single E2E test
npx playwright test e2e/favorite-workflow.spec.ts
# Run test by name
npx playwright test -g "should add job to favorites"
# Run in headed mode (see browser)
npx playwright test --headed
# Run with specific browser
npx playwright test --project=firefox-
Run in parallel (default):
// playwright.config.ts fullyParallel: true, workers: 4, // Number of parallel workers
-
Reduce timeouts for fast tests:
test('fast test', async ({ page }) => { test.setTimeout(10000); // 10 seconds // ... });
-
Use test.describe.configure for independent tests:
test.describe.configure({ mode: 'parallel' });
-
Batch API calls:
await Promise.all([ apiClient.updateJobStatus(job1, 'favorite'), apiClient.updateJobStatus(job2, 'applied'), apiClient.updateJobStatus(job3, 'archive'), ]);
-
Reduce file wait times (if tests are stable):
await new Promise(resolve => setTimeout(resolve, 200)); // Instead of 500
Edit integration/helpers/test-data.ts:
export const testJobs = {
newCompany: {
company: 'New Company',
position: 'New Position',
jobKey: 'new company|new position',
},
};Edit e2e/fixtures/auth.json or e2e/fixtures/jobs.json:
{
"newTestUser": {
"username": "testuser",
"password": "testpass"
}
}# Manual cleanup
node -e "
const fs = require('fs');
fs.writeFileSync('../backend/output/job_tracking.json', '{}');
fs.writeFileSync('../backend/output/job_applications.csv', '');
"Cause: Backend database might not be initialized
Solution: Run backend once manually before tests:
cd backend && python api.py
# Wait for startup, then Ctrl+C
cd ../testing && npm run test:allSymptom: browserType.launch: Executable doesn't exist
Solution:
npx playwright installSymptom: Backend/frontend won't start
Solution:
# Find process using port
lsof -i :5000 # Backend
lsof -i :5173 # Frontend
# Kill process
kill -9 <PID>When adding tests:
- Follow existing test structure
- Use descriptive test names
- Add comments for complex logic
- Ensure tests are independent
- Update this README if adding new test types
This testing suite provides comprehensive coverage for Job Scanner:
- 15+ integration tests verifying backend functionality
- 10+ E2E tests verifying user workflows
- Real server testing for accurate results
- File verification for data persistence
- Detailed reports with screenshots and videos
Run npm run test:all to verify everything works correctly!