Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
120 commits
Select commit Hold shift + click to select a range
2a9ca85
feat: Card Pioneers waitlist frontend implementation
Hugo0 Jan 29, 2026
4f191ce
fix: update CardDetailsScreen to handle purchase flow
Hugo0 Jan 29, 2026
d8a3a5c
fix: add missing heading prop to FAQsPanel in CardLandingPage
Hugo0 Jan 29, 2026
64568f2
fix: handle null username in useWebSocket call
Hugo0 Jan 29, 2026
a22d2fd
fix(card): fix E2E tests and update Card Pioneers feature
Hugo0 Feb 2, 2026
aca7ae5
Merge branch 'peanut-wallet-dev' into card-pioneers-frontend
Hugo0 Feb 2, 2026
43bc336
fix(card): address CodeRabbit review issues
Hugo0 Feb 2, 2026
03e83cd
feat(card): add backwards compat redirect and clean POST proxy
Hugo0 Feb 2, 2026
0681612
refactor: remove body mutation from proxy, delete redundant /post proxy
Hugo0 Feb 2, 2026
c29911d
fix: CardPioneerModal props and re-enable dismissal logic
Hugo0 Feb 2, 2026
b60dde1
fix: resolve TypeScript errors for PR build
Hugo0 Feb 2, 2026
08f4077
ci: add submodules checkout for animations
Hugo0 Feb 2, 2026
e2aa2da
fix(tests): update E2E tests to match /setup redirect behavior
Hugo0 Feb 2, 2026
e5c7bf7
last fixess gn
Hugo0 Feb 2, 2026
068c1a7
fix(tests): use waitForURL for client-side auth redirects
Hugo0 Feb 2, 2026
239b200
refactor: reuse logout logic in BackendErrorScreen
Hugo0 Feb 2, 2026
a6f7481
fix: remove duplicate error display in UserDetailsForm
jjramirezn Feb 4, 2026
4291152
Merge pull request #1666 from peanutprotocol/fix/double-error-display
jjramirezn Feb 4, 2026
7facbf3
feat: add third-party deposit warning to Manteca deposit details
jjramirezn Feb 4, 2026
d77432b
Merge pull request #1667 from peanutprotocol/feat/manteca-deposit-war…
jjramirezn Feb 4, 2026
1febb51
feat: enable coral v2
jjramirezn Feb 5, 2026
be20aca
fix: squidId
jjramirezn Feb 5, 2026
2db941b
temp
Hugo0 Feb 5, 2026
a0fe99b
fix: squid quote id status
jjramirezn Feb 5, 2026
032be22
fix: sentry filters all configs
jjramirezn Feb 5, 2026
da99e4a
Merge pull request #1670 from peanutprotocol/fix/sentry-filters-all-c…
jjramirezn Feb 5, 2026
7cb2b11
fix: better sentry
jjramirezn Feb 5, 2026
60ca8fa
fix: ignore vercel analytics errors
jjramirezn Feb 5, 2026
b96bfe7
fix: prettier
jjramirezn Feb 5, 2026
48e1fa0
Merge pull request #1671 from peanutprotocol/fix/sentry-filters-all-c…
jjramirezn Feb 5, 2026
5fc2004
Merge pull request #1669 from peanutprotocol/feat/squid-quote-id-status
jjramirezn Feb 9, 2026
5f81ad9
feature flag to disable card pioneers waitlist
Hugo0 Feb 10, 2026
2286a68
merge peanut-wallet-dev, resolve conflicts
Hugo0 Feb 10, 2026
c10ced6
fix: wrap logoutUser in arrow fn to fix TypeScript onClick type mismatch
Hugo0 Feb 10, 2026
64bd916
re-enable card
Hugo0 Feb 10, 2026
ddf553d
🐛 QA fixes: design system alignment, layout centering, modal priority…
Hugo0 Feb 12, 2026
78ed529
🐛 fix: prettier formatting
Hugo0 Feb 12, 2026
505c00a
📚 add pre-push checklist to .cursorrules
Hugo0 Feb 12, 2026
4ad9eba
🐛 address CodeRabbit review: security, cleanup, card interaction fixes
Hugo0 Feb 12, 2026
6830d7f
✨ allow all /dev routes on staging, block on peanut.me only
Hugo0 Feb 12, 2026
8b9fce7
🐛 fix ActionModal prop name in dev showcase, add typecheck script
Hugo0 Feb 12, 2026
4139dee
🐛 fix dev route guard for Vercel previews, fix 404 page layout and na…
Hugo0 Feb 12, 2026
2a66155
feat: sumsub sdk types and declrations
kushagrasarathe Feb 13, 2026
b7a4141
feat: initiateSumsubKyc server action
kushagrasarathe Feb 13, 2026
0dd89d3
feat: useSumsubKycFlow hook setup using initiateSumsubKyc server action
kushagrasarathe Feb 13, 2026
2c2bf14
feat: handle websocket event receiving for sumsub kyc
kushagrasarathe Feb 13, 2026
27ea649
feat: SumsubKycWrapper component to handle sumsub web sdk intializati…
kushagrasarathe Feb 13, 2026
1fa243f
feat: SumsubKycFlow entry point for sumsub kyc wrapper and pending st…
kushagrasarathe Feb 13, 2026
61bd07e
fix: update verification view ux copy + add region intent type
kushagrasarathe Feb 13, 2026
2d79044
chore: fix formatting
kushagrasarathe Feb 13, 2026
030986f
✨ QA polish: credit card icon, geo screen shadow, card crossfade, git…
Hugo0 Feb 16, 2026
6c13368
Merge pull request #1654 from peanutprotocol/card-pioneers-frontend
Hugo0 Feb 16, 2026
e3c9bd8
feat: add sumsub provider to kyc types and shared status consts
kushagrasarathe Feb 16, 2026
b2b90e1
feat: unified kyc status hook
kushagrasarathe Feb 16, 2026
a3316cc
fix: sumsub flow, regionIntent and levelName resolution
kushagrasarathe Feb 16, 2026
6b8f838
feat: sumsub region routing
kushagrasarathe Feb 16, 2026
3188926
feat: unified kyc status drawer
kushagrasarathe Feb 16, 2026
4fb61d4
feat: sumsub kyc gate for qr payments
kushagrasarathe Feb 16, 2026
6d390ad
feat: update views for sumsub flow
kushagrasarathe Feb 16, 2026
ec0d1e9
chore: remove dead code
kushagrasarathe Feb 16, 2026
22fa6b7
Merge branch 'peanut-wallet-dev' into feat/kyc2.0
kushagrasarathe Feb 16, 2026
d0b2764
chore: format
kushagrasarathe Feb 16, 2026
e9715af
fix: address cr review comments
kushagrasarathe Feb 17, 2026
7297b9b
fix: remove levelName param and use regionIntent
kushagrasarathe Feb 17, 2026
b564cb9
fix: reuse exiting start kyc modal and fix its copy
kushagrasarathe Feb 17, 2026
9bf32ae
fix: new cr comments
kushagrasarathe Feb 17, 2026
a8ddab2
fix: more cr comments xD
kushagrasarathe Feb 17, 2026
c7f377c
Merge peanut-wallet (production) into peanut-wallet-dev
Hugo0 Feb 17, 2026
71fe5d3
fix: kernel client ready state + transaction query key bug
Hugo0 Feb 17, 2026
f24d698
Add retry logic before kernel client logout
Hugo0 Feb 17, 2026
79e5c6f
Move state updates after primary client check to prevent UI flicker
Hugo0 Feb 17, 2026
0d48306
Merge pull request #1681 from peanutprotocol/merge/production-sync-130
Hugo0 Feb 17, 2026
3d786b4
✏️ update cashback tooltip and fix comment path
Hugo0 Feb 18, 2026
70c98dd
chore: disable Card Pioneers waitlist
Hugo0 Feb 18, 2026
c06a550
cashback fixes
Hugo0 Feb 18, 2026
cb49019
fix: add shadow to share invite buttons on points page
Hugo0 Feb 18, 2026
111faa3
fix: hide My Card menu item in profile when card pioneers is disabled
Hugo0 Feb 18, 2026
9fbb5d8
feat: add UserRail types, rejectType and metadata to kyc verification…
kushagrasarathe Feb 18, 2026
60e9dc9
feat: add action_required status category and human-readable sumsub r…
kushagrasarathe Feb 18, 2026
fe5f07d
feat: scope region unlocking by verification regionIntent, expose act…
kushagrasarathe Feb 18, 2026
ea64d17
feat: handle sumsub_kyc_status_update websocket messages
kushagrasarathe Feb 18, 2026
7ed541a
feat: add bridge tos acceptance flow: tos step component, reminder ca…
kushagrasarathe Feb 18, 2026
235724f
feat: handle bridge tos acceptance
kushagrasarathe Feb 18, 2026
9e996b0
fix: listen to additional sumsub sdk methods
kushagrasarathe Feb 19, 2026
250cea8
feat: listen to user rail websocket events
kushagrasarathe Feb 19, 2026
40d222f
fix: move PeanutDoesntStoreAnyPersonalInformation out to a separate c…
kushagrasarathe Feb 19, 2026
2f892cb
feat: add useRailStatusTracking hook
kushagrasarathe Feb 19, 2026
f58ad8d
fix: update SumsubKycFlow and KycVerificationInProgressModal to handl…
kushagrasarathe Feb 19, 2026
8c64be9
feat: add isTerminalRejection utility and sumsubRejectType to unified…
kushagrasarathe Feb 20, 2026
302df7b
refactor: extract shared rejectlabelslist component and simplify draw…
kushagrasarathe Feb 20, 2026
8e5ab8b
fix: handle kyc status transitions for non-success terminal states
kushagrasarathe Feb 20, 2026
2bc70ba
feat: add status-aware modals for regions verification page
kushagrasarathe Feb 20, 2026
1170822
fix: re-submit verification flow and stop verification button in kyc …
kushagrasarathe Feb 20, 2026
546bfe1
feat: add support for GBP(sort-code) based bridge on/off-ramps
kushagrasarathe Feb 23, 2026
21d672a
fix: tests, gbp ex. rate and min withdraw check
kushagrasarathe Feb 23, 2026
bb407e8
fix: cr comments
kushagrasarathe Feb 23, 2026
bebaeef
fix: gate terminal rejection logic by provider and log tos retry failure
kushagrasarathe Feb 23, 2026
05029c0
docs: update kyc 2.0 testing guide with all implemented test cases
kushagrasarathe Feb 23, 2026
3c62aef
fix: remove kyc testing guide
kushagrasarathe Feb 23, 2026
4cda4bb
feat: bridge additional document collection UI
kushagrasarathe Feb 24, 2026
91d7b1f
chore: format
kushagrasarathe Feb 24, 2026
bcb698c
fix: address code review findings
kushagrasarathe Feb 24, 2026
10f5ee5
fix: aggregate additional requirements across all rails, guard termin…
kushagrasarathe Feb 24, 2026
7f7c8be
Merge pull request #1688 from peanutprotocol/feat/bridge-gbp
kushagrasarathe Feb 24, 2026
1b4a9e7
fix: label copy
kushagrasarathe Feb 24, 2026
3c929c2
Merge pull request #1689 from peanutprotocol/feat/kyc2.0-provider-res…
kushagrasarathe Feb 24, 2026
908e38d
Merge pull request #1683 from peanutprotocol/feat/kyc2.0-error-retry-ui
kushagrasarathe Feb 24, 2026
c214dc2
Merge pull request #1679 from peanutprotocol/feat/kyc2.0
kushagrasarathe Feb 24, 2026
58df746
refactor: unify all KYC flows through Sumsub via useMultiPhaseKycFlow
kushagrasarathe Feb 25, 2026
e8a9769
chore: format
kushagrasarathe Feb 25, 2026
47b2661
fix: skip intermediate modal in bridge ToS flow from home page
kushagrasarathe Feb 25, 2026
9af38d1
🐛 fix: show confirmation modal before KYC and prevent backend record …
kushagrasarathe Feb 25, 2026
fd28c3b
chore: format
kushagrasarathe Feb 25, 2026
753b695
🐛 fix: remove pre-KYC name/email collection — now handled by Sumsub SDK
kushagrasarathe Feb 25, 2026
aedabec
🗑️ chore: delete unused UserDetailsForm component
kushagrasarathe Feb 25, 2026
c463dbe
🐛 fix: bridge ToS persistence + consolidate KYC activity by region
kushagrasarathe Feb 25, 2026
045aed9
chore: format
kushagrasarathe Feb 25, 2026
5767b54
fix: qa bugs
kushagrasarathe Feb 25, 2026
0cba1de
fix: auto close drawer bug + activity drawer ui
kushagrasarathe Feb 25, 2026
4587440
Merge pull request #1690 from peanutprotocol/fix/kyc2.0-bugs
kushagrasarathe Feb 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .cursorrules
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
- **Do not generate .md files** unless explicity told to do so.
- **Comments** should always be made in all lowercase and simple english
- **Error messages**, any error being shown in the ui should be user friendly and easy to understand, and any error being logged in consoles and sentry should be descriptive for developers to help with debugging
- **Never add AI co-author to commits** - do not add "Co-Authored-By" lines for AI assistants in git commits

## 💻 Code Quality

Expand Down Expand Up @@ -78,6 +79,57 @@
- **Service Worker cache version** - only bump `NEXT_PUBLIC_API_VERSION` for breaking API changes (see JSDoc in `src/app/sw.ts`). Users auto-migrate.
- **Gate heavy features in dev** - prefetching, precompiling, or eager loading of routes can add 5-10s to dev cold starts. wrap with `process.env.NODE_ENV !== 'development'` (e.g. `<link rel="prefetch" href="/qr-pay" />` in layout.tsx).

## 🎨 Design System

- **Live showcase**: visit `/dev/components` to see all components rendered with all variants and copy-paste code
- **Three layers**: Bruddle primitives (`src/components/0_Bruddle/`), Global shared components (`src/components/Global/`), and Tailwind custom classes (`tailwind.config.js`)

### Bruddle Primitives (`0_Bruddle/`)
- Button, Card (named export), BaseInput, BaseSelect, Checkbox, Divider, Title, Toast, PageContainer, CloudsBackground

### Global Shared Components (`Global/`)
- **Navigation**: NavHeader (back button + title), TopNavbar, Footer
- **Modals**: Modal (base @headlessui Dialog), ActionModal (with buttons/checkboxes/icons), Drawer (vaul bottom sheet)
- **Loading**: Loading (spinner), PeanutLoading (branded), PeanutFactsLoading (with fun facts)
- **Cards**: Card (with position prop for stacked lists), InfoCard, PeanutActionCard
- **Status**: StatusPill, StatusBadge, ErrorAlert, ProgressBar
- **Icons**: Icon component with 50+ icons — `<Icon name="check" size={20} />`
- **Inputs**: AmountInput, ValidatedInput, CopyField, GeneralRecipientInput, TokenSelector
- **Utilities**: CopyToClipboard, AddressLink, ExternalWalletButton, ShareButton, Banner, MarqueeWrapper

### Color Names (misleading!)
- `purple-1` / `primary-1` = `#FF90E8` (pink, not purple)
- `primary-3` = `#EFE4FF` (lavender)
- `yellow-1` / `secondary-1` = `#FFC900`
- `green-1` = `#98E9AB`

### Key Rules
- **Button sizing trap**: `size="large"` is `h-10` (40px) — SHORTER than default `h-13` (52px). never use for primary CTAs
- **Primary CTA**: `<Button variant="purple" shadowSize="4" className="w-full">` — no size prop
- **Secondary CTA**: `<Button variant="stroke" className="w-full">`
- **Shadows**: always black `#000000`. use `shadowSize="4"` for action buttons
- **Border radius**: always `rounded-sm` (not rounded-lg or rounded-md)
- **Border stroke**: `border border-n-1` (1px black)
- **Links**: `text-black underline` — never `text-purple-1` (pink)
- **Text hierarchy**: `text-n-1` primary, `text-grey-1` secondary
- **Two Card components**: `0_Bruddle/Card` (standalone containers, named export) vs `Global/Card` (stacked list items, default export)
- **Backgrounds**: `bg-peanut-repeat-normal` for waving peanut pattern
- **Messaging**: use "starter balance" for card deposits — never "card balance" or "Peanut rewards"

### Page Layouts

- **Outer shell**: `flex min-h-[inherit] flex-col gap-8` — NavHeader is first child
- **Centered content + CTA** (default): wrap content AND CTA in `<div className="my-auto flex flex-col gap-6">`. CTA must be INSIDE this div, never a sibling
- **Pinned footer CTA**: add `justify-between` to outer div, CTA as last child outside content
- **Never** use `space-y-*` on the outer flex div (conflicts with centering) — use `gap-*` instead

## ✅ Before Pushing

- **Format**: `pnpm prettier --write <changed-files>` then verify with `pnpm prettier --check .`
- **Typecheck**: `npm run typecheck` — catches type errors that tests miss (tests don't run tsc)
- **Test**: `npm test` (fast, ~5s) — all 17 suites must pass
- **Build** (if touching imports/types): `npm run build` to catch compile errors

## 📝 Commits

- **Be descriptive**
Expand Down
17 changes: 16 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true

- uses: actions/setup-node@v4
with:
Expand All @@ -24,11 +26,24 @@ jobs:
- name: Check formatting
run: pnpm prettier --check .

- name: Run Tests
- name: Run Unit Tests
run: pnpm test

- name: Install Playwright Browsers
run: npx playwright install --with-deps chromium

- name: Run E2E Tests
run: pnpm test:e2e

- name: Upload Coverage
uses: actions/upload-artifact@v4
with:
name: coverage
path: coverage/

- name: Upload Playwright Report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-report
path: playwright-report/
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ PR.md

# testing
/coverage
/test-results/
/playwright-report/
/playwright/.cache/

# next.js
/.next/
Expand Down Expand Up @@ -70,3 +73,6 @@ public/sw*
public/swe-worker*

.idea

# mobile POC
android/
170 changes: 170 additions & 0 deletions docs/TESTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
# Testing Philosophy

## Overview

peanut-ui uses a focused testing strategy that prioritizes **high-value tests** over coverage theater. We test critical paths that catch real bugs, not to hit arbitrary coverage percentages.

## Test Types

### 1. Unit Tests (Jest)

**Location**: Tests live with the code they test (e.g. `src/utils/foo.test.ts`)

**What we test**:
- Pure business logic (calculations, validations, transformations)
- Complex utility functions
- Critical algorithms (e.g. point calculations, country eligibility)

**What we DON'T test**:
- React components (brittle, low ROI)
- API service wrappers (thin fetch calls)
- Hooks that just wrap react-query (already tested upstream)
- JSX/UI layout (visual QA better)

**Run tests**:
- `npm test` - Run all unit tests
- `npm run test:watch` - Run tests in watch mode

### 2. E2E Tests (Playwright)

**Location**: Tests live with features they test (e.g. `src/features/card-pioneer/card-pioneer.e2e.test.ts`)

**What we test**:
- ✅ Multi-step navigation flows
- ✅ Form validation and error states
- ✅ URL state management (nuqs integration)
- ✅ Auth flows (signup, login, logout)
- ✅ UI interactions without external dependencies

**What we DON'T test**:
- ❌ Payment flows (require real transactions)
- ❌ KYC flows (external API dependencies)
- ❌ Bank transfers (real money, manual QA required)
- ❌ Wallet connections (MetaMask/WalletConnect popups)

**Why this split?**
External dependencies (payments, KYC, banks) are better tested manually because:
1. They require real credentials and real money
2. They have complex state (KYC approval status, bank account verification)
3. They involve third-party UIs (wallet popups, bank OAuth)
4. Manual QA catches edge cases E2E can't simulate

**Run tests**:
- `npm run test:e2e` - Run all E2E tests (headless)
- `npm run test:e2e:headed` - Run with browser visible
- `npm run test:e2e:ui` - Run in interactive UI mode
- `npx playwright test --grep "Card Pioneer"` - Run specific test suite
- `npx playwright test --list` - List all tests without running

## Testing Principles

### 1. Test Critical Paths Only

Focus on code that:
- Has financial impact (payment calculations, point multipliers)
- Has legal requirements (sanctions compliance, geo restrictions)
- Has security implications (reference parsing, user ID extraction)
- Is complex or hard to verify manually (date logic, ISO code mappings)

### 2. Fast Tests

- Unit tests run in ~5s
- E2E tests focus on minimal, high-value flows
- No unnecessary setup/teardown
- Mock external APIs but keep mocks simple

### 3. Tests Live With Code

Per .cursorrules: tests live where the code they test is, not in a separate folder.

```
src/
utils/
geo.ts
geo.test.ts ← unit test
features/
card-pioneer/
card-pioneer.tsx
card-pioneer.e2e.test.ts ← e2e test
```

### 4. DRY in Tests

Reuse test utilities, shared fixtures, and helper functions. Less code is better code.

## Example Test Scenarios

### Unit Test Example

```typescript
// src/utils/country-codes.test.ts
describe('convertIso3ToIso2', () => {
it('should convert USA to US', () => {
expect(convertIso3ToIso2('USA')).toBe('US')
})

it('should handle sanctioned countries', () => {
expect(convertIso3ToIso2('CUB')).toBe('CU') // Cuba
expect(convertIso3ToIso2('VEN')).toBe('VE') // Venezuela
})
})
```

### E2E Test Example

```typescript
// src/features/card-pioneer/card-pioneer.e2e.test.ts
test('user can navigate card pioneer flow', async ({ page }) => {
await page.goto('/card-pioneer')

// step 1: info screen
await expect(page.getByRole('heading', { name: /card pioneer/i })).toBeVisible()
await page.getByRole('button', { name: /get started/i }).click()

// step 2: details screen (check URL state)
await expect(page).toHaveURL(/step=details/)
await page.getByRole('button', { name: /continue/i }).click()

// step 3: geo check
await expect(page).toHaveURL(/step=geo/)
})
```

## When to Add Tests

Add tests when:
1. Implementing new financial logic
2. Handling compliance requirements
3. Complex algorithms or data transformations
4. Bug fixes (regression tests)

Skip tests when:
1. Just rendering JSX
2. Thin wrappers around libraries
3. Purely visual changes
4. Code that's easier to verify manually

## CI Integration

- Unit tests run on every PR
- E2E tests run on PR to main
- Fail fast: first failure stops the build

## Maintenance

Keep tests:
- **Concise** - no verbose setup or comments
- **Focused** - one concern per test
- **Stable** - avoid flaky selectors or timing issues
- **Up-to-date** - delete tests for removed features

When tests fail:
1. Fix the bug (if test caught a real issue)
2. Update the test (if behavior intentionally changed)
3. Delete the test (if feature was removed)

## Resources

- Jest: https://jestjs.io/
- Playwright: https://playwright.dev/
- Testing Library: https://testing-library.com/ (for React unit tests if needed)
9 changes: 9 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@
"knip": "knip",
"format": "prettier --write .",
"analyze": "ANALYZE=true next build",
"typecheck": "tsc --noEmit",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:e2e": "playwright test",
"test:e2e:ui": "playwright test --ui",
"test:e2e:headed": "playwright test --headed",
"script": "NODE_OPTIONS=\"--experimental-json-modules\" tsx"
},
"dependencies": {
Expand Down Expand Up @@ -86,6 +90,7 @@
},
"devDependencies": {
"@next/bundle-analyzer": "^16.1.1",
"@playwright/test": "^1.58.0",
"@serwist/build": "^9.0.10",
"@size-limit/preset-app": "^11.2.0",
"@testing-library/jest-dom": "^6.4.2",
Expand Down Expand Up @@ -147,6 +152,10 @@
"**/__tests__/**/*.test.[jt]s?(x)",
"**/?(*.)+(spec|test).[jt]s?(x)"
],
"testPathIgnorePatterns": [
"/node_modules/",
"\\.e2e\\.test\\.(ts|tsx)$"
],
"extensionsToTreatAsEsm": [
".ts",
".tsx"
Expand Down
53 changes: 53 additions & 0 deletions playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { defineConfig, devices } from '@playwright/test'

/**
* Playwright E2E Test Configuration
*
* Testing philosophy:
* - Test navigation flows and UI logic without external dependencies
* - Do NOT test payment/KYC/bank flows (manual QA required)
* - Fast, reliable tests for core user journeys
*
* See docs/TESTING.md for full testing philosophy
*/
export default defineConfig({
// test directory lives with code (per .cursorrules)
testDir: './src',
testMatch: '**/*.e2e.test.ts',

// reasonable timeout for UI tests
timeout: 30 * 1000,

// fail fast in CI
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 0,
workers: process.env.CI ? 1 : undefined,

// clear, concise reporting
reporter: 'html',

use: {
// base url for tests
baseURL: 'http://localhost:3000',
trace: 'on-first-retry',
screenshot: 'only-on-failure',
},

// test against chromium only (simplest, fastest)
// can expand to firefox/webkit if cross-browser bugs emerge
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],

// start dev server before tests
webServer: {
command: 'npm run dev',
url: 'http://localhost:3000',
reuseExistingServer: !process.env.CI,
timeout: 120 * 1000, // 2 minutes for dev server startup
},
})
Loading
Loading