Some checks are pending
Bidi Control Character Guard / bidi-control-guard (push) Waiting to run
Circular Dependency Check / Check for new circular dependencies (push) Waiting to run
Citus Migration Smoke / Combined migrations on single-node Citus (push) Waiting to run
E2E Fresh Install Tests / fresh-install-e2e (push) Waiting to run
ext-v2 guardrails / Run ext-v2 guard and ESLint (push) Waiting to run
Integration Tests / Check for relevant changes (push) Waiting to run
Integration Tests / ${{ (github.event_name == 'schedule' || github.event.inputs.suite == 'full') && 'Full integration suite' || 'Tier-1 integration subset' }} (push) Blocked by required conditions
Mobile checks / Mobile lint + typecheck (push) Waiting to run
Mobile checks / Mobile unit tests (push) Waiting to run
Mobile checks / Mobile dependency audit (report) (push) Waiting to run
Mobile checks / Mobile reproducibility checks (push) Waiting to run
Secrets guard (env backups) / Ensure no tracked env backup files (push) Waiting to run
Temporal Readiness / fast-readiness (push) Waiting to run
Temporal Readiness / docker-parity (push) Waiting to run
TypeScript Type Check / Nx affected typecheck (push) Waiting to run
Unit Tests / Skipped-test budget (push) Waiting to run
Unit Tests / Nx affected unit tests (push) Waiting to run
Unit Tests / Server unit coverage (informational) (push) Waiting to run
Validate Tenant Management Schema / Check for relevant changes (push) Waiting to run
Validate Tenant Management Schema / Validate Tenant Management Schema (push) Blocked by required conditions
EE Workflows Build Guard / ee-workflows-build-guard (push) Waiting to run
Excluded: .git, node_modules, secrets/, compose.env, assemblyscript tgz Source: /opt/alga-psa on psa.joliet.tech
6.7 KiB
6.7 KiB
E2E Testing Guide
This guide explains how to run End-to-End (E2E) tests for the Temporal workflows.
Overview
Our E2E testing strategy uses:
- Temporal TestWorkflowEnvironment for time-skipping unit tests
- temporalio/auto-setup Docker container for full integration tests
- Main application database for realistic data validation
- Vitest as the test runner with proper timeout configuration
Test Types
1. Unit Tests (Database Logic)
Location: src/activities/__tests__/*-simple.test.ts
- Test database operations without Temporal context
- Fast execution, isolated test data
- Focus on business logic validation
npm run test:unit
2. E2E Tests (Full Workflow)
Location: src/__tests__/e2e/*.e2e.test.ts
- Test complete workflows with Temporal
- Real activity execution with database operations
- End-to-end validation of business processes
npm run test:e2e
Prerequisites
-
Main Application Database: Must be running on port 5432
cd /Users/robertisaacs/alga-psa docker-compose -f docker-compose.base.yaml up -d postgres -
Node.js 20+: Required for Temporal SDK compatibility
-
Docker: For running Temporal test environment
Running E2E Tests
Method 1: Using NPM Scripts (Recommended)
# Run E2E tests once
npm run test:e2e
# Run E2E tests in watch mode
npm run test:e2e:watch
# Run all tests (unit + E2E)
npm run test:all
Method 2: Manual Docker Setup
# Start Temporal test environment
npm run docker:test:up
# Wait for services to be ready (check logs)
docker-compose -f docker-compose.test.yml logs -f
# Run tests manually
npm test -- src/__tests__/e2e
# Clean up
npm run docker:test:down
Method 3: Using Test Script
# Run the comprehensive E2E test script
./scripts/test-e2e.sh
# Run in watch mode
./scripts/test-e2e.sh --watch
Test Environment Configuration
Environment Files
.env.test: Unit test configuration (uses main app DB).env.e2e: E2E test configuration (Temporal + main app DB)
Docker Services
docker-compose.test.yml includes:
temporal: Temporal server with auto-setuppostgres: Dedicated PostgreSQL for Temporal metadatatemporal-admin-tools: CLI tools for debugging
Ports
- 7233: Temporal gRPC endpoint
- 8233: Temporal Web UI (http://localhost:8233)
- 5433: Temporal PostgreSQL
- 5432: Main application PostgreSQL (external)
Test Configuration
Vitest Settings
{
testTimeout: 120000, // 2 minutes for E2E tests
hookTimeout: 60000, // 1 minute for setup/teardown
pool: 'forks', // Required for Temporal
poolOptions: {
forks: { singleFork: true } // Prevent concurrent environments
}
}
Temporal Settings
{
address: 'localhost:7233',
namespace: 'default',
taskQueue: 'e2e-temporal-workflows'
}
Writing E2E Tests
Basic Structure
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { TestWorkflowEnvironment } from '@temporalio/testing';
import { Worker } from '@temporalio/worker';
import * as activities from '../../activities';
import { myWorkflow } from '../../workflows/my-workflow';
describe('My Workflow E2E', () => {
let testEnv: TestWorkflowEnvironment;
beforeAll(async () => {
testEnv = await TestWorkflowEnvironment.createTimeSkipping();
});
afterAll(async () => {
await testEnv?.teardown();
});
it('should complete workflow successfully', async () => {
const worker = await Worker.create({
connection: testEnv.nativeConnection,
taskQueue: 'test-queue',
workflowsPath: require.resolve('../../workflows'),
activities,
});
const handle = await testEnv.client.workflow.start(myWorkflow, {
args: [{ input: 'test' }],
taskQueue: 'test-queue',
workflowId: 'test-' + Date.now(),
});
const result = await handle.result();
expect(result.success).toBe(true);
await worker.shutdown();
});
});
Best Practices
-
Unique Test Data: Use timestamps to avoid conflicts
const timestamp = Date.now(); const email = `test-${timestamp}@example.com`; -
Proper Cleanup: Always clean up test data
afterEach(async () => { await testDb.cleanup(); }); -
Realistic Data: Use actual database operations
// Verify in database, not just workflow result const tenant = await testDb.getTenant(result.tenantId); expect(tenant.client_name).toBe(input.companyName ?? input.tenantName); -
Error Testing: Test failure scenarios
await expect(handle.result()).rejects.toThrow('Expected error');
Debugging
Temporal Web UI
Visit http://localhost:8233 when test environment is running to:
- View workflow executions
- Inspect workflow history
- Debug failed workflows
Logs
# View Temporal server logs
docker-compose -f docker-compose.test.yml logs temporal
# View PostgreSQL logs
docker-compose -f docker-compose.test.yml logs postgres
Database Inspection
# Connect to test database
docker exec -it temporal-workflows-postgres-1 psql -U temporal -d temporal
# Connect to main app database
docker exec -it alga-psa-postgres-1 psql -U postgres -d server
Troubleshooting
Common Issues
- Timeout Errors: Increase test timeouts in vitest.config.ts
- Port Conflicts: Ensure ports 7233, 8233, 5433 are available
- Database Connection: Verify main app database is running
- Memory Issues: Use
singleFork: truein Vitest pool options
Error: "Main application database not running"
cd /Users/robertisaacs/alga-psa
docker-compose -f docker-compose.base.yaml up -d postgres
Error: "Temporal connection failed"
# Restart test environment
npm run docker:test:down
npm run docker:test:up
Error: "Test timeout"
- Check Temporal Web UI for stuck workflows
- Increase timeouts in vitest.config.ts
- Verify all services are healthy
Performance
Expected Test Times
- Basic setup test: ~10-30 seconds
- Simple workflow test: ~30-60 seconds
- Complex workflow test: ~1-2 minutes
Optimization Tips
- Use
TestWorkflowEnvironment.createTimeSkipping()for faster tests - Minimize database operations in tests
- Use test data factories for consistent setup
- Run tests in single fork mode to avoid conflicts
Integration with CI/CD
# Example GitHub Actions step
- name: Run E2E Tests
run: |
docker-compose -f docker-compose.base.yaml up -d postgres
npm run test:e2e
env:
NODE_ENV: test
For more details, see the test files in src/__tests__/e2e/ and the setup utilities in src/test-utils/.