Web3 wallets for Playwright.
This library provides methods for interacting with Web3 wallets using Playwright.
npm install -D w3walletsMetaMask and Polkadot{.js} wallets are currently supported.
npx w3wallets metamask polkadotjsShort aliases are also supported:
npx w3wallets mm pjsThe unzipped files are stored in the .w3wallets/<wallet-name> directory. Add .w3wallets to .gitignore.
CLI Options
USAGE:
npx w3wallets [OPTIONS] <targets...>
TARGETS:
Alias name Known wallet alias (metamask, polkadotjs)
Short alias Short form (mm, pjs)
Extension ID 32-character Chrome extension ID
URL Chrome Web Store URL
OPTIONS:
-h, --help Show help message
-l, --list List available wallet aliases
-o, --output Output directory (default: .w3wallets)
-f, --force Force re-download even if already exists
--debug Save raw .crx file for debugging
EXAMPLES:
npx w3wallets metamask # Download MetaMask
npx w3wallets mm pjs # Download all wallets (short)
npx w3wallets --list # List available aliases
npx w3wallets -o ./extensions metamask # Custom output directory
npx w3wallets --force mm # Force re-download
Install the required wallets into Chromium using withWallets.
// your-fixture.ts
import { withWallets, metamask, polkadotJS } from "w3wallets";
import { test as base } from "@playwright/test";
export const test = withWallets(base, metamask, polkadotJS);
export { expect } from "@playwright/test";Most commonly, you will use the following methods:
onboard: to set up your walletapprove: for operations that confirm actionsdeny: for actions that reject or cancel operations
import { test, expect } from "./your-fixture";
test("Can connect MetaMask to dApp", async ({ page, metamask }) => {
const mnemonic =
"set your seed phrase test test test test test test test junk";
await metamask.onboard(mnemonic);
await page.goto("https://your-dapp.com");
await page.getByRole("button", { name: "Connect Wallet" }).click();
await metamask.approve();
await expect(page.getByText("Connected")).toBeVisible();
});Wallet onboarding can be slow. Caching lets you run the setup once and reuse the browser profile across tests.
Create a *.cache.ts file in a wallets-cache/ directory (default):
// wallets-cache/default.cache.ts
import { prepareWallet, metamask } from "w3wallets";
export default prepareWallet(metamask, async (wallet, page) => {
await wallet.onboard("your seed phrase ...", "YourPassword123!");
});npx w3wallets cacheCLI Options
USAGE:
npx w3wallets cache [OPTIONS] [directory]
OPTIONS:
-f, --force Force rebuild even if cache exists
--headed Run browser in headed mode
directory Directory containing *.cache.{ts,js} files (default: ./wallets-cache/)
The cached profiles are stored in .w3wallets/cache/. The .w3wallets directory should already be in .gitignore.
Import the setup and pass it to withWallets:
import { test as base, expect } from "@playwright/test";
import { withWallets } from "w3wallets";
import cachedMetamask from "./wallets-cache/default.cache";
const test = withWallets(base, cachedMetamask);
test("wallet is ready", async ({ metamask }) => {
await metamask.unlock("YourPassword123!");
// wallet is already onboarded
});Note: All wallets in a test must be either all cached or all non-cached.
Configure library behavior via environment variables:
| Variable | Description | Default |
|---|---|---|
W3WALLETS_ACTION_TIMEOUT |
Timeout (ms) for all wallet actions (click, fill, navigation, assertions) | undefined |
Example:
# In .env or CI environment
W3WALLETS_ACTION_TIMEOUT=60000This only affects w3wallets library code. Your own Playwright configuration remains independent.