Skip to main content

E2E Test Plan

E2E Test Plan: Drop — Fintech Payment App

Project: Drop — Remittance + QR Payments Version: 1.0 Date: 2026-02-23 Author: John (AI Director) Status: Approved Reviewers: Alem Bašić (CEO)

Document History

Version Date Author Changes
0.1 2026-02-23 John Initial E2E plan — 3 Playwright projects (user-flows, full-flows, input-chaos)

1. E2E Testing Objectives

Objectives:

  1. Validate that the 5 most critical Drop user journeys work end-to-end on staging
  2. Catch integration failures between Next.js frontend, API routes, SQLite DB, and mock BaaS that unit/integration tests cannot detect
  3. Provide confidence before every production deployment via post-staging deploy gate
  4. Serve as living documentation of critical user flows for CEO UAT

What E2E tests are NOT for:

  • Complete feature coverage (handled by unit/integration tests — 40+ Vitest tests)
  • Testing every error state (too expensive to maintain; covered by input-chaos.spec.ts for validation)
  • Performance benchmarking (handled by api-benchmarks.test.ts)
  • Visual pixel-perfection (Figma source of truth: mockups/figma-make-export/)

2. Critical User Journeys

Journey 1: User Registration — 3-Step Onboarding

Field Value
Priority Critical
Business Impact Core user acquisition — no registration = no users
Frequency Every new user (one-time)
Test File src/drop-app/__tests__/e2e/user-flows.spec.ts

Steps:

  1. Navigate to https://drop-staging.fly.dev/
  2. Click "Registrer deg" — registration form opens
  3. Enter valid data: name (with Unicode: Amir Hasić), email, password ≥ 8 chars, Norwegian phone (+47), DOB ≥ 18 years
  4. Submit form — OTP sent to phone, OTP input shown
  5. Enter correct 6-digit OTP
  6. Enter and confirm 4-digit PIN
  7. Redirect to dashboard — account activated

Assertions:

  • 201 Created on registration (no password hash in response)
  • JWT httpOnly cookie set after PIN setup
  • Dashboard visible with user's name
  • Audit log entry created

Journey 2: User Login + Dashboard Access

Field Value
Priority Critical
Business Impact Core returning user flow — no login = no revenue
Frequency Every user, every session
Test File src/drop-app/__tests__/e2e/user-flows.spec.ts

Steps:

  1. Navigate to /login
  2. Enter valid email and password
  3. Submit
  4. Redirected to dashboard
  5. Bank balance shown (from mock AISP)
  6. Recent transactions visible

Assertions:

  • 200 on login; JWT cookie set; SameSite=Strict; httpOnly
  • GET /api/auth/me returns user object (no password hash)
  • Balance shown is from mock BaaS (not stored in Drop DB)

Journey 3: Remittance — NOK to RSD

Field Value
Priority Critical
Business Impact Core revenue — 0.5% fee per transaction
Frequency Multiple times per month per user
Test File src/drop-app/__tests__/e2e/full-flows.spec.ts

Steps:

  1. Log in as KYC-approved consumer
  2. Navigate to "Send penger" (Send Money)
  3. Select recipient; enter amount = 1,000 NOK; select currency = RSD
  4. Review: fee shown as 5 NOK (0.5%); exchange rate shown
  5. Confirm and submit
  6. Transaction created with status = completed
  7. Navigate to Transaction History — transaction visible

Assertions:

  • 201 Created; transaction in DB with fee = 5 NOK
  • Transaction history shows amount, fee, currency, status
  • No balance change in Drop DB (pass-through — balance read from mock AISP)

Journey 4: QR Payment — Scan + Pay

Field Value
Priority Critical
Business Impact Core QR revenue — 1% merchant fee
Frequency Multiple times per week per merchant
Test File src/drop-app/__tests__/e2e/full-flows.spec.ts

Steps:

  1. Log in as KYC-approved consumer
  2. Navigate to "Scan QR"
  3. Enter valid merchantId (pre-seeded merchant)
  4. Enter amount = 200 NOK
  5. Review: merchant_fee = 2 NOK (1%)
  6. Confirm payment
  7. Transaction created; visible in history

Assertions:

  • 201 Created; merchant_fee = 2 NOK; amount = 200 NOK
  • Transaction visible in consumer history
  • Mock PISP payment recorded

Journey 5: Merchant Registration + QR Generation

Field Value
Priority High
Business Impact Merchant onboarding — enables QR revenue
Frequency One-time per merchant
Test File src/drop-app/__tests__/e2e/full-flows.spec.ts

Steps:

  1. Log in as user (not yet a merchant)
  2. Navigate to "Bli Merchant" (Become Merchant)
  3. Enter business_name and bank_account
  4. Submit — merchant created with unique QR code value
  5. Navigate to merchant dashboard — QR code visible

Assertions:

  • 201 Created; merchant has unique qr_code_value
  • GET /api/merchants/me returns merchant details + QR code
  • QR code is unique (no two merchants share a code)

All Journeys Summary

Journey Priority Est. Duration Automated Playwright Project
User Registration (3-step) Critical ~30s Yes user-flows
User Login + Dashboard Critical ~15s Yes user-flows
Remittance NOK→RSD Critical ~30s Yes full-flows
QR Payment Critical ~25s Yes full-flows
Merchant Registration High ~20s Yes full-flows
Input Chaos (20+ edge cases) High ~60s Yes input-chaos

3. Browser & Device Matrix

Desktop Browsers

Browser Version OS Priority Notes
Chrome Latest stable macOS, Linux (CI) Critical Primary test browser in Playwright CI
Safari Latest stable macOS High WebKit engine — required for Norwegian users on Mac

Mobile Browsers

Browser Platform Version Priority Notes
Safari iOS Latest Critical Primary Drop platform — iPhone SE to iPhone Pro Max
Chrome Android Latest High Secondary mobile platform

Screen Resolutions (configured in playwright.config.ts)

Category Resolution Test Priority Notes
Mobile S (iPhone SE) 375×667 Critical Drop primary target device
Mobile L (iPhone 14 Pro) 428×926 Critical Drop primary target device
Tablet 768×1024 Medium Secondary
Desktop 1280×800 Medium Fallback / admin use

Matrix in CI: Chromium + WebKit (mobile viewports 375px and 428px) on every deployment.


4. Test Data Setup & Teardown

Setup Strategy

Data Type Method Scope
Consumer account (KYC approved) Pre-seeded in beforeAll via API Test suite
Merchant account Pre-seeded in beforeAll via API Test suite
Test recipients (for remittance) Pre-seeded in beforeAll Test suite
Isolated fresh user (for registration tests) Created via API in beforeEach with unique email Individual test

Seed command: npm run db:seed (populates staging SQLite with synthetic test data)

Teardown Strategy

Cleanup Item Method Trigger
Fresh users created per test DELETE via API afterEach
Test session data Clear browser storage afterEach
Transactions created during test Archive (not delete — audit trail) Test suite end

Rule: Tests must not leave state that affects other tests. Each test creates its own isolated data.

Test Accounts

Account Email Role Purpose
Consumer (Amir) [email protected] Consumer, KYC approved Standard journeys: login, remittance, QR
Merchant (Ahmet) [email protected] Merchant Merchant dashboard, QR generation
Fresh user e2e-fresh-{timestamp}@test.alai.no None Registration flow tests

Credentials stored in: Vaultwarden (vault.basicconsulting.no) → "Drop E2E Test Accounts"


5. Authentication Handling in Tests

Strategy: API-based auth — authenticate via POST /api/auth/login in beforeAll, save storage state, reuse for all tests in the suite. Only use UI login when testing the login flow itself.

// playwright.config.ts approach:
// 1. beforeAll: POST /api/auth/login → save JWT cookie to storage state
// 2. Each test that needs auth: restore storage state (< 1ms overhead)
// 3. Tests for login UI: always fresh (no saved state)

Session reuse:

  • Session state saved per role (consumer, merchant) after first auth
  • Reused for all tests requiring that role
  • JWT expires in 7 days — within test run duration

6. Test Environment Requirements

Requirement Specification
Environment Staging (https://drop-staging.fly.dev/)
Database Staging SQLite with synthetic seed data only
External services Mock BaaS (NEXT_PUBLIC_SERVICE_MODE=mock); mock Sumsub
Stability No active deployments during E2E run (Fly.io deployment check)
Data persistence Isolated from manual testing during E2E run
Response times < 5,000ms for all endpoints (Playwright default timeout)

Critical: E2E tests must NOT run against a production environment. Drop handles financial data — all E2E tests use mock BaaS exclusively.


7. Flaky Test Management Strategy

Definition: A test that fails inconsistently for the same code.

Prevention:

  • Use explicit waits: waitForResponse('/api/...') not page.waitForTimeout(1000)
  • Isolate test data — unique emails per test run (e2e-fresh-{Date.now()}@test.alai.no)
  • Use data-testid selectors — not CSS classes or text (can change with Norwegian/English toggle)
  • Disable animations in test env via prefers-reduced-motion

Detection:

  • Any test failing > 5% of runs without code changes = flaky
  • Playwright HTML report shows flaky tests in CI artifacts

Response:

  • Tag flaky test with test.fixme() annotation in Playwright
  • Create Mission Control task with P2 priority
  • Fix within 3 days or remove the test
  • Monthly flaky test review during sprint retrospective

8. Visual Regression Testing

Approach: Playwright screenshot comparisons on critical screens. Baseline: Stored in src/drop-app/__tests__/e2e/snapshots/ (committed to repo) Source of Truth: Figma Make export: mockups/figma-make-export/src/components/

Check Scope Trigger
Dashboard screenshot Dashboard screen Post-staging deploy
Send Money form Remittance form On UI changes
QR Scan screen QR payment screen On UI changes
Mobile 375px layout All critical screens On responsive changes

Review process: Screenshot diffs require Builder + Validator sign-off before merge. Figma is the source of truth — any diff vs Figma is a regression.


9. Performance Assertions Within E2E

Assertion Metric Threshold Journey
Page load Time to Interactive < 3,000ms Dashboard, Send Money
Core Web Vitals — LCP Largest Contentful Paint < 2,500ms Homepage, Dashboard
API response Remittance endpoint < 1,000ms Journey 3
API response Login endpoint < 1,000ms Journey 2
API response Exchange rates < 200ms Journey 3 (rates call)

10. CI Integration

Trigger: Post-staging deployment (GitHub Actions workflow: .github/workflows/e2e.yml)

Parallelization:

  • 3 Playwright projects run in parallel: user-flows, full-flows, input-chaos
  • 2 workers per project on CI (total: 6 parallel Playwright workers)
  • Estimated total time: < 10 minutes

CI configuration:

# .github/workflows/e2e.yml
# Key settings:
# - Projects: user-flows, full-flows, input-chaos
# - Retries: 1 (flaky detection; not masking failures)
# - Timeout per test: 30,000ms
# - Timeout total: 600,000ms (10 min)
# - Base URL: https://drop-staging.fly.dev/

On failure:

  • Collect screenshots, videos, Playwright traces as CI artifacts
  • Retain artifacts for 7 days
  • Alert Slack #drop-e2e-failures on alai-talk.slack.com
  • Block production deployment until fixed

11. Test Report Format & Artifacts

Report format: Playwright HTML report + JUnit XML for CI Report location: GitHub Actions CI artifacts (7-day retention)

Artifacts collected on failure:

Artifact Format When Collected
Screenshot PNG On step failure
Screen recording WebM video On test failure
Network trace HAR file On test failure
Browser console log JSON On test failure
Playwright trace .zip (Playwright trace viewer) On test failure

12. Maintenance Strategy

Page Object Pattern:

  • All page interactions wrapped in lightweight Page Object classes
  • Selectors centralized in tests/e2e/pages/
  • Location: src/drop-app/__tests__/e2e/pages/

Selector strategy (Drop-specific):

  1. data-testid attributes — preferred (e.g., data-testid="remittance-amount")
  2. ARIA roles + accessible name (e.g., getByRole('button', { name: 'Send penger' }))
  3. Text content — acceptable for stable Norwegian/English text
  4. CSS class names — avoid (Tailwind classes can change)
  5. XPath — never

Review cadence:

  • E2E tests updated in same PR as feature changes (tests are part of the PR)
  • Monthly review: remove tests for deprecated features
  • Figma-make-export checked after every UI change


Approval

Role Name Date Signature
Author John (AI Director) 2026-02-23 Approved (AI)
QA Lead Validator Agent 2026-02-23 Approved (AI)
AI Director (John) John 2026-02-23 Approved
CEO (Alem) Alem Bašić TBD