Home

E2E Testing Strategy: Git Chat React App

E2E Testing Strategy: Git Chat React App

Date: November 2025 Project: Git Chat - React + TypeScript Frontend Location: /home/ubuntu/workplace/AhaiaApp/ide/web-react


Overview

This document outlines the essential E2E testing strategy for the Git Chat React application, prioritized by risk and user impact. These tests verify the full stack: React frontend → Socket.io → Node.js backend → command execution.


Top 5 Essential E2E Test Scenarios

1. Happy Path: Quick Command Execution

Priority: 🔴 Critical Phase: 1 (MVP) Expected Duration: ~8 seconds

test('User can execute quick command and see result', async ({ page }) => {
  // Visit app
  // Click first repository
  // Type "echo 'Hello World'"
  // Press Enter
  // Verify: User message appears (blue bubble, right side)
  // Wait 1.5s
  // Verify: Response appears as simple gray bubble (not job UI)
  // Verify: Output contains "Hello World"
})

What it tests:

Why critical: This is the most common user flow. If this breaks, app is unusable.


2. Long Command with Job UI

Priority: 🔴 Critical Phase: 1 (MVP) Expected Duration: ~10 seconds

test('Long-running command shows job UI with live output', async ({ page }) => {
  // Visit app → Select repo
  // Type "sleep 3 && echo 'Done'"
  // Press Enter
  // Verify: Typing indicator appears
  // Wait 1.5s
  // Verify: Job UI appears (with cancel button, running status)
  // Verify: Output updates in real-time
  // Wait for completion
  // Verify: Success footer with duration
  // Verify: Cancel button removed
})

What it tests:

Why critical: Tests the core differentiator - smart message rendering logic and real-time streaming.


3. Job Cancellation

Priority: 🟡 High Phase: 2 (Production) Expected Duration: ~6 seconds

test('User can cancel running job', async ({ page }) => {
  // Select repo
  // Type "sleep 10"
  // Press Enter
  // Wait for job UI to appear
  // Click cancel button (X)
  // Verify: Job shows "Cancelled by user"
  // Verify: Cancel button disappears
  // Verify: No more output updates
})

What it tests:

Why critical: Tests Socket.io bidirectional communication and user control.


4. Repository Navigation

Priority: 🔴 Critical Phase: 1 (MVP) Expected Duration: ~10 seconds

test('User can switch between repositories', async ({ page }) => {
  // Load contacts page
  // Verify: Repository list loads
  // Click first repo
  // Verify: Chat page loads with correct repo name in header
  // Send command "pwd"
  // Verify: Output shows correct repo path
  // Click back button
  // Verify: Returns to contacts page
  // Click different repo
  // Verify: Chat context switched (different repo name)
  // Verify: Previous messages cleared
})

What it tests:

Why critical: Tests routing, context switching, and state isolation. Multi-repo support is core functionality.


5. Error Handling and Recovery

Priority: 🟡 High Phase: 2 (Production) Expected Duration: ~8 seconds

test('App handles command errors gracefully', async ({ page }) => {
  // Select repo
  // Type invalid command "nonexistentcommand12345"
  // Press Enter
  // Wait for completion
  // Verify: Error message shown
  // Verify: Exit code displayed (likely 127)
  // Verify: App still responsive
  // Send another valid command "echo 'recovery'"
  // Verify: App continues working normally
})

What it tests:

Why critical: Ensures one error doesn't crash the app. Tests production resilience.


Coverage Map

User Flows Covered:

Technical Areas Covered:

Risk Areas Covered:

  1. Backend connectivity - All tests require working Socket.io
  2. Message rendering - Tests both simple bubbles and job UI
  3. Timing logic - Tests the 1-second upgrade threshold
  4. State management - Tests context switches and message isolation
  5. Error resilience - Ensures app doesn't crash on errors

Additional Scenarios (Not in Top 5)

Phase 3 (Polish):


Implementation Phases

Phase 1 (MVP) - Tests #1, #2, #4

Goal: Prove basic functionality works Duration: ~28 seconds Coverage: Core user journeys

Deliverables:

Phase 2 (Production) - Tests #3, #5

Goal: Prove robustness and error handling Duration: +14 seconds (total: 42 seconds) Coverage: Edge cases and resilience

Deliverables:

Phase 3 (Polish) - Additional scenarios

Goal: Cover edge cases and polish Duration: +30 seconds (total: 72 seconds) Coverage: Nice-to-haves and edge cases


Test Structure

// e2e/critical-flows.spec.ts
import { test, expect } from '@playwright/test';

test.describe('Critical User Journeys', () => {
  test.beforeEach(async ({ page }) => {
    // Ensure backend is running on port 8000
    // Frontend on port 3015
    await page.goto('http://localhost:3015');
    await expect(page.locator('h1')).toContainText('Chats');
  });

  test('1. Quick command execution', async ({ page }) => { /*...*/ });
  test('2. Long command with job UI', async ({ page }) => { /*...*/ });
  test('3. Job cancellation', async ({ page }) => { /*...*/ });
  test('4. Repository navigation', async ({ page }) => { /*...*/ });
  test('5. Error handling', async ({ page }) => { /*...*/ });
});

Expected Test Times

Following the terminal-only development philosophy:

This ensures fast feedback loops even for E2E tests.


Test Environment Requirements

Prerequisites:

  1. Backend server running on port 8000
  2. Frontend dev server on port 3015 (or production build)
  3. At least 2 repositories in ~/workplace for navigation tests
  4. Playwright installed and configured

Setup Commands:

# Terminal 1: Backend
cd /home/ubuntu/workplace/AhaiaApp/ide/web
node server.js > /tmp/backend.log 2>&1 &

# Terminal 2: Frontend
cd /home/ubuntu/workplace/AhaiaApp/ide/web-react
npm run dev > /tmp/frontend.log 2>&1 &

# Terminal 3: Run tests
npm run test:e2e

Cleanup:

# Kill servers after tests
fuser -k 8000/tcp  # Backend
fuser -k 3015/tcp  # Frontend

Playwright Configuration

// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  testDir: './e2e',
  timeout: 30000, // 30s per test
  expect: {
    timeout: 5000, // 5s for assertions
  },
  fullyParallel: false, // Run sequentially (shared state)
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: 1, // Single worker (shared backend)
  reporter: 'list',
  use: {
    baseURL: 'http://localhost:3015',
    trace: 'on-first-retry',
    screenshot: 'only-on-failure',
  },
  projects: [
    {
      name: 'chromium',
      use: { ...devices['Desktop Chrome'] },
    },
  ],
  webServer: [
    {
      command: 'cd ../web && node server.js',
      port: 8000,
      timeout: 10000,
      reuseExistingServer: true,
    },
    {
      command: 'npm run dev',
      port: 3015,
      timeout: 10000,
      reuseExistingServer: true,
    },
  ],
});

Test Selectors Best Practices

Use data-testid for stability:

// Component
<button data-testid="send-button">Send</button>

// Test
await page.getByTestId('send-button').click();

Avoid brittle selectors:

.message-bubble:nth-child(2) - Breaks if UI changes ✅ page.getByRole('button', { name: 'Send' }) - Semantic ✅ page.getByTestId('job-output') - Explicit


Debugging E2E Tests

View test output:

npm run test:e2e > /tmp/e2e.log 2>&1
cat /tmp/e2e.log

Run in headed mode (requires X11 forwarding):

npm run test:e2e -- --headed

Run single test:

npx playwright test --grep "Quick command execution"

Debug with trace viewer:

npx playwright show-trace trace.zip

Check server logs during test:

tail -f /tmp/backend.log
tail -f /tmp/frontend.log

Success Metrics

You'll know E2E tests are working if:

  1. ✅ All Phase 1 tests pass in < 30 seconds
  2. ✅ Tests catch regressions before manual testing
  3. ✅ Can run tests in CI/CD pipeline
  4. ✅ No flaky tests (>95% pass rate)
  5. ✅ Tests fail with clear error messages

Red flags:


Maintenance

When to update tests:

Test review checklist:


Integration with CI/CD

Pre-commit hook (optional):

# .git/hooks/pre-commit
npm run test:e2e:quick  # Phase 1 tests only

Pre-deploy check:

npm run test:e2e  # All tests

GitHub Actions example:

- name: Run E2E Tests
  run: |
    npm run test:e2e
  env:
    CI: true


Notes for Future Developers

  1. Always test against real backend - Mocking Socket.io in E2E defeats the purpose
  2. Keep tests fast - Slow tests won't be run
  3. Use stable selectors - data-testid or semantic roles
  4. Test user journeys, not implementation - Test what users do, not how it works
  5. Redirect output to /tmp - Don't clutter workspace with test logs
  6. One assertion per test is a myth - Test complete user journeys

Quick Reference Commands

# Setup
npm install -D @playwright/test
npx playwright install

# Run all E2E tests
npm run test:e2e

# Run Phase 1 only
npm run test:e2e -- --grep "Phase 1"

# Run specific test
npx playwright test --grep "Quick command"

# Debug mode
npx playwright test --debug

# Update snapshots
npx playwright test --update-snapshots

# View test report
npx playwright show-report

Written for: Git Chat React refactoring project Last Updated: November 2025 Status: Strategy defined, implementation pending

READ i