All docs/CI/CD & Testing

docs/architecture/e2e-testing-architecture.md

E2E Testing Architecture

Overview

End-to-end smoke tests validate the critical user journey across the video stack: branded-video-flow → video processing → library. Tests run on staging after deployment, gating production releases.

Tech Stack:

  • Playwright (Chromium only, for speed)
  • GitHub Actions (CI/CD integration)
  • Clerk API (programmatic authentication)

High-Level Test Flow

Test Phases

PhaseStatusPurpose
Phase 1: Deployment Verificationāœ… CompletePoll /api/info endpoints, verify SHA matches
Phase 2: Clerk AuthenticationšŸ”² PendingCreate test session via Clerk API, inject cookies
Phase 3: Video Upload FlowšŸ”² PendingUpload test video via BVF, submit form
Phase 4: Library VerificationšŸ”² PendingFind video in Library, verify playable
Phase 5: CleanupšŸ”² PendingDelete test video to leave clean state
Phase 6: Rollback AutomationšŸ”² PendingAuto-rollback staging on test failure

Architecture Diagram

Clerk Authentication Strategy

Approach: API Token Session Injection

Rather than automating UI login (slow, flaky), we create a Clerk session programmatically and inject it into Playwright's browser context.

Required Secrets

SecretPurposeWhere Used
CLERK_SECRET_KEYAPI authenticationFixture creation
E2E_TEST_USER_IDTest user identifierSession creation
BVF_STAGING_URLBVF base URLTest navigation
LIBRARY_STAGING_URLLibrary base URLTest navigation
VERCEL_AUTOMATION_BYPASS_SECRETSkip Vercel authProtected deployments

Test User Requirements

Create a dedicated test user in Clerk dashboard:

  • Email: e2e-test@happyclient.internal (or similar)
  • Assigned to a test organization with known orgId
  • Has permissions to view/delete videos
  • Should NOT be a real user account

Video Upload Strategy

Current State: No Upload Mode

The branded-video-flow app currently only supports webcam recording, not file uploads. For CI/headless testing, we need an alternative.

Options Comparison

OptionComplexityReliabilitySpeed
A: Add upload mode to BVFMediumHighFast
B: Direct API upload + mock formLowMediumFast
C: WebRTC mock (fake camera)HighLowSlow

Recommended: Option A - Upload Mode

Add a query parameter to enable file upload in BVF:

/flows/sanity-smoke?uploadMode=true&testMode=true

When enabled:

  1. Show file input instead of camera UI
  2. Accept video file from disk
  3. Upload via existing /api/blob/upload
  4. Continue with normal submission flow

Guard: Only enabled when both:

  • ?uploadMode=true in URL
  • DEPLOYMENT_ENVIRONMENT is staging or local (never production)

Test Flow Configuration

Dedicated Test Flow: sanity-smoke

Create a minimal flow specifically for e2e testing:

// packages/app-video-flow/src/server/flows/configurations/sanity-smoke.ts
export const sanitySmokeFlow: FlowConfig = {
  id: "sanity-smoke",
  name: "E2E Smoke Test Flow",
  slug: "sanity-smoke",
  orgId: "org_e2e_test", // Dedicated test org

  questions: [
    {
      id: "q1",
      type: "video",
      text: { en: "Please share a brief test message." },
      required: true,
    },
  ],

  // Minimal config for fast tests
  settings: {
    allowSkip: false,
    requireName: true,
    requireEmail: false,
  },

  // Test-specific flags
  __testConfig: {
    uploadModeAllowed: true,
    cleanupAfterSubmit: false, // Let test handle cleanup
  },
};

Flow Availability

Complete Test Sequence

File Organization

tests/e2e/
ā”œā”€ā”€ playwright.config.ts          # Playwright configuration
ā”œā”€ā”€ package.json                  # E2E-specific dependencies
ā”œā”€ā”€ tsconfig.json                 # TypeScript config
ā”œā”€ā”€ specs/
│   ā”œā”€ā”€ smoke.spec.ts             # Main smoke test (deployment + flow)
│   └── helpers/
│       └── polling.ts            # Retry/polling utilities
ā”œā”€ā”€ fixtures/
│   ā”œā”€ā”€ auth.ts                   # Clerk session fixture
│   ā”œā”€ā”€ test-data.ts              # Test video metadata
│   └── sanity-smoke.mp4          # Small test video (~100KB)
└── test-results/                 # Playwright artifacts (gitignored)

packages/ci-scripts/
└── src/
    └── cleanup-e2e-session.ts    # Fallback cleanup script

CI/CD Integration

Workflow Outputs

JobOutputUsed By
deploy-stagingbvf_url, library_urle2e-smoke-test
e2e-smoke-testresult: success|failuredeploy-production, rollback-staging

Environment Configuration

Staging-Only Features

FeatureFlag/CheckPurpose
Upload mode in BVF?uploadMode=true + env checkEnable file upload for CI
Test flows visibleDEPLOYMENT_ENVIRONMENT !== 'prod'Expose sanity-smoke flow
Cleanup endpointDEPLOYMENT_ENVIRONMENT === 'staging'Allow test data deletion

Secrets Required in GitHub

# .github/workflows/e2e-smoke-test.yml
env:
  BVF_STAGING_URL: ${{ secrets.BVF_STAGING_URL }}
  LIBRARY_STAGING_URL: ${{ secrets.LIBRARY_STAGING_URL }}
  CLERK_SECRET_KEY: ${{ secrets.E2E_CLERK_SECRET_KEY }}
  E2E_TEST_USER_ID: ${{ secrets.E2E_TEST_USER_ID }}
  E2E_TEST_ORG_ID: ${{ secrets.E2E_TEST_ORG_ID }}
  VERCEL_AUTOMATION_BYPASS_SECRET: ${{ secrets.VERCEL_AUTOMATION_BYPASS_SECRET }}

Error Handling & Artifacts

On Failure

  1. Screenshot: Captured at failure point
  2. HTML snapshot: DOM state preserved
  3. Video recording: Full test session video
  4. Trace file: Playwright trace for debugging
  5. Correlation ID: Links to app logs (if implemented)

Artifact Retention

  • Pass: Artifacts deleted after 1 day
  • Fail: Artifacts retained for 7 days

Monitoring & Alerts

Test Metrics

MetricTargetAlert Threshold
Test duration< 3 min> 5 min
Success rate> 99%< 95% over 7 days
Flake rate< 2%> 5% over 7 days

On Repeated Failures

  1. First failure: Retry (built into Playwright config)
  2. Second failure: Mark as failed, upload artifacts
  3. Third consecutive failure: Alert team via Slack webhook

Key Files Reference

FilePurpose
tests/e2e/playwright.config.tsPlaywright configuration
tests/e2e/specs/smoke.spec.tsMain smoke test spec
tests/e2e/fixtures/auth.tsClerk authentication fixture
.github/workflows/e2e-smoke-test.ymlCI workflow
.github/workflows/deployment-pipeline.ymlMain pipeline (calls e2e)
apps/branded-video-flow/app/api/info/route.tsDeployment version endpoint
apps/library/app/api/info/route.tsDeployment version endpoint

Related Documentation