Skip to content

Commit ba6b200

Browse files
authored
Merge pull request #1049 from ensdomains/use-extension
Use extension
2 parents 93d70be + f0c4a7d commit ba6b200

File tree

12 files changed

+1576
-42
lines changed

12 files changed

+1576
-42
lines changed

.github/actions/setup-playwright/action.yml

Lines changed: 0 additions & 8 deletions
This file was deleted.

.github/actions/setup/action.yml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,3 @@ runs:
1717
- name: Install dependencies
1818
shell: bash
1919
run: pnpm install --frozen-lockfile
20-
21-
- name: Install Playwright Browsers and Dependencies
22-
shell: bash
23-
run: pnpm exec playwright install --with-deps

.github/workflows/test-wallet.yaml

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
name: Wallet Tests (Container)
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
paths:
7+
#all files
8+
- '**'
9+
10+
env:
11+
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
12+
13+
jobs:
14+
wallets-container:
15+
name: wallets (container)
16+
timeout-minutes: 20
17+
runs-on: ubuntu-latest
18+
container:
19+
image: mcr.microsoft.com/playwright:v1.55.0-jammy
20+
steps:
21+
- uses: actions/checkout@v4
22+
23+
- name: Setup pnpm
24+
uses: pnpm/action-setup@v4
25+
with:
26+
version: 9.3.0
27+
28+
- name: Setup Node.js
29+
uses: actions/setup-node@v4
30+
with:
31+
node-version: 20
32+
cache: 'pnpm'
33+
34+
- name: Install dependencies
35+
run: pnpm install --frozen-lockfile
36+
37+
- name: Install system dependencies
38+
run: |
39+
apt-get update
40+
apt-get install -y parallel
41+
42+
- name: Verify Playwright installation
43+
run: |
44+
echo "Checking Playwright installation..."
45+
pnpm exec playwright --version
46+
47+
echo "Checking browser installations..."
48+
pnpm exec playwright show-report || true
49+
50+
echo "Cache contents:"
51+
ls -la ~/.cache/ms-playwright/ || echo "No cache found"
52+
53+
- name: Run wallet tests
54+
env:
55+
SECRET_WORDS: ${{ secrets.SECRET_WORDS }}
56+
run: |
57+
parallel --lb --halt now,success=1,fail=1 ::: \
58+
"pnpm dev" \
59+
"pnpm wait-on http://localhost:3000 && xvfb-run --auto-servernum pnpm e2e:wallet"
60+
61+
- uses: actions/upload-artifact@v4
62+
if: always()
63+
with:
64+
name: wallets-report-playwright-action
65+
path: |
66+
playwright-report/
67+
test-results/
68+
*.png
69+
retention-days: 30

.github/workflows/test.yaml

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ jobs:
126126
steps:
127127
- uses: actions/checkout@v4
128128
- uses: ./.github/actions/setup
129-
- uses: ./.github/actions/setup-playwright
129+
130+
- name: Install Playwright
131+
run: pnpm exec playwright install --with-deps chromium
130132

131133
- run: pnpm rebuild -r
132134

@@ -163,7 +165,9 @@ jobs:
163165
steps:
164166
- uses: actions/checkout@v4
165167
- uses: ./.github/actions/setup
166-
- uses: ./.github/actions/setup-playwright
168+
169+
- name: Install Playwright
170+
run: pnpm exec playwright install --with-deps chromium
167171

168172
- run: pnpm rebuild -r
169173

@@ -202,7 +206,9 @@ jobs:
202206
steps:
203207
- uses: actions/checkout@v4
204208
- uses: ./.github/actions/setup
205-
- uses: ./.github/actions/setup-playwright
209+
210+
- name: Install Playwright
211+
run: pnpm exec playwright install --with-deps chromium
206212

207213
- run: |
208214
export NEXT_PUBLIC_CHAIN_NAME=mainnet

docs/safe-ens-metamask-testing.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Safe-ENS MetaMask Integration Testing
2+
3+
This document describes the MetaMask extension testing setup for Safe-ENS integration using dappwright.
4+
5+
## Overview
6+
7+
We've implemented a comprehensive testing framework that uses real MetaMask extension in automated browsers to test Safe-ENS integration scenarios. This replaces the headless wallet approach with actual browser extension automation.
8+
9+
## Architecture
10+
11+
### Key Components
12+
13+
1. **Dappwright Integration** (`@tenkeylabs/dappwright`)
14+
15+
- Handles MetaMask extension download and setup
16+
- Provides wallet automation methods (approve, reject, switchNetwork)
17+
- Manages browser context with extension loaded
18+
19+
2. **Configuration System** (`e2e/config/safe-ens-config.ts`)
20+
21+
- Centralized configuration management
22+
- Environment variable integration
23+
- Network-specific settings
24+
25+
3. **Test Implementation** (`e2e/specs/stateful/safe-ens-dappwright.spec.ts`)
26+
- Complete Safe-ENS integration test suite
27+
- Robust error handling and multiple selector fallbacks
28+
- Real browser automation with MetaMask
29+
30+
## Setup
31+
32+
### Prerequisites
33+
34+
```bash
35+
# Install dependencies
36+
pnpm add -D @tenkeylabs/dappwright playwright-core
37+
38+
# Install Playwright browsers
39+
npx playwright install chromium
40+
npx playwright-core install chromium
41+
```
42+
43+
### Environment Configuration
44+
45+
Configure your `.env` file:
46+
47+
```bash
48+
# Wallet Configuration (optional - will use test defaults if not provided)
49+
SECRET_WORDS="your twelve word mnemonic phrase here"
50+
PASSWORD="YourMetaMaskPassword"
51+
52+
# Network Configuration
53+
NETWORK="sepolia" # Will be overridden to sepolia for tests
54+
55+
# Safe Configuration (optional)
56+
SAFE_URL="https://app.safe.global"
57+
ENS_APP_URL="http://localhost:3000" # For local development
58+
```
59+
60+
## How It Works
61+
62+
### 1. MetaMask Setup
63+
64+
```typescript
65+
const [metaMask, page, browserContext] = await dappwright.bootstrap('chromium', {
66+
wallet: 'metamask',
67+
version: '12.23.0', // Recommended stable version
68+
seed: 'test test test test test test test test test test test junk',
69+
password: 'TestMetaMask',
70+
headless: false, // Required for extensions
71+
slowMo: 100,
72+
})
73+
74+
// Switch to Sepolia network
75+
await metaMask.switchNetwork('sepolia')
76+
```
77+
78+
### 2. Safe Connection
79+
80+
The test automatically:
81+
82+
- Navigates to Safe welcome page
83+
- Tries multiple selectors to find connect button
84+
- Selects MetaMask from wallet options
85+
- Handles MetaMask approval popup
86+
87+
### 3. ENS App Integration
88+
89+
- Adds ENS app as custom Safe app
90+
- Opens the ENS app within Safe iframe
91+
- Tests basic interactions like name search
92+
93+
## Running Tests
94+
95+
### Basic Test Run
96+
97+
```bash
98+
# Run the Safe-ENS integration test
99+
npx playwright test --project=stateful safe-ens-dappwright.spec.ts --headed
100+
```
101+
102+
### Development Mode
103+
104+
```bash
105+
# Run with slower execution for debugging
106+
DEBUG_BROWSER=1 npx playwright test --project=stateful safe-ens-dappwright.spec.ts --headed --debug
107+
```
108+
109+
### Configuration Options
110+
111+
The test uses configuration from `e2e/config/safe-ens-config.ts`:
112+
113+
```typescript
114+
export const SafeEnsConfig = {
115+
NETWORK: 'sepolia', // Fixed for testing
116+
METAMASK: {
117+
VERSION: '12.23.0', // Stable dappwright-recommended version
118+
SETUP_TIMEOUT: 30000,
119+
TRANSACTION_TIMEOUT: 60000,
120+
},
121+
BROWSER: {
122+
HEADLESS: false, // Extensions require headed mode
123+
SLOW_MO: 100,
124+
TIMEOUT: 120000,
125+
},
126+
}
127+
```
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import * as path from 'path'
2+
3+
// eslint-disable-next-line import/no-extraneous-dependencies
4+
import * as dotenv from 'dotenv'
5+
6+
// Load environment variables from .env
7+
dotenv.config({ path: path.resolve(process.cwd(), '.env') })
8+
9+
export const SafeEnsConfig = {
10+
// Wallet configuration
11+
SEED_PHRASE:
12+
process.env.SECRET_WORDS || 'test test test test test test test test test test test junk',
13+
WALLET_PASSWORD: process.env.PASSWORD || 'TestMetaMask',
14+
15+
// Network configuration - force sepolia for testing
16+
NETWORK: 'sepolia',
17+
18+
// URLs
19+
SAFE_URL: process.env.SAFE_URL || 'https://app.safe.global',
20+
ENS_APP_URL: process.env.CI
21+
? 'https://sepolia.app.ens.domains/'
22+
: process.env.ENS_APP_URL || 'http://localhost:3000',
23+
24+
// Safe addresses for different networks
25+
SAFE_ADDRESSES: {
26+
sepolia: 'sep:0x7894BFD6441B2e9a22358F8F71FdF9B2AC817ef8',
27+
holesky: 'hol:0x4caeA72C02d06edF1788B743554a94a076CBdBB0', // Example
28+
mainnet: 'eth:0x4caeA72C02d06edF1788B743554a94a076CBdBB0', // Example
29+
} as const,
30+
31+
// Browser configuration
32+
BROWSER: {
33+
HEADLESS: false, // MetaMask requires headed mode
34+
SLOW_MO: process.env.CI ? 0 : 100,
35+
TIMEOUT: 120000,
36+
},
37+
38+
// MetaMask configuration
39+
METAMASK: {
40+
VERSION: '12.23.0', // Use recommended dappwright version
41+
SETUP_TIMEOUT: 30000,
42+
TRANSACTION_TIMEOUT: 60000,
43+
},
44+
} as const
45+
46+
export type Network = keyof typeof SafeEnsConfig.SAFE_ADDRESSES
47+
48+
// Helper function to get Safe address for current network
49+
export function getSafeAddress(network: string = SafeEnsConfig.NETWORK): string {
50+
const networkKey = network as Network
51+
return SafeEnsConfig.SAFE_ADDRESSES[networkKey] || SafeEnsConfig.SAFE_ADDRESSES.sepolia
52+
}
53+
54+
// Log test configuration
55+
export function logTestConfig(): void {
56+
console.log('Safe-ENS Test Configuration:')
57+
console.log(`Network: ${SafeEnsConfig.NETWORK}`)
58+
console.log(`Safe URL: ${SafeEnsConfig.SAFE_URL}`)
59+
console.log(`ENS App URL: ${SafeEnsConfig.ENS_APP_URL}`)
60+
console.log(`Safe Address: ${getSafeAddress()}`)
61+
console.log(`MetaMask Version: ${SafeEnsConfig.METAMASK.VERSION}`)
62+
console.log(`Headless: ${SafeEnsConfig.BROWSER.HEADLESS}`)
63+
console.log(
64+
` Using Custom Seed: ${
65+
SafeEnsConfig.SEED_PHRASE !== 'test test test test test test test test test test test junk'
66+
? '✓'
67+
: '✗'
68+
}`,
69+
)
70+
}

0 commit comments

Comments
 (0)