# End-to-End Testing End-to-end (E2E) testing validates complete user workflows from platform loading through authentication, interaction, and logout. ## Overview E2E tests simulate real user interactions: 1. **Platform Loading** - UI and API infrastructure operational 2. **BotServer Initialization** - Backend service running and ready 3. **User Authentication** - Login workflow functional 4. **Chat Interaction** - Message sending and receiving 5. **Logout** - Session management and access control ## Complete Platform Flow Test The main E2E test validates the entire user journey: ```rust #[tokio::test] async fn test_complete_platform_flow_login_chat_logout() { // Setup let ctx = E2ETestContext::setup_with_browser().await?; let browser = ctx.browser.as_ref().unwrap(); // Phase 1: Platform Loading verify_platform_loading(&ctx).await?; // Phase 2: BotServer Running verify_botserver_running(&ctx).await?; // Phase 3: User Login test_user_login(browser, &ctx).await?; // Phase 4: Chat Interaction test_chat_interaction(browser, &ctx).await?; // Phase 5: Logout test_user_logout(browser, &ctx).await?; ctx.close().await; } ``` ## Test Phases ### Phase 1: Platform Loading Verifies UI and API infrastructure: ```rust verify_platform_loading(&ctx).await? ``` Checks: - Health endpoint responds with 2xx status - API endpoints are accessible - Database migrations completed - Services are initialized ### Phase 2: BotServer Initialization Verifies the backend service is operational: ```rust verify_botserver_running(&ctx).await? ``` Checks: - Process is alive and responding - Configuration properly loaded - Dependencies connected (DB, cache, storage) - Health checks pass ### Phase 3: User Authentication Tests the login workflow: ```rust test_user_login(browser, &ctx).await? ``` Tests: - Navigate to login page - Form elements present and functional - Accept valid test credentials (test@example.com / TestPassword123!) - Create session and authentication token - Redirect to dashboard/chat interface ### Phase 4: Chat Interaction Tests messaging functionality: ```rust test_chat_interaction(browser, &ctx).await? ``` Tests: - Chat interface loads correctly - User can type and send messages - Bot responds with valid output - Message history persists - Multiple exchanges work correctly ### Phase 5: Logout & Session Management Tests secure session handling: ```rust test_user_logout(browser, &ctx).await? ``` Tests: - Logout button/action works - Session is invalidated - User redirected to login page - Protected routes block unauthenticated access - Cannot access chat after logout ## Running E2E Tests ### HTTP-Only Tests (No Browser Required) These tests verify API and infrastructure without browser automation: ```bash cd gb/bottest # Platform loading verification cargo test --test e2e test_platform_loading_http_only -- --nocapture # BotServer startup verification cargo test --test e2e test_botserver_startup -- --nocapture ``` Execution time: ~2-5 seconds ### Complete Flow Tests (Requires WebDriver) Full browser-based tests with user interactions: ```bash # Start WebDriver first chromedriver --port=4444 & # Run complete platform flow cargo test --test e2e test_complete_platform_flow_login_chat_logout -- --nocapture # Run simplified flow cargo test --test e2e test_login_and_chat_flow -- --nocapture ``` Execution time: ~30-60 seconds ## WebDriver Setup ### Option 1: Local Installation ```bash # Download chromedriver from https://chromedriver.chromium.org/ # Place in PATH, then start: chromedriver --port=4444 ``` ### Option 2: Docker ```bash docker run -d -p 4444:4444 selenium/standalone-chrome ``` ### Option 3: Docker Compose ```bash docker-compose up -d webdriver ``` ## Environment Variables Control test behavior: | Variable | Default | Purpose | |----------|---------|---------| | `HEADED` | unset | Show browser window instead of headless | | `WEBDRIVER_URL` | `http://localhost:4444` | WebDriver server endpoint | | `SKIP_E2E_TESTS` | unset | Skip E2E tests if set | | `RUST_LOG` | info | Logging level: debug, info, warn, error | | `KEEP_TEMP_STACK_ON_ERROR` | unset | Preserve temp directory on failure | ### Examples ```bash # Show browser UI for debugging HEADED=1 cargo test --test e2e -- --nocapture # Use custom WebDriver WEBDRIVER_URL=http://localhost:4445 cargo test --test e2e -- --nocapture # Verbose logging RUST_LOG=debug cargo test --test e2e -- --nocapture # Run single-threaded with output cargo test --test e2e -- --nocapture --test-threads=1 ``` ## Test Helpers Reusable helper functions for custom tests: ```rust // Verify platform is operational verify_platform_loading(&ctx) -> Result<()> // Verify BotServer is running verify_botserver_running(&ctx) -> Result<()> // Perform login with credentials test_user_login(browser, &ctx) -> Result<()> // Send message and wait for response test_chat_interaction(browser, &ctx) -> Result<()> // Logout and verify session invalidation test_user_logout(browser, &ctx) -> Result<()> ``` ## Test Context Setup a test context for E2E testing: ```rust use bottest::prelude::*; use bottest::web::{Browser, BrowserConfig}; // HTTP-only context let ctx = E2ETestContext::setup().await?; // With browser automation let ctx = E2ETestContext::setup_with_browser().await?; let browser = ctx.browser.as_ref().unwrap(); // Access base URL let url = ctx.base_url(); // Access running server let is_running = ctx.server.is_running(); // Cleanup ctx.close().await; ``` ## Common Issues ### WebDriver Not Available **Problem**: Test fails with "WebDriver not available" **Solution**: ```bash # Start WebDriver chromedriver --port=4444 # or docker run -d -p 4444:4444 selenium/standalone-chrome ``` ### Port Already in Use **Problem**: Services fail to start due to port conflicts **Solution**: ```bash # Kill existing services pkill -f chromedriver pkill -f botserver pkill -f postgres pkill -f redis-server ``` ### Test Hangs or Timeout **Problem**: Test appears to hang or timeout **Solution**: ```bash # Run with timeout and verbose output timeout 120s RUST_LOG=debug cargo test --test e2e test_name -- --nocapture --test-threads=1 ``` ### Browser Connection Issues **Problem**: Browser fails to connect to WebDriver **Solution**: ```bash # Use different WebDriver port WEBDRIVER_URL=http://localhost:4445 cargo test --test e2e -- --nocapture ``` ## Debugging ### View Test Output ```bash # Show all output cargo test --test e2e test_name -- --nocapture # With timestamps RUST_LOG=debug cargo test --test e2e test_name -- --nocapture # Save to file cargo test --test e2e test_name -- --nocapture 2>&1 | tee test.log ``` ### Watch Browser in Action ```bash # Run with visible browser HEADED=1 cargo test --test e2e test_name -- --nocapture --test-threads=1 ``` ### Check Server Logs ```bash # Monitor logs while tests run tail -f /tmp/bottest-*/botserver.log # In another terminal: cargo test --test e2e test_name -- --nocapture ``` ## Performance Typical execution times: | Test | Time | Resources | |------|------|-----------| | Platform loading (HTTP-only) | ~2s | Minimal | | BotServer startup (HTTP-only) | ~5s | Minimal | | Login and chat flow | ~20s | Browser + Memory | | Complete flow with all phases | ~45s | Browser + Memory | | Full E2E test suite | ~2-3 min | High | Use release mode for faster execution: ```bash cargo test --test e2e --release -- --nocapture ``` ## CI/CD Integration ### GitHub Actions Example ```yaml name: E2E Tests on: [push, pull_request] jobs: e2e: runs-on: ubuntu-latest services: chromedriver: image: selenium/standalone-chrome options: --shm-size=2gb steps: - uses: actions/checkout@v3 - uses: actions-rs/toolchain@v1 with: toolchain: stable - run: cd gb/bottest && cargo test --test e2e -- --nocapture ``` ## Temporary Stack Architecture (Future) When BotServer implements `--temp-stack`, E2E tests will run in isolated environments: ```bash botserver --temp-stack # Creates: /tmp/botserver-test-{timestamp}-{random}/ # With isolated: PostgreSQL, Redis, MinIO, Mock LLM # Auto-cleanup after test completion ``` Benefits: - ✓ Isolation - Each test in separate environment - ✓ Reproducibility - Consistent setup every time - ✓ Automation - No manual configuration - ✓ Safety - Won't interfere with development - ✓ Cleanup - Automatic resource management - ✓ Parallel - Multiple tests simultaneously - ✓ CI/CD Ready - Perfect for automated pipelines ## Writing Custom E2E Tests Create new test files in `gb/bottest/tests/e2e/`: ```rust #[tokio::test] async fn test_my_feature() { // Setup context let ctx = E2ETestContext::setup_with_browser().await?; let browser = ctx.browser.as_ref().unwrap(); // Navigate to feature browser.navigate(&format!("{}/my-feature", ctx.base_url())).await?; // Interact with UI browser.click("button.action").await?; browser.wait_for_element(".result", Duration::from_secs(10)).await?; // Verify results let text = browser.get_text(".result").await?; assert_eq!(text, "Expected result"); // Cleanup ctx.close().await; } ``` Register in `tests/e2e/mod.rs`: ```rust mod my_feature; ``` ## Best Practices 1. **Keep tests focused** - Test one user workflow per test 2. **Use meaningful names** - `test_complete_platform_flow` not `test_1` 3. **Explicit waits** - Use `wait_for_element` instead of `sleep` 4. **Test realistic flows** - Use actual test credentials 5. **Verify results explicitly** - Check status codes, UI elements, and state 6. **Clean up properly** - Always call `ctx.close().await` 7. **Handle errors gracefully** - Use `?` operator for error propagation 8. **Make tests independent** - Don't rely on test execution order ## Test Success Criteria ✓ Platform fully loads without errors ✓ BotServer starts and becomes ready ✓ User can login with credentials ✓ Chat messages are sent and responses received ✓ User can logout and session is invalidated ✓ Protected routes block unauthenticated access ✓ Tests run consistently multiple times ✓ Tests complete within acceptable time (~60 seconds) ## See Also - [Testing Overview](./README.md) - Testing strategy and structure - [Performance Testing](./performance.md) - Benchmarks and load tests - [Test Architecture](./architecture.md) - Design patterns and best practices - [Integration Testing](./integration.md) - Multi-component testing