@finn_gal/playwright-wallet-mock-ts
v1.0.3
Published
Mock Web3 Browser wallets, like Metamask, in Playwright tests.
Maintainers
Readme
Wallet Mock
Fully functional end-to-end (E2E) tests for your decentralized application (dApp). This package installs a fully operational, headless Web3 Wallet into the Playwright Browser Context. The wallet can be configured to execute on the blockchain or return mock responses. It is discoverable through EIP-6963 and leverages viem Account and Transport interfaces for easy customization.
Features
- Create comprehensive E2E tests for your dApps, including real blockchain transactions
- Mock specific calls or all calls to the wallet
- All wallet actions are pre-approved by default, eliminating the need for user interaction
- All wallet interactions are headless, meaning, no user interaction is required. You should be testing your dApp, not the wallet
Quick start
Install
npm install -D @finn_gal/playwright-wallet-mock-tsExample
import { test } from "@playwright/test";
import { installMockWallet } from "@finn_gal/playwright-wallet-mock-ts";
import { privateKeyToAccount } from "viem/accounts";
import { http } from "viem";
import { mainnet } from "viem/chains";
test.beforeEach(async ({ page }) => {
await installMockWallet({
page,
account: privateKeyToAccount(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
),
defaultChain: {
...mainnet,
rpcUrls: {
default: {
http: ["https://eth-mainnet.public.blastapi.io"],
},
},
},
transports: { [mainnet.id]: http() },
});
});
test("Your Test", async ({ page }) => {
await page.getByRole("button", { name: "Log In" }).click();
await page.getByRole("button", { name: "Choose Wallet" }).click();
await page.getByRole("menuitem", { name: "Mock Wallet" }).click();
});Note: This setup will execute actual transactions on the blockchain without user intervention using the provided Private Key.
Mocking
Here's a simple example of how to mock a specific function while using regular RPC calls for all other functions:
await installMockWallet({
page,
account: privateKeyToAccount(
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80",
),
defaultChain: sepolia,
transports: {
[sepolia.id]: (config) => {
return custom({
request: async ({ method, params }) => {
// Mock only this RPC call
if (method === "eth_sendTransaction") {
return "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
}
return await http()(config).request({ method, params });
},
})(config);
}
},
});Wallet Methods Implementation Status
Implemented
- [x]
eth_accounts- Returns wallet addresses - [x]
eth_requestAccounts- Returns wallet addresses - [x]
wallet_requestPermissions- Returns basic permissions - [x]
wallet_revokePermissions- Returns basic permissions - [x]
wallet_getPermissions- Returns empty permissions array - [x]
wallet_switchEthereumChain- Switches the current chain - [x]
personal_sign- Signs messages - [x]
eth_signTypedData_v4- Signs typed data (EIP-712) - [x]
eth_sendTransaction- Sends transactions
Not Implemented Yet
- [ ]
eth_signTypedData- Basic typed data signing - [ ]
eth_signTypedData_v3- Version 3 of typed data signing
Other RPC Methods
All other standard RPC methods are automatically passed through to the wallet client for processing.
Testing with Hardhat
To test with a local Hardhat node:
Start your local Hardhat Node:
npx hardhat nodeConnect the Mock Wallet to your Hardhat Node:
import { hardhat } from "viem/chains"; await installMockWallet({ page, account: privateKeyToAccount( "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80", ), defaultChain: hardhat, });
