Bug fixes and features should always come with tests.
- Unit - test both frontend code in isolation
- Workflows - tools and libraries for GitHub Workflows or any DevOps processes
- act - Emulates GitHub Workflows virtual environment via Docker containers.
Separate the business logic from the view as much as possible. Create hooks, helpers & reducers to utilize this logic from the UI and test that code in isolation from its UI.
This is an example of how we structure our unit tests.
import mockAxios from 'axios'
import { isLoggedIn } from './isLoggedIn'
import { describe, it, expect } from 'vitest'
const UserData = { id: 1, name: 'UserName' }
const mockUserData = id => {
mockAxios.get.mockImplementationOnce(() => Promise.resolve(id ? data : undefined))
}
describe('isLoggedIn', () => {
describe('isLoggedIn', () => {
it('should return true when passed a userId', () => {
const userId = 1
mockUserData(userId)
expect(isLoggedIn(userId)).toBe(true)
})
it('should return false when userId is undefined', () => {
const userId = undefined
mockUserData(userId)
expect(isLoggedIn(userId)).toBe(false)
})
})
})This is an example of how we structure our hook tests.
import { renderHook } from '@testing-library/react'
import { useIsComponentMounted } from './useIsComponentMounted'
const setup = () => {
return renderHook(() => useIsComponentMounted())
}
describe('useIsComponentMounted hook', () => {
it('should be true on render', () => {
const { result } = setup()
expect(result.current.current).toBe(true)
})
it('should false on unmount', () => {
const { result, unmount } = setup()
unmount()
expect(result.current.current).toBe(false)
})
})Requirements:
- act -
brew install act- Requires Docker Desktop
- GitHub Personal Access Token - via GitHub Settings
Example command to test a GitHub action locally:
# run from project root
act -s GITHUB_TOKEN=$GITHUB_TOKEN -j <job-name> --reuseNOTE: there are two parameters set in the project's root .actrc file.
Two important flags that can be passed to the act command:
--reuse- persist state across runs--rm- remove container on failure
For PRs related to swapper integrations, swapper behavior changes, or quote aggregation, actual swap execution testing is required to ensure production readiness.
Execute actual swaps when the PR involves:
-
New Swapper Integration: Adding support for a new DEX aggregator, bridge, or swapper
- Examples: Integrating Bebop, Portals, Jupiter, 0x, 1inch, Relay, Cetus, etc.
-
Swapper Behavior Changes: Modifying existing swapper logic
- Fee calculation changes
- Quote fetching modifications
- Route optimization updates
- Slippage tolerance adjustments
-
Chain Adapter Modifications: Changes to chain adapters affecting swap flows
- New chain support for swaps
- Gas estimation changes
- Transaction building modifications
-
Quote Aggregation Changes: Updates to how quotes are fetched, sorted, or presented
- Multi-swapper aggregation logic
- Quote filtering/sorting algorithms
- Rate calculation modifications
For each swapper-related PR, execute at least 2 successful swaps:
-
Primary swap direction: Test the main use case
- Example: ETH → USDC on the new swapper
-
Secondary swap direction: Test reverse or alternative route
- Example: USDC → ETH or ETH → BTC
-
Cross-chain swap (if applicable): Test bridge/cross-chain functionality
- Example: USDC on Arbitrum → New Chain (Plasma, SUI, HyperEVM, Monad, etc.)
- Example: ETH on Ethereum → Asset on new chain
- Verify cross-chain route aggregation and bridge selection
- Quote Accuracy: Verify quoted rates match executed rates (within acceptable slippage)
- Balance Updates: Confirm source and destination balances update correctly post-swap
- Fee Estimation: Validate transaction fees match estimates
- Transaction Completion: Ensure swaps complete successfully with proper notifications
- Error Handling: Test edge cases (insufficient balance, no routes, etc.)
- Multi-chain Support: For cross-chain swappers, test bridge functionality
- Price Impact: Verify price impact calculations are accurate
- Slippage Tolerance: Test swaps near slippage limits
- Transaction History Parsing: Verify TX history displays correctly for new chains/swappers
- Navigate to asset page and verify TX appears in history
- Click on TX row to open details drawer
- Verify all TX details are correct (amount, fee, timestamp, addresses, status)
- Check that TX type is correctly identified (swap, send, receive, etc.)
- Cross-chain TX Tracking: For bridge swaps, verify both source and destination TX appear
# 1. Start local development environment
pnpm run dev
# 2. Use browser automation (Playwright) or manual testing
# Connect wallet and execute test swaps
# 3. Document results in PR commentInclude the following in your PR:
## Swap Execution Test Results
### Test 1: [Asset A] → [Asset B]
**Setup**:
- Direction: [Asset A] → [Asset B]
- Amount: [amount]
- Protocol: [swapper name]
**Pre-Swap Balances**:
- [Asset A]: [balance]
- [Asset B]: [balance]
**Quote Details**:
- Expected output: [amount]
- Exchange rate: [rate]
- Fee: [fee]
- Price impact: [%]
**Execution**: ✅ Success / ❌ Failed
- Transaction hash: [hash]
- Block explorer: [link]
**Post-Swap Balances**:
- [Asset A]: [balance] (change: [delta])
- [Asset B]: [balance] (change: [delta])
**Verification**:
- ✅/❌ Quote accuracy
- ✅/❌ Balance updates
- ✅/❌ Fee estimation
- ✅/❌ Transaction notification
**Notes**: [any observations]- Use Testnet When Possible: Prefer testnets for initial validation, but include at least 1 mainnet swap for production verification
- Document Edge Cases: Note any limitations, directional liquidity issues, or unsupported routes
- Test Multiple Amounts: Small, medium, and large swaps may have different behaviors
- Monitor Console Errors: Document any errors or warnings during swap execution
- Verify UI/UX: Ensure loading states, notifications, and error messages display correctly
See .playwright-mcp/swap-execution-test-report.md for comprehensive testing examples.
While manual swap execution is currently required, we aim to automate this with:
- Playwright end-to-end tests
- Mock swapper responses for unit tests
- Testnet automation for CI/CD pipelines