Skip to main content

E2E Test Plan: Drop — Fintech Payment App

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 testE2E plan — all3 MVPPlaywright modulesprojects (user-flows, full-flows, input-chaos)

1. TestE2E Testing Objectives

This test plan covers testing for Drop MVP + Phase 0.5 Security Hardening (v0.5.0).

Primary objectives:Objectives:

  1. VerifyValidate that allthe authentication5 andmost onboardingcritical flowsDrop (registration,user OTP, PIN, login)journeys work correctlyend-to-end foron Norwegian residents (age ≥ 18, phone +47)staging
  2. VerifyCatch thatintegration remittancefailures transactionsbetween applyNext.js correctfrontend, 0.5%API feeroutes, acrossSQLite allDB, 6 NOK corridors withand mock BaaS that unit/integration tests cannot detect
  3. VerifyProvide thatconfidence QRbefore paymentsevery applyproduction correctdeployment 1%via merchantpost-staging feedeploy with mock BaaSgate
  4. ConfirmServe theas pass-throughliving modeldocumentation invariant:of Drop NEVER storescritical user balances or full card data
  5. Confirm Phase 0.5 security hardening: bcrypt 12 rounds, persistent rate limiting, CSRF, security headers, audit logging
  6. Validate performance under expected load (40+ concurrent users; target 200flows for PhaseCEO 1)UAT

OutWhat 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 scopetruth: formockups/figma-make-export/)
  • this plan: BankID SCA (Phase 2), real BaaS payments (Phase 2), real Sumsub KYC (Phase 2), Cards feature (Phase 3), mobile native app (Phase 2).


2. FeaturesCritical UnderUser TestJourneys

Journey 1: User Registration — 3-Step Onboarding

FeatureFieldValue
PriorityCritical
Business ImpactCore user acquisition — no registration = no users
FrequencyEvery new user (one-time)
Test Filesrc/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

FieldValue
PriorityCritical
Business ImpactCore returning user flow — no login = no revenue
FrequencyEvery user, every session
Test Filesrc/drop-app/__tests__/e2e/user-flows.spec.ts

Steps:

  1. Navigate to /login
  2. Story
  3. Enter valid email and password
  4. Submit
  5. Redirected to dashboard
  6. Bank balance shown (from mock AISP)
  7. 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

FieldValue
PriorityCritical
Business ImpactCore revenue — 0.5% fee per transaction
FrequencyMultiple times per month per user
Test Filesrc/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

FieldValue
PriorityCritical
Business ImpactCore QR revenue — 1% merchant fee
FrequencyMultiple times per week per merchant
Test Filesrc/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

FieldValue
PriorityHigh
Business ImpactMerchant onboarding — enables QR revenue
FrequencyOne-time per merchant
Test Filesrc/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

+ Validator+ Validator + Validator 20+edge
Journey Priority TestEst. TypesDuration OwnerAutomatedPlaywright Project
User Registration (3-step (FR-001)step) Critical Unit, Integration, E2E~30s BuilderYes user-flows
User Login (FR-002)+ Dashboard Critical Unit, Integration, E2E~15s BuilderYes user-flows
Remittance Transaction (FR-020)NOK→RSD Critical Unit, Integration, E2E~30s Builder + Validator
Exchange Rates API (FR-021)Yes HighIntegrationBuilder + Validatorfull-flows
QR Payment — Consumer (FR-030) Critical Unit, Integration, E2E~25s BuilderYes full-flows
Merchant Registration + QR (FR-031) High Unit, Integration~20s Builder + Validator
Rate Limiting (NFR-SEC05)Yes CriticalIntegrationBuilder + Validatorfull-flows
Input Validation / SecurityChaos (NFR-SEC06) Critical Unit, E2E (input-chaos)Builder + Validator
DB Compliance — No Balance/CVV (NF-AC-020/021)CriticalIntegration (db.test.ts)Builder + Validator
bcrypt Hashing (NFR-SEC02)CriticalUnit (auth.test.ts)Builder + Validator
Performance Benchmarks (NFR-P01..P06)cases) High Performance (api-benchmarks)~60s Builder + Validator
Feature Flags (FR-090)Yes MediumUnit (feature-flags.test.ts)Builder + Validatorinput-chaos

3. ScopeBrowser & Device Matrix

InDesktop Scope

  • Authentication module: registration, OTP verification, PIN setup, login, logout, /api/auth/me
  • Remittance module: POST /api/transactions/remittance, GET /api/transactions, exchange rates
  • QR payments module: POST /api/transactions/qr-payment, POST /api/merchants, GET /api/merchants/me
  • Security middleware: rate limiting, CSRF, JWT validation, security headers
  • Database compliance: schema assertions (no balance, no card_number, no cvv), FK constraints, transaction type enum
  • Performance benchmarks: bcrypt timing, DB query latency, concurrent rate limit check throughput
  • Regression testing of all 26 API routes
  • Input validation: XSS, SQL injection, boundary ages, Unicode names, long passwords

Out of ScopeBrowsers

implemented
ItemBrowser JustificationVersionOSPriorityNotes
BankID SCA integrationChrome PhaseLatest 2stable macOS, notLinux yet(CI) CriticalPrimary test browser in Playwright CI
Real BaaS PISP/AISP paymentsSafari PhaseLatest 2stablemacOSHighWebKit enginemockrequired modefor only in MVP
Real Sumsub KYC webhooksPhase 2 — auto-approved in MVP
Cards featurePhase 3 — feature-flagged OFF
Mobile native appPhase 2 — web only in MVP
Load testing > 200 concurrentNorwegian users Phaseon 1 migration to PostgreSQL required firstMac

Mobile

4. Test Schedule & Milestones

Browsers (AIDirector) mobile
MilestoneBrowser DatePlatform ResponsibleVersionPriorityNotes
Test plan approvedSafari 2026-02-23iOS JohnLatest Critical Primary Drop platform — iPhone SE to iPhone Pro Max
Test environment ready (staging)Chrome Before Phase 0.5 releaseAndroid John (DevOps)
Test data seededLatest Before E2E runHigh BuilderSecondary agent
Unit + integration tests completePer PR (CI automated)Builder agent
Playwright E2E authoring completeBefore Phase 0.5 releaseBuilder agent
Regression testing complete (all 26 routes)Before Phase 0.5 releaseValidator agent
Performance benchmarks runBefore Phase 0.5 releaseBuilder agent
UAT start (CEO walkthrough)TBD — before Phase 1 launchJohn
UAT sign-offTBDAlem Bašić (CEO)
Go/no-go decisionBefore Phase 1 launchAlem Bašić (CEO)
Production releasePhase 1 (BaaS partner confirmed)John (AI Director)platform

Screen

5.Resolutions Resource(configured Allocation

in playwright.config.ts) Owner admin
ResourceCategory RoleResolution TestingTest ActivitiesPriority AvailabilityNotes
BuilderMobile AgentS (ClaudeiPhone Sonnet)SE) Developer / QA375×667 Unit + integration + E2E authoringCritical PerDrop taskprimary target device
ValidatorMobile AgentL (ClaudeiPhone Sonnet,14 read-only)Pro) QA Lead428×926 Code review + test verificationCritical PerDrop taskprimary target device
John (AI Director)Tablet Tech Lead768×1024 Test strategy, UAT coordinationMedium ContinuousSecondary
Alem Bašić (CEO)Desktop Product1280×800 MediumFallback / UAT CEO UAT walkthroughTBDuse

6. Entry Criteria

Testing may begin when:

  •  Feature development is code-complete (all ticketsMatrix in "ReadyCI: forChromium QA")
  • +
  •  Unit tests passingWebKit (mobile 100%viewports pass375px rateand 428px) on unitevery + integration suite)
  •  Build artifact deployed to staging (https://drop-staging.fly.dev/)
  •  Staging environment is stable (health checks passing)
  •  Test data is seeded (npm run db:seed)
  •  Previous known blocking bugs resolved (Mission Control backlog reviewed)

7. Exit Criteria

Testing is complete when:

  •  All 14 test files execute cleanly
  •  ≥ 100% of unit + integration tests pass
  •  All Critical and High test cases in AC-001–AC-092 pass
  •  Code coverage ≥ 80% overall; 100% for auth + transaction paths
  •  All Playwright E2E tests passing on staging (user-flows, full-flows, input-chaos)
  •  Performance benchmarks meeting NFR-P01..P06 targets (api-benchmarks.test.ts green)
  •  DB compliance tests passing (db.test.ts: no balance, no card_number/cvv columns)
  •  UAT sign-off obtained from Alem Bašić (CEO) — or conditional approval documented
  •  Security audit score ≥ 80/100 (post Phase 0.5 hardening)

Exceptional circumstances: If exit criteria cannot be met, a documented risk acceptance from Alem Bašić (CEO) is required.deployment.


8.4. Test Data Setup & Teardown

Setup Strategy Summary Per Type

Test
Data Type ApproachMethod ToolOwnerGateScope
UnitConsumer account (KYC approved) White-boxPre-seeded in bcrypt,beforeAll JWT,via fee calc, validatorsAPI Vitest BuilderBlocks mergesuite
IntegrationMerchant account RealPre-seeded SQLitein test DB — 26 API routes, DB schemaVitestBuilderBlocks merge
E2ECritical journeys on staging — 3 Playwright projectsPlaywrightBuilderBlocks release
RegressionAll 26 routesbeforeAll via api-endpoints.test.tsAPIVitestBuilderBlocks merge
Performanceapi-benchmarks.test.ts — bcrypt timing, query latencyVitest benchBuilderWarning → release
Securitynpm audit + validation.test.ts + middleware.test.tsVitest + GitHub ActionsBuilderBlocks merge
DB compliancedb.test.ts — schema assertionsVitestBuilderBlocks merge
UATCEO business scenario walkthroughManualAlem BašićBlocks Phase 1 launch

9. Test Environment Requirements

EnvironmentPurposeURLAccess Needed
Local devUnit/integrationhttp://localhost:3000Builder agent
Staging (Fly.io, Stockholm)E2E, regression, UAThttps://drop-staging.fly.dev/Team + Alem
PerformanceBenchmarksLocal (api-benchmarks.test.ts)Builder agent

Environment requirements:

  • Staging must have NEXT_PUBLIC_SERVICE_MODE=mock (no real BaaS)
  • Staging SQLite DB seeded with synthetic test data (no real PII)
  • Monitoring enabled (Fly.io metrics)

10. Test Data Requirements

Pre-seeded
Data CategoryVolumeCreation MethodResponsible
Test consumer accounts3 (fresh, KYC-approved, KYC-pending)npm run db:seedBuilder agent
Test merchant accounts2 (registered, unregistered)npm run db:seedBuilder agentsuite
Test recipients (for remittance) 3 in npm run db:seedbeforeAll BuilderTest agentsuite
EdgeIsolated casefresh datauser (under-18,for duplicateregistration email, max amounts)tests) DefinedCreated pervia testAPI in beforeEach with unique email VitestIndividual fixturesBuilder agenttest

DataSeed cleanup:command: Allnpm run db:seed (populates staging SQLite with synthetic test data removed after test run via Vitest afterEach teardown. Staging DB reset between major test runs.data)


Teardown

11. Risk-Based Test Prioritization

Strategy
RiskCleanup AreaItem LikelihoodMethod ImpactPriorityMitigationTrigger
Pass-throughFresh modelusers violationcreated (Dropper stores balance)test LowDELETE via API CriticalP1db.test.ts always asserts no balance columnafterEach
AuthenticationTest bypasssession data LowClear browser storage CriticalP1Full auth.test.ts suite + middleware.test.tsafterEach
FeeTransactions calculationcreated errorduring (wrong percentage)test MediumArchive (not delete — audit trail) CriticalTest suite end

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

Test Accounts

0.5%Merchant
AccountEmailRolePurpose
Consumer (Amir) P1[email protected] UnitConsumer, testsKYC forapproved Standard andjourneys: 1%login, feeremittance, calculationsQR
Double-spendMerchant race condition(Ahmet) Low[email protected] CriticalMerchant P1 Transactiondashboard, lockQR integration testgeneration
RateFresh limiter reset on server restartuser Medium (was a bug)e2e-fresh-{timestamp}@test.alai.no HighNone P2Registration 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

StagingSQLitewith
RequirementSpecification
Environment middleware.test.tsStaging with persistent limiter(https://drop-staging.fly.dev/)
BaaS mock mode leaking to production configDatabase Low High P2 CIsynthetic checkseed fordata NEXT_PUBLIC_SERVICE_MODE env varonly
SQLiteExternal concurrent write limit reachedservices HighMock BaaS (atNEXT_PUBLIC_SERVICE_MODE=mock); ~200mock users)Sumsub
Stability MediumNo active deployments during E2E run (Fly.io deployment check)
Data persistence P3Isolated from manual testing during E2E run
Response times Phase< 1:5,000ms PostgreSQLfor migrationall 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/

CheckScopeTrigger
Dashboard screenshotDashboard screenPost-staging deploy
Send Money formRemittance formOn UI changes
QR Scan screenQR payment screenOn UI changes
Mobile 375px layoutAll critical screensOn 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

AssertionMetricThresholdJourney
Page loadTime to Interactive< 3,000msDashboard, Send Money
Core Web Vitals — LCPLargest Contentful Paint< 2,500msHomepage, Dashboard
API responseRemittance endpoint< 1,000msJourney 3
API responseLogin endpoint< 1,000msJourney 2
API responseExchange rates< 200msJourney 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:

ArtifactFormatWhen Collected
ScreenshotPNGOn step failure
Screen recordingWebM videoOn test failure
Network traceHAR fileOn test failure
Browser console logJSONOn test failure
Playwright trace.zip (Playwright trace viewer)On test failure

12. DependenciesMaintenance & AssumptionsStrategy

Dependencies:Page Object Pattern:

  • StagingAll environmentpage provisionedinteractions andwrapped accessiblein atlightweight https://drop-staging.fly.dev/Page Object classes
  • MockSelectors BaaS and Mock Sumsub configuredcentralized in staging environment variablestests/e2e/pages/
  • PlaywrightLocation: installed in CI (npx playwright installsrc/drop-app/__tests__/e2e/pages/)

Assumptions: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:

  • FeatureE2E requirementstests willupdated notin changesame duringPR as feature changes (tests are part of the testing phase without John (AI Director) reviewPR)
  • AllMonthly Builderreview: agent PRs includeremove tests alongsidefor codedeprecated features
  • ValidatorFigma-make-export agentchecked reviewsafter testevery filesUI before merge
  • BaaS partnership not confirmed — mock mode accepted for MVP/stagingchange

13. Defect Management Process

Bug tracker: Mission Control tasks + Slack #drop-bugs on alai-talk.slack.com Severity levels:

SeverityDefinitionResolution SLA
CriticalFinancial invariant broken; auth bypass; data lossFix before release — no exceptions
HighMajor feature broken; security finding; no workaroundFix before release
MediumFeature degraded; mock/workaround existsFix in next sprint
LowMinor issue, cosmeticBacklog

Bug lifecycle: Open → Assigned (Mission Control) → In Progress → Fixed → Verified by Validator → Closed Triage cadence: On each PR/commit (CI-driven); daily for active test phase


14. Test Deliverables

DeliverableFormatDue DateOwner
Test plan (this document)Markdown2026-02-23John (AI Director)
Test strategytest-strategy.md2026-02-23John
Test cases (automated)Vitest + Playwright test filesPer sprintBuilder agent
Test execution resultsVitest + Playwright CI reportsPer PRCI
Performance test reportapi-benchmarks.test.ts outputPer releaseBuilder agent
UAT sign-offuat-signoff.mdBefore Phase 1Alem Bašić
Test summary reportMarkdown (per release)Per releaseValidator agent


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