End-to-end wallet testing
Chroma drives Polkadot, Ethereum & Solana wallet extensions inside real Playwright tests. Import seeds, authorize dApps, approve and reject transactions, all in code.
Why Chroma
No stubbed providers or injected globals. Chroma loads the real browser extensions and clicks through them, so your tests exercise the exact flows your users hit.
Polkadot-JS, Talisman and MetaMask run as actual Chromium extensions. Chroma finds their popups and side panels and drives them like a person would.
Configure one wallet or several in a single test. The wallets fixture is fully typed. Only the wallets you declare show up, with their own methods.
Import an account once and reuse it across the whole worker. Clone a prepared profile per parallel worker for fast, isolated runs.
It is Playwright. createWalletTest() returns a normal test object, so every assertion, trace and reporter you already use just works.
npx chroma download-extensions pulls pinned extension builds into .chroma/, reproducible across machines and CI.
Run headed locally to watch the flow, or headless in a container. A ready-made Dockerfile runs the full matrix on CI.
From zero to signed tx
Declare the wallets you need, import an account, then walk the dApp exactly like a user.
Pass the wallets to createWalletTest() and get a typed test.
Seed an account with a mnemonic. Chroma drives the extension's import flow.
Connect to the dApp, then approve or reject the transaction popup.
import { createWalletTest } from '@avalix/chroma' const test = createWalletTest({ wallets: [{ type: 'polkadot-js' }], }) test('connects and signs', async ({ page, wallets }) => { const pjs = wallets['polkadot-js'] await pjs.importMnemonic({ seed: 'bottom drive obey lake curtain smoke...', }) await page.goto('http://localhost:3000') await pjs.authorize() // connect dApp await pjs.approveTx() // sign the tx })
Coverage
The matrix grows with every release. Here's what ships in v1.0.1.
Install the package, download the extensions, write your first test in minutes.