Playwright E2E Testing
End-to-end tests validate the client PWA and admin dashboard using Playwright, with fixtures for Anvil fork interaction and mock-based critical path testing.
How To Approach Tests
Playwright E2E tests verify complete user journeys through the browser — from page navigation to blockchain interaction. The philosophy is to keep E2E tests focused on critical paths, using mock-based CI variants for speed and Anvil fork variants for fidelity.
Test Directory Structure
Tests live in the tests/ directory at the monorepo root:
tests/
fixtures/ # Anvil fork, contract helpers, config
helpers/ # Shared test utilities
mocks/ # Pimlico bundler/paymaster mocks
specs/ # Test specifications
global-setup.ts # Pre-test environment bootstrap
global-teardown.ts
Test Projects
The config defines several Playwright projects for different testing scopes:
| Project | Matches | Purpose |
|---|---|---|
client-ci | client.smoke.spec.ts, client.*.ci.spec.ts | Client lane smoke and critical client specs |
admin-ci | admin.smoke.spec.ts, admin.production-flows.ci.spec.ts | Admin lane smoke and production-flow specs |
chromium | admin*.spec.ts | Manual admin dashboard tests |
chromium-client | client.smoke.spec.ts | Manual client smoke tests |
critical-path | *.ci.spec.ts | Manual mock-based critical UI flows |
performance | performance.spec.ts | Load time and resource checks |
anvil-fork | *.fork.spec.ts | Tests with local Anvil fork (60s timeout) |
passkey-mock | *.passkey.spec.ts | Passkey E2E with mocked Pimlico |
client-full | client*.spec.ts | Full client suite (optional) |
Mobile projects (mobile-chrome, mobile-safari) exist in the config, but the normal repo entry points use the explicit root scripts below rather than relying on those projects implicitly.
Web Server Configuration
Playwright config (playwright.config.ts) always starts the Envio indexer on port 8080 unless SKIP_WEBSERVER=true is set. App servers are selected with PLAYWRIGHT_APP: PLAYWRIGHT_APP=client starts the client on 3001, PLAYWRIGHT_APP=admin starts the admin on 3002, and an unset value starts both apps for broader local runs.
Completing Test Coverage
Spec Conventions
Spec files follow the naming pattern {package}.{feature}.spec.ts:
client.navigation.spec.ts-- Client routing and page transitionsclient.work-submission.spec.ts-- Full work submission flowadmin.auth.spec.ts-- Admin authentication and role checksclient.offline-sync.spec.ts-- Offline-first behavior and sync
CI-specific variants (*.ci.spec.ts) use lightweight mocks instead of real infrastructure, enabling faster and more reliable CI runs.
Test Fixtures
Anvil Fork Fixture
The anvil-fork.ts fixture spawns a local Anvil process forking from Sepolia, providing:
testClient-- Anvil manipulation (mine blocks, set balances, impersonate)publicClient-- Read operations against forked statewalletClient-- Write operations with test accounts
const context = await startAnvilFork();
try {
await context.testClient.setBalance({
address: TEST_ACCOUNTS.gardener1.address,
value: parseEther('100'),
});
// ... test blockchain interactions
} finally {
await context.cleanup();
}
Contract Helpers
The contract-helpers.ts fixture provides deployment artifact types and utility functions for interacting with deployed contracts during E2E tests. It reads addresses from packages/contracts/deployments/{chainId}-latest.json.
Running Tests
# Standard local wrapper
bun run test:e2e
# Smoke suite
bun run test:e2e:smoke
# Fork / passkey / testnet variants
bun run test:e2e:fork
bun run test:e2e:passkey
bun run test:e2e:testnet
# Direct Playwright usage when you want a specific project or file
npx playwright test --project=client-ci
npx playwright test --project=admin-ci
npx playwright test tests/specs/client.navigation.spec.ts
npx playwright test --ui
The bun run test:e2e wrapper starts bun run dev, waits for the client and admin surfaces to become reachable, then runs npx playwright test with SKIP_WEBSERVER=true and SKIP_HEALTH_CHECK=true.
Configuration Details
Key settings from playwright.config.ts:
- Retries: 1 locally, 2 in CI
- Workers: 4 locally, 2 in CI
- Traces: Captured on first retry
- Video: Retained on failure (local only)
- Screenshots: Only on failure
- Timeouts: 30s navigation, 15s actions; fork tests get 60s, testnet gets 120s
The global setup (global-setup.ts) bootstraps the test environment, and global-teardown.ts handles cleanup. Both use ESM-compatible imports.
Resources
- Playwright Documentation -- Official Playwright docs
- Playwright Test API -- Test API reference
- Test specs:
tests/specs/ - Test fixtures:
tests/fixtures/ - Playwright config:
playwright.config.ts
Next page
Next: Vitest Unit Testing
Learn how to write unit and integration tests for TypeScript packages with Vitest.
Vitest Unit Testing