e2e-testing-web3
Playwright E2E test patterns for Web3 and blockchain features — mocking wallet providers (MetaMask, Phantom), testing wallet connection flows, and handling async blockchain confirmations.
Best use case
e2e-testing-web3 is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Playwright E2E test patterns for Web3 and blockchain features — mocking wallet providers (MetaMask, Phantom), testing wallet connection flows, and handling async blockchain confirmations.
Teams using e2e-testing-web3 should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/e2e-testing-web3/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How e2e-testing-web3 Compares
| Feature / Agent | e2e-testing-web3 | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Playwright E2E test patterns for Web3 and blockchain features — mocking wallet providers (MetaMask, Phantom), testing wallet connection flows, and handling async blockchain confirmations.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# E2E Testing — Web3 & Blockchain
Playwright patterns for testing applications that integrate with browser wallets and blockchain transactions.
## When to Activate
- Writing E2E tests for wallet connection flows (MetaMask, Phantom, WalletConnect)
- Testing DeFi features that trigger on-chain transactions
- Mocking browser wallet providers (`window.ethereum`, `window.solana`) in tests
- Handling async blockchain confirmation waits in test flows
> For general Playwright E2E patterns (page objects, CI artifacts, visual testing) — see skill `e2e-testing`.
## Wallet / Web3 Testing
### Mock Wallet Provider (Ethereum/MetaMask)
```typescript
test('wallet connection', async ({ page, context }) => {
// Mock wallet provider
await context.addInitScript(() => {
window.ethereum = {
isMetaMask: true,
request: async ({ method }) => {
if (method === 'eth_requestAccounts')
return ['0x1234567890123456789012345678901234567890']
if (method === 'eth_chainId') return '0x1'
}
}
})
await page.goto('/')
await page.locator('[data-testid="connect-wallet"]').click()
await expect(page.locator('[data-testid="wallet-address"]')).toContainText('0x1234')
})
```
### Financial / Critical Flow Testing
```typescript
test('trade execution', async ({ page }) => {
// Skip on production — real money
test.skip(process.env.NODE_ENV === 'production', 'Skip on production')
await page.goto('/markets/test-market')
await page.locator('[data-testid="position-yes"]').click()
await page.locator('[data-testid="trade-amount"]').fill('1.0')
// Verify preview
const preview = page.locator('[data-testid="trade-preview"]')
await expect(preview).toContainText('1.0')
// Confirm and wait for blockchain
await page.locator('[data-testid="confirm-trade"]').click()
await page.waitForResponse(
resp => resp.url().includes('/api/trade') && resp.status() === 200,
{ timeout: 30000 }
)
await expect(page.locator('[data-testid="trade-success"]')).toBeVisible()
})
```
## Wallet Rejection Flow
```typescript
test('wallet rejection shows error state', async ({ page, context }) => {
await context.addInitScript(() => {
window.ethereum = {
isMetaMask: true,
request: async ({ method }) => {
if (method === 'eth_requestAccounts') {
// Simulate user clicking "Reject" in MetaMask
throw { code: 4001, message: 'User rejected the request.' }
}
if (method === 'eth_chainId') return '0x1'
}
}
})
await page.goto('/')
await page.locator('[data-testid="connect-wallet"]').click()
// Error state should appear, not the wallet address
await expect(page.locator('[data-testid="wallet-error"]')).toContainText('rejected')
await expect(page.locator('[data-testid="wallet-address"]')).not.toBeVisible()
})
```
## Network Switch Required
```typescript
test('prompts network switch when on wrong chain', async ({ page, context }) => {
await context.addInitScript(() => {
window.ethereum = {
isMetaMask: true,
chainId: '0x89', // Polygon, not mainnet
request: async ({ method, params }) => {
if (method === 'eth_requestAccounts')
return ['0xdeadbeef00000000000000000000000000000000']
if (method === 'eth_chainId') return '0x89'
if (method === 'wallet_switchEthereumChain')
throw { code: 4902, message: 'Chain not added' }
}
}
})
await page.goto('/')
await page.locator('[data-testid="connect-wallet"]').click()
// App should prompt user to switch networks
await expect(page.locator('[data-testid="wrong-network-banner"]')).toBeVisible()
await expect(page.locator('[data-testid="switch-network-btn"]')).toBeVisible()
})
```
## Gas Estimation Failure
```typescript
test('shows gas error when estimation fails', async ({ page, context }) => {
await context.addInitScript(() => {
window.ethereum = {
isMetaMask: true,
request: async ({ method }) => {
if (method === 'eth_requestAccounts')
return ['0x1234567890123456789012345678901234567890']
if (method === 'eth_chainId') return '0x1'
if (method === 'eth_estimateGas')
throw { code: -32603, message: 'execution reverted: insufficient balance' }
}
}
})
await page.goto('/swap')
await page.locator('[data-testid="amount-input"]').fill('999999')
await page.locator('[data-testid="swap-btn"]').click()
await expect(page.locator('[data-testid="gas-error"]')).toContainText('insufficient balance')
await expect(page.locator('[data-testid="swap-btn"]')).toBeDisabled()
})
```
## Web3 Test Checklist
- [ ] Wallet provider mocked via `addInitScript` (not real wallet)
- [ ] Blockchain confirmations awaited with generous timeout (30s+)
- [ ] Production guard applied to tests involving real transactions
- [ ] Wallet address assertions use `toContainText` (partial match — chain-dependent format)
- [ ] Error states tested: rejected wallet request, insufficient funds, network switch requiredRelated Skills
visual-testing
Visual Regression Testing: tool comparison (Chromatic/Percy/Playwright screenshots/BackstopJS), pixel-diff vs AI-based comparison, baseline management, flakiness strategies (masks, tolerances, waitForLoadState), CI integration with GitHub Actions, and Storybook integration.
typescript-testing
TypeScript testing patterns: Vitest for unit/integration, Playwright for E2E, MSW for API mocking, Testing Library for React components. Core TDD methodology for TypeScript/JavaScript projects.
swift-testing
Swift testing patterns: Swift Testing framework (Swift 6+), XCTest for UI tests, async/await test cases, actor testing, Combine testing, and XCUITest for UI automation. TDD for Swift/SwiftUI.
swift-protocol-di-testing
Protocol-based dependency injection for testable Swift code — mock file system, network, and external APIs using focused protocols and Swift Testing.
security-review-web3
Security patterns for Web3 and blockchain applications — Solana wallet signature verification, transaction validation, smart contract interaction security, and checklist for DeFi/NFT features.
scala-testing
Scala testing with ScalaTest, MUnit, and ScalaCheck: FunSpec/FlatSpec test structure, property-based testing with forAll, mocking with MockitoSugar, Cats Effect testing with munit-cats-effect (runTest/IOSuite), ZIO Test, Testcontainers-Scala for database integration tests, and CI integration with sbt. Use when writing or reviewing Scala tests.
rust-testing
Rust testing patterns — unit tests with mockall, integration tests with sqlx transactions, HTTP handler testing (axum), benchmarks (criterion), property tests (proptest), fuzzing, and CI with cargo-nextest.
rust-testing-advanced
Advanced Rust testing anti-patterns and corrections — cfg(test) placement, expect() over unwrap(), mockall expectation ordering, executor mixing (#[tokio::test] vs block_on), PgPool isolation with
ruby-testing
RSpec testing patterns for Ruby and Rails — factories, mocks, request specs, feature specs, VCR, and SimpleCov coverage.
r-testing
R testing patterns: testthat 3e with expect_* assertions, snapshot testing, mocking with mockery and httptest2, covr code coverage, lintr static analysis, property-based testing with hedgehog, testing Shiny apps with shinytest2. Use when writing or reviewing R tests.
python-testing
Python testing strategies using pytest, TDD methodology, fixtures, mocking, and parametrization. Core testing fundamentals.
python-testing-advanced
Advanced Python testing — async testing with pytest-asyncio, exception/side-effect testing, test organization, common patterns (API, database, class methods), pytest configuration, and CLI reference. Extends python-testing.