synpress-e2e

synpress-e2e

End-to-end testing with wallet automation using Synpress. Use this skill for testing dApp flows that require MetaMask/wallet interactions, transaction signing, and on-chain verification.

0星標
0分支
更新於 1/17/2026
SKILL.md
readonlyread-only
name
synpress-e2e
description

End-to-end testing with wallet automation using Synpress. Use this skill for testing dApp flows that require MetaMask/wallet interactions, transaction signing, and on-chain verification.

Synpress E2E Testing

This skill guides E2E testing of Web3 dApps using Synpress, which extends Playwright with MetaMask automation capabilities.

When to Use This Skill

Invoke this skill when:

  • Testing wallet connection flows
  • Testing transaction signing
  • Testing on-chain state changes
  • Automating multi-step DeFi interactions
  • Testing wallet-dependent UI states

Prerequisites

Installation

cd apps/web
pnpm add -D @synthetixio/synpress

Environment Setup

Create .env.e2e:

# Test wallet (DO NOT use with real funds)
TEST_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
TEST_NETWORK_NAME=Base Sepolia
TEST_NETWORK_RPC=https://sepolia.base.org
TEST_CHAIN_ID=84532

Synpress Test Structure

Basic Test Template

// apps/web/e2e/wallet-connect.spec.ts
import { testWithSynpress } from '@synthetixio/synpress';
import { MetaMask, metaMaskFixtures } from '@synthetixio/synpress/playwright';

const test = testWithSynpress(metaMaskFixtures);

test.describe('Wallet Connection', () => {
  test('should connect wallet', async ({ page, metamask }) => {
    // Navigate to app
    await page.goto('http://localhost:5173');
    
    // Click connect button
    await page.click('[data-testid="connect-wallet"]');
    
    // Approve connection in MetaMask
    await metamask.connectToDapp();
    
    // Verify connected state
    await expect(page.locator('[data-testid="wallet-address"]')).toBeVisible();
  });
});

Transaction Test Template

test('should place an order', async ({ page, metamask }) => {
  // Setup: Connect wallet
  await page.goto('http://localhost:5173/market/1');
  await page.click('[data-testid="connect-wallet"]');
  await metamask.connectToDapp();
  
  // Action: Fill order form
  await page.fill('[data-testid="order-amount"]', '100');
  await page.click('[data-testid="place-order-btn"]');
  
  // Handle MetaMask confirmation
  await metamask.confirmTransaction();
  
  // Verify: Check transaction success
  await expect(page.locator('text=Order placed')).toBeVisible({ timeout: 30000 });
});

Synpress Commands Reference

Wallet Setup

// Import wallet from private key
await metamask.importWallet(process.env.TEST_PRIVATE_KEY);

// Add custom network
await metamask.addNetwork({
  name: 'Base Sepolia',
  rpcUrl: 'https://sepolia.base.org',
  chainId: 84532,
  symbol: 'ETH',
});

// Switch network
await metamask.switchNetwork('Base Sepolia');

Transaction Handling

// Confirm transaction (approve gas)
await metamask.confirmTransaction();

// Confirm with custom gas
await metamask.confirmTransaction({ gasLimit: 500000 });

// Reject transaction
await metamask.rejectTransaction();

// Sign message
await metamask.confirmSignature();

Token Approval

// Handle ERC20 approval popup
await metamask.approveTokenPermission();

// Or with specific amount
await metamask.approveTokenPermission({ spendLimit: '1000' });

Sooth-Specific Test Patterns

Market Creation Flow

test('should create a market', async ({ page, metamask }) => {
  await page.goto('http://localhost:5173/create');
  await metamask.connectToDapp();
  
  // Fill market details
  await page.fill('[data-testid="market-question"]', 'Will ETH reach $5000?');
  await page.fill('[data-testid="creator-deposit"]', '100');
  await page.selectOption('[data-testid="resolution-date"]', '2025-12-31');
  
  // Submit creation
  await page.click('[data-testid="create-market-btn"]');
  
  // Approve USDC spend
  await metamask.approveTokenPermission();
  await metamask.confirmTransaction();
  
  // Verify creation
  await expect(page.locator('[data-testid="market-created-success"]')).toBeVisible();
});

Order Placement Flow

test('should place YES order', async ({ page, metamask }) => {
  await page.goto('http://localhost:5173/market/1');
  await metamask.connectToDapp();
  
  // Select YES outcome
  await page.click('[data-testid="outcome-yes"]');
  
  // Enter order details
  await page.fill('[data-testid="order-amount"]', '50');
  await page.fill('[data-testid="limit-price"]', '0.65');
  
  // Place order
  await page.click('[data-testid="place-order"]');
  
  // Handle approvals
  await metamask.approveTokenPermission();
  await metamask.confirmTransaction();
  
  // Verify order in book
  await expect(page.locator('[data-testid="open-orders"]')).toContainText('50 USDC');
});

Test Configuration

playwright.config.ts

import { defineConfig } from '@playwright/test';

export default defineConfig({
  testDir: './e2e',
  timeout: 60000, // Longer timeout for blockchain
  retries: 2,
  workers: 1, // Serial execution for wallet state
  use: {
    baseURL: 'http://localhost:5173',
    trace: 'on-first-retry',
  },
  webServer: {
    command: 'pnpm dev',
    url: 'http://localhost:5173',
    reuseExistingServer: !process.env.CI,
  },
});

Running Tests

# Run all E2E tests
pnpm test:e2e

# Run with UI
pnpm test:e2e:ui

# Run specific test
pnpm test:e2e -- --grep "wallet connect"

# Debug mode
pnpm test:e2e -- --debug

Best Practices

Wait for Blockchain State

// Wait for transaction confirmation
await expect(async () => {
  const balance = await page.locator('[data-testid="balance"]').textContent();
  expect(parseFloat(balance)).toBeGreaterThan(0);
}).toPass({ timeout: 30000 });

Handle Network Delays

// Retry pattern for chain state
await page.waitForFunction(
  () => document.querySelector('[data-testid="tx-confirmed"]'),
  { timeout: 45000 }
);

Clean State Between Tests

test.beforeEach(async ({ metamask }) => {
  // Reset to known state
  await metamask.switchNetwork('Base Sepolia');
});

Troubleshooting

MetaMask Not Loading

  • Ensure Chrome extension path is correct
  • Check that no other MetaMask instances are running
  • Clear extension cache

Transaction Stuck

  • Increase gas limit in confirmTransaction()
  • Check RPC endpoint health
  • Verify test wallet has sufficient balance

Flaky Tests

  • Add explicit waits for blockchain state
  • Use toPass() with timeout for async checks
  • Run tests serially (workers: 1)

You Might Also Like

Related Skills

fix

fix

243Kdev-testing

Use when you have lint errors, formatting issues, or before committing code to ensure it passes CI.

facebook avatarfacebook
獲取
peekaboo

peekaboo

179Kdev-testing

Capture and automate macOS UI with the Peekaboo CLI.

openclaw avataropenclaw
獲取
frontend-testing

frontend-testing

128Kdev-testing

Generate Vitest + React Testing Library tests for Dify frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.

langgenius avatarlanggenius
獲取
frontend-code-review

frontend-code-review

127Kdev-testing

Trigger when the user requests a review of frontend files (e.g., `.tsx`, `.ts`, `.js`). Support both pending-change reviews and focused file reviews while applying the checklist rules.

langgenius avatarlanggenius
獲取
code-reviewer

code-reviewer

92Kdev-testing

Use this skill to review code. It supports both local changes (staged or working tree) and remote Pull Requests (by ID or URL). It focuses on correctness, maintainability, and adherence to project standards.

google-gemini avatargoogle-gemini
獲取
session-logs

session-logs

90Kdev-testing

Search and analyze your own session logs (older/parent conversations) using jq.

moltbot avatarmoltbot
獲取