E2E Test Plan - Rapid Platform
Overview
Comprehensive end-to-end test plan for the Rapid platform (Aether frontend + Nemesis backend) using Playwright. This test suite covers authentication, employee flows, employer flows, contractor flows, and RBAC validation.
Tech Stack:
- Frontend: React + TypeScript + Vite (Aether)
- Backend: Django REST Framework (Nemesis)
- Testing: Playwright
- Authentication: JWT with Email OTP
Test Tasks - ALL
| # | Task | Status | Description |
|---|---|---|---|
| 1 | OTP Bypass Implementation | X | Django backend OTP bypass for E2E testing |
| 2 | Playwright Scaffold | X | Base setup with fixtures and utilities |
| 3 | Authentication Tests | X | Login, OTP, password reset flows |
| 4 | Employee Onboarding Tests | X | 6-step onboarding flow |
| 5 | Employee Verification Tests | X | eKYC and e-sign flows |
| 6 | Employee Requests Tests | X | Leave and expense claims |
| 7 | Employee Tax/Profile Tests | X | Tax declaration, profile management |
| 8 | Employer Setup Tests | X | First-login, settings wizard |
| 9 | Employer Contracts Tests | X | Create, edit, withdraw contracts |
| 10 | Employer Approvals Tests | X | Request approval workflow |
| 11 | Employer Settings Tests | X | All settings tabs |
| 12 | RBAC Tests | X | Access control validation |
Test Scenarios Checklist
Authentication Tests
| Scenario | File | Status |
|---|---|---|
| Display login page correctly | login.spec.ts | X |
| Validate empty email | login.spec.ts | X |
| Validate invalid email format | login.spec.ts | X |
| Show error for wrong credentials | login.spec.ts | X |
| Employee login success | login.spec.ts | X |
| Employer login success | login.spec.ts | X |
| Contractor login success | login.spec.ts | X |
| Complete login with OTP | login.spec.ts | X |
| Persist login on refresh | login.spec.ts | X |
| Redirect authenticated from login | login.spec.ts | X |
| Display OTP page | otp.spec.ts | X |
| Validate OTP is 6 digits | otp.spec.ts | X |
| Show error for wrong OTP | otp.spec.ts | X |
| Verify OTP with bypass code | otp.spec.ts | X |
| Resend OTP functionality | otp.spec.ts | X |
| Display forgot password page | password-reset.spec.ts | X |
| Submit forgot password request | password-reset.spec.ts | X |
| Reset password with valid token | password-reset.spec.ts | X |
Employee Onboarding Tests
| Scenario | File | Status |
|---|---|---|
| Display personal details form | personal-details.spec.ts | X |
| Pre-fill user data | personal-details.spec.ts | X |
| Validate required fields | personal-details.spec.ts | X |
| Validate PAN format | personal-details.spec.ts | X |
| Select gender and marital status | personal-details.spec.ts | X |
| Proceed to next step | personal-details.spec.ts | X |
| Display employment eligibility | employment-eligibility.spec.ts | X |
| Show employment status options | employment-eligibility.spec.ts | X |
| Upload eligibility documents | employment-eligibility.spec.ts | X |
| Display contact details form | contact-details.spec.ts | X |
| Country/State/City cascading | contact-details.spec.ts | X |
| Validate phone format | contact-details.spec.ts | X |
| Display emergency contact form | emergency-contact.spec.ts | X |
| Validate different from personal | emergency-contact.spec.ts | X |
| Display bank details form | bank-details.spec.ts | X |
| Validate IFSC format | bank-details.spec.ts | X |
| Upload bank documents | bank-details.spec.ts | X |
| Display statutory tax form | statutory-tax.spec.ts | X |
| Select tax regime | statutory-tax.spec.ts | X |
| Complete onboarding | statutory-tax.spec.ts | X |
| Full 6-step journey | full-flow.spec.ts | X |
Employee Verification Tests
| Scenario | File | Status |
|---|---|---|
| Display consent step | verification.spec.ts | X |
| Accept consent | verification.spec.ts | X |
| Personal details verification | verification.spec.ts | X |
| ID proof type selection | verification.spec.ts | X |
| Upload ID document | verification.spec.ts | X |
| Face verification | verification.spec.ts | X |
| Display offer letter | verification.spec.ts | X |
| Download offer letter | verification.spec.ts | X |
| E-sign agreement | verification.spec.ts | X |
Employee Requests Tests
| Scenario | File | Status |
|---|---|---|
| Display leave request form | leave-request.spec.ts | X |
| Load leave types with balance | leave-request.spec.ts | X |
| Validate date range | leave-request.spec.ts | X |
| Show duration options | leave-request.spec.ts | X |
| Calculate total days | leave-request.spec.ts | X |
| Submit leave request | leave-request.spec.ts | X |
| Display expense claim form | expense-claim.spec.ts | X |
| Load expense types | expense-claim.spec.ts | X |
| Validate amount | expense-claim.spec.ts | X |
| Upload receipts | expense-claim.spec.ts | X |
| Submit expense claim | expense-claim.spec.ts | X |
| Display requests table | requests-list.spec.ts | X |
| Filter by status | requests-list.spec.ts | X |
| Filter by type | requests-list.spec.ts | X |
| Pagination | requests-list.spec.ts | X |
| Open sidebar details | requests-list.spec.ts | X |
| Withdraw request | requests-list.spec.ts | X |
Employee Tax & Profile Tests
| Scenario | File | Status |
|---|---|---|
| Display tax page | tax.spec.ts | X |
| Show tax regime options | tax.spec.ts | X |
| Select new/old regime | tax.spec.ts | X |
| Show exemption categories | tax.spec.ts | X |
| Enter investment amounts | tax.spec.ts | X |
| Save declaration | tax.spec.ts | X |
| Upload tax proof | tax.spec.ts | X |
| Display profile tabs | profile.spec.ts | X |
| View personal details | profile.spec.ts | X |
| Edit bank details | profile.spec.ts | X |
| View/upload documents | profile.spec.ts | X |
Employer Setup Tests
| Scenario | File | Status |
|---|---|---|
| Display first login dashboard | first-login.spec.ts | X |
| Show setup steps | first-login.spec.ts | X |
| Navigate to settings wizard | first-login.spec.ts | X |
| Settings wizard step 1: Bonus | first-login.spec.ts | X |
| Settings wizard step 2: Leave | first-login.spec.ts | X |
| Settings wizard step 3: Holiday | first-login.spec.ts | X |
| Complete wizard | first-login.spec.ts | X |
| Hire first employee form | first-login.spec.ts | X |
Employer Contracts Tests
| Scenario | File | Status |
|---|---|---|
| Display contracts list | contracts.spec.ts | X |
| Show table headers | contracts.spec.ts | X |
| Filter by status | contracts.spec.ts | X |
| Search contracts | contracts.spec.ts | X |
| Navigate to create contract | contracts.spec.ts | X |
| Download report | contracts.spec.ts | X |
| View contract details | contracts.spec.ts | X |
| Create contract form | contracts.spec.ts | X |
| Validate required fields | contracts.spec.ts | X |
| Multi-step contract creation | contracts.spec.ts | X |
| Edit contract | contracts.spec.ts | X |
| Withdraw contract | contracts.spec.ts | X |
Employer Requests Tests
| Scenario | File | Status |
|---|---|---|
| Display requests dashboard | requests.spec.ts | X |
| Show status filter buttons | requests.spec.ts | X |
| Filter by status/type/employee | requests.spec.ts | X |
| Open request sidebar | requests.spec.ts | X |
| Approve request | requests.spec.ts | X |
| Approve with remarks | requests.spec.ts | X |
| Reject request | requests.spec.ts | X |
| Require remarks for rejection | requests.spec.ts | X |
| Magic link approval | requests.spec.ts | X |
Employer Settings Tests
| Scenario | File | Status |
|---|---|---|
| Display settings page | settings.spec.ts | X |
| Show settings tabs | settings.spec.ts | X |
| Company profile view/edit | settings.spec.ts | X |
| Leave policy configuration | settings.spec.ts | X |
| Holiday calendar management | settings.spec.ts | X |
| Team creation | settings.spec.ts | X |
| User permissions | settings.spec.ts | X |
| Invite new user | settings.spec.ts | X |
| Edit user role | settings.spec.ts | X |
| Resend invite | settings.spec.ts | X |
RBAC Tests
| Scenario | File | Status |
|---|---|---|
| Employee cannot access employer routes | access-control.spec.ts | X |
| Employee cannot access contractor routes | access-control.spec.ts | X |
| Employer cannot access employee routes | access-control.spec.ts | X |
| Employer cannot access contractor routes | access-control.spec.ts | X |
| Contractor cannot access employee routes | access-control.spec.ts | X |
| Contractor cannot access employer routes | access-control.spec.ts | X |
| Unauthenticated redirect to login | access-control.spec.ts | X |
| Authenticated redirect from public routes | access-control.spec.ts | X |
| Expired token handling | access-control.spec.ts | X |
Test Files Structure
e2e/
├── playwright.config.ts # Playwright configuration
├── package.json # Dependencies and scripts
├── tsconfig.json # TypeScript configuration
├── .env.test # Test environment variables
├── .env.example # Example environment file
├── global-setup.ts # Global test setup
├── README.md # Quick start guide
│
├── fixtures/ # Role-based test fixtures
│ ├── auth.ts # Authentication helpers
│ ├── employee.ts # Employee role fixture
│ ├── employer.ts # Employer role fixture
│ └── contractor.ts # Contractor role fixture
│
├── utils/ # Shared utilities
│ ├── test-data.ts # Test data generators
│ └── selectors.ts # Common CSS selectors
│
├── tests/
│ ├── auth/ # Authentication tests
│ │ ├── login.spec.ts
│ │ ├── otp.spec.ts
│ │ └── password-reset.spec.ts
│ │
│ ├── employee/ # Employee flow tests
│ │ ├── dashboard.spec.ts
│ │ ├── onboarding/
│ │ │ ├── personal-details.spec.ts
│ │ │ ├── employment-eligibility.spec.ts
│ │ │ ├── contact-details.spec.ts
│ │ │ ├── emergency-contact.spec.ts
│ │ │ ├── bank-details.spec.ts
│ │ │ ├── statutory-tax.spec.ts
│ │ │ └── full-flow.spec.ts
│ │ ├── verification/
│ │ │ └── verification.spec.ts
│ │ ├── requests/
│ │ │ ├── leave-request.spec.ts
│ │ │ ├── expense-claim.spec.ts
│ │ │ └── requests-list.spec.ts
│ │ ├── profile/
│ │ │ └── profile.spec.ts
│ │ └── tax/
│ │ └── tax.spec.ts
│ │
│ ├── employer/ # Employer flow tests
│ │ ├── dashboard.spec.ts
│ │ ├── setup/
│ │ │ └── first-login.spec.ts
│ │ ├── contracts/
│ │ │ └── contracts.spec.ts
│ │ ├── requests/
│ │ │ └── requests.spec.ts
│ │ └── settings/
│ │ └── settings.spec.ts
│ │
│ └── rbac/ # Access control tests
│ └── access-control.spec.ts
│
└── docs/ # Documentation
├── employee-flows.md
├── employer-flows.md
├── backend-analysis.md
└── test-plan.md
Running Tests
Quick Start
bash
# Install dependencies
cd e2e
npm install
npx playwright install
# Run all tests
npm test
# Run with browser visible
npm run test:headed
# Run with Playwright UI
npm run test:ui
Run Specific Suites
bash
# By role
npm run test:employee # All employee tests
npm run test:employer # All employer tests
npm run test:auth # Authentication tests
npm run test:rbac # RBAC tests
# By file
npx playwright test tests/employee/onboarding/
# By test name
npx playwright test -g "login"
Debug Mode
bash
# Debug single test
npm run test:debug
# With trace
npx playwright test --trace on
# Record new test
npm run codegen
Reports
bash
# View HTML report
npm run report
# Generate JSON report
npx playwright test --reporter=json
Environment Setup
1. Backend (Nemesis)
Add to your .env file:
env
# Enable E2E testing mode
E2E_TESTING_MODE=True
E2E_OTP_BYPASS_CODE=000000
Start the backend:
bash
cd nemesis
source venv/bin/activate
python manage.py runserver
2. Frontend (Aether)
Start the development server:
bash
cd aether
npm run dev
3. Test Database
Load test fixtures:
bash
cd nemesis
python manage.py loaddata fixtures/users.json
python manage.py loaddata fixtures/company.json
python manage.py loaddata fixtures/employee.json
python manage.py loaddata fixtures/contractor.json
4. E2E Configuration
Create .env.test:
env
# URLs
FRONTEND_URL=http://localhost:5173
API_URL=http://localhost:8000
# OTP Bypass (must match backend)
E2E_OTP_BYPASS_CODE=000000
# Test Users
TEST_EMPLOYEE_EMAIL=test-employee@rapid.one
TEST_EMPLOYEE_PASSWORD=Test@123
TEST_EMPLOYER_EMAIL=test-employer@rapid.one
TEST_EMPLOYER_PASSWORD=Test@123
TEST_CONTRACTOR_EMAIL=test-contractor@rapid.one
TEST_CONTRACTOR_PASSWORD=Test@123
CI/CD Integration
GitHub Actions
yaml
name: E2E Tests
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
e2e:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:14
env:
POSTGRES_DB: rapid_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
ports:
- 5432:5432
redis:
image: redis:7
ports:
- 6379:6379
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Backend Dependencies
run: |
cd nemesis
pip install -r requirements.txt
- name: Setup Backend
run: |
cd nemesis
python manage.py migrate
python manage.py loaddata fixtures/users.json
env:
E2E_TESTING_MODE: 'True'
E2E_OTP_BYPASS_CODE: '000000'
DATABASE_NAME: rapid_test
DATABASE_USERNAME: postgres
DATABASE_PASSWORD: postgres
DATABASE_HOST: localhost
- name: Start Backend
run: |
cd nemesis
python manage.py runserver &
env:
E2E_TESTING_MODE: 'True'
E2E_OTP_BYPASS_CODE: '000000'
- name: Install Frontend Dependencies
run: |
cd aether
npm ci
- name: Start Frontend
run: |
cd aether
npm run dev &
- name: Install E2E Dependencies
run: |
cd e2e
npm ci
npx playwright install --with-deps
- name: Run E2E Tests
run: |
cd e2e
npm test
env:
FRONTEND_URL: http://localhost:5173
API_URL: http://localhost:8000
E2E_OTP_BYPASS_CODE: '000000'
- name: Upload Test Report
uses: actions/upload-artifact@v3
if: always()
with:
name: playwright-report
path: e2e/playwright-report/
Docker Compose (Local CI)
yaml
version: '3.8'
services:
backend:
build: ./nemesis
environment:
- E2E_TESTING_MODE=True
- E2E_OTP_BYPASS_CODE=000000
ports:
- "8000:8000"
frontend:
build: ./aether
ports:
- "5173:5173"
e2e:
build: ./e2e
depends_on:
- backend
- frontend
environment:
- FRONTEND_URL=http://frontend:5173
- API_URL=http://backend:8000
command: npm test
Best Practices
1. Test Organization
typescript
// Group related tests
test.describe('Feature Name', () => {
// Setup before each test
test.beforeEach(async ({ page }) => {
// Navigate to page
});
test('should do something', async ({ page }) => {
// Test implementation
});
});
2. Use Role Fixtures
typescript
// Instead of manual auth
import { test, expect } from '../../fixtures/employee';
test('employee test', async ({ page }) => {
// page is already authenticated
});
3. Selector Strategy
typescript
// Priority order:
// 1. data-testid (most stable)
await page.locator('[data-testid="submit-button"]');
// 2. Role + name
await page.getByRole('button', { name: 'Submit' });
// 3. Name attribute
await page.locator('input[name="email"]');
// 4. Text content (fallback)
await page.locator('text=/submit/i');
4. Wait Strategies
typescript
// Wait for navigation
await expect(page).toHaveURL(/\/dashboard/);
// Wait for element
await expect(page.locator('[data-testid="table"]')).toBeVisible();
// Wait for API response
await page.waitForResponse(resp => resp.url().includes('/api/'));
// Wait for network idle
await page.waitForLoadState('networkidle');
5. Handle Flaky Tests
typescript
// Retry assertions
await expect(element).toBeVisible({ timeout: 10000 });
// Multiple valid outcomes
await Promise.race([
expect(page).toHaveURL(/\/success/),
expect(page.locator('text=Success')).toBeVisible(),
]);
// Catch optional elements
await element.click().catch(() => {});
Troubleshooting
Common Issues
| Issue | Solution |
|---|---|
| Backend unavailable | Ensure Django is running on port 8000 |
| OTP verification fails | Check E2E_TESTING_MODE=True and bypass code matches |
| Token refresh fails | Verify refresh token in localStorage |
| Role redirect issues | Check user user_type in database |
| Flaky tests | Add explicit waits, increase timeouts |
| File upload fails | Use setInputFiles with Buffer content |
Debug Commands
bash
# Run with debug logs
DEBUG=pw:api npm test
# Run single test in debug mode
npx playwright test tests/auth/login.spec.ts --debug
# Generate trace for failed tests
npx playwright test --trace on
# View trace
npx playwright show-trace trace.zip
Test Metrics
| Category | Test Files | Test Cases | Priority |
|---|---|---|---|
| Authentication | 3 | ~25 | Critical |
| Employee Onboarding | 7 | ~45 | High |
| Employee Verification | 1 | ~15 | High |
| Employee Requests | 3 | ~30 | High |
| Employee Profile/Tax | 2 | ~20 | Medium |
| Employer Setup | 1 | ~15 | High |
| Employer Contracts | 1 | ~20 | High |
| Employer Requests | 1 | ~15 | High |
| Employer Settings | 1 | ~25 | Medium |
| RBAC | 1 | ~30 | Critical |
| Total | 21 | ~240 |
Maintenance
Adding New Tests
- Identify the feature category (auth, employee, employer, rbac)
- Create test file in appropriate directory
- Use existing fixtures for authentication
- Follow naming convention:
feature-name.spec.ts - Add test scenarios to this document
Updating Selectors
When UI changes:
- Update
utils/selectors.tsfor common selectors - Prefer
data-testidattributes - Test locally before pushing
Test Data
- Update
utils/test-data.tsfor new test data - Keep fixtures in sync with Django fixtures
- Use generators for unique data (emails, etc.)
Test Coverage Gaps
For a comprehensive analysis of missing test coverage and implementation tasks, see:
- Test Coverage Gap Analysis - Detailed analysis of what's missing
- Full Task Breakdown - Implementation tasks with effort estimates
Summary
Current Coverage: ~75%
Target Coverage: ~90%
Priority Gaps:
- 🔴 Contractor Tests (80% gap) - Time sheets, invoices, full onboarding flow
- 🔴 Company Registration - Complete employer signup flow
- 🔴 Error Handling - Validation errors, API errors, edge cases
- 🟡 Advanced Employer Features - Payroll, teams, advanced settings
- 🟡 Advanced Employee Features - Dashboard, document management
See test-coverage-gaps.md for complete details and tasks-full.md for implementation plan.
Version History
| Version | Date | Changes |
|---|---|---|
| 1.0.0 | 2024-02 | Initial test suite with all flows |
Contributors
- Based on Aether (React) + Nemesis (Django) codebase analysis