@avalix/chroma

中文文档
1.2.0发布于 2026/07/09MITTypeScriptES Module近 30 天下载 6486

End-to-end testing library for Polkadot, Ethereum, and Solana wallet interactions

原始使用文档
文档目录9 节
  1. Documentation
  2. Installation
  3. Download Extensions
  4. Quick Start
  5. Multiple Wallets
  6. Setup Project Pattern
  7. Features
  8. Requirements
  9. License

@avalix/chroma

End-to-end testing library for Polkadot, Ethereum, and Solana wallet interactions using Playwright.

Documentation

We highly recommend you take a look at the Chroma documentation to level up. It's a great resource for learning more about the library. It covers everything from getting started to advanced topics like CI/CD integration and Docker setup.

Installation

npm install @avalix/chroma @playwright/test

Note: @playwright/test is a peer dependency and must be installed separately to avoid conflicts.

Download Extensions

Before running your tests, you need to download the wallet extensions:

npx chroma download-extensions

This will download the wallet extensions (e.g. MetaMask, Polkadot JS, Talisman) to ./.chroma directory in your project root.

Tip: Add this to your package.json scripts for convenience:

{
  "scripts": {
    "test:prepare": "chroma download-extensions"
  }
}

Important: You must run this command before running Playwright tests. If the extension is not found, tests will fail with a helpful error message.

Quick Start

import { createWalletTest, expect } from '@avalix/chroma'

const test = createWalletTest({
  wallets: [{ type: 'metamask' }]
})

test('connect wallet and sign transaction', async ({ page, wallets }) => {
  const metamask = wallets.metamask

  await metamask.importSeedPhrase({
    seedPhrase: 'test test test test test test test test test test test junk'
  })

  await page.goto('http://localhost:3000')
  await page.click('button:has-text("Connect Wallet")')
  await metamask.approve()

  await page.click('button:has-text("Send Transaction")')
  await metamask.approve()

  await expect(page.locator('.transaction-success')).toBeVisible()
})

Multiple Wallets

import { createWalletTest } from '@avalix/chroma'

const test = createWalletTest({
  wallets: [{ type: 'metamask' }, { type: 'talisman' }]
})

test('multi-wallet test', async ({ page, wallets }) => {
  const metamask = wallets.metamask
  const talisman = wallets.talisman

  await metamask.importSeedPhrase({ seedPhrase: 'test test test test test test test test test test test junk' })
  await talisman.importEthPrivateKey({ privateKey: '0x...', name: 'Bob' })

  await page.goto('http://localhost:3000')
  await metamask.approve()
})

Setup Project Pattern

By default the browser context uses a temporary profile, so wallet state (imported accounts, passwords) is lost between runs. To import a seed phrase once and reuse the prepared state across all your specs, combine the userDataDir and cloneUserDataDirFrom options with Playwright's setup project pattern.

A setup project writes the prepared profile to a shared dir; spec projects then point a userDataDir at it (or clone it per worker for parallelism).

1. Setup project — seed once

The setup test guards onboarding with a sentinel file so re-running playwright test doesn't try to onboard an already-prepared profile (the second run would deadlock on a UI that no longer matches the import flow). Delete .cache/wallet-setup to force a fresh seed.

// metamask.setup.ts
import fs from 'node:fs'
import path from 'node:path'
import { createWalletTest } from '@avalix/chroma'

const SETUP_DIR = '.cache/wallet-setup'
const SENTINEL = path.join(SETUP_DIR, '.chroma-onboarded')

const setup = createWalletTest({
  wallets: [{ type: 'metamask' }],
  userDataDir: SETUP_DIR,
})

setup('seed metamask', async ({ wallets }) => {
  if (fs.existsSync(SENTINEL))
    return

  await wallets.metamask.importSeedPhrase({
    seedPhrase: 'test test test test test test test test test test test junk',
  })
  fs.writeFileSync(SENTINEL, '')
})

2. Shared spec fixtures

Spec files import a shared test factory pointed at the prepared profile. Because MetaMask boots into a locked state on a previously-onboarded profile, each spec must call wallets.metamask.unlock() once (it's idempotent — when MetaMask is already unlocked the call is a no-op). On unlock, the MetaMask side panel is left open for the rest of the test session.

// fixtures.ts — shared by your spec files
import { createWalletTest } from '@avalix/chroma'

export const test = createWalletTest({
  wallets: [{ type: 'metamask' }],
  userDataDir: '.cache/wallet-setup',
})

export { expect } from '@playwright/test'
// some.spec.ts
import { test } from './fixtures'

test('connect and sign', async ({ page, wallets }) => {
  const metamask = wallets.metamask

  await page.goto('http://localhost:3000')
  await metamask.unlock()

  await page.click('button:has-text("Connect Wallet")')
  await metamask.approve()

  await page.click('button:has-text("Sign Message")')
  await metamask.approve()
})

3. Wire up the projects

// playwright.config.ts
export default defineConfig({
  workers: 1,
  projects: [
    { name: 'setup', testMatch: /.*\.setup\.ts/ },
    {
      name: 'metamask',
      testMatch: /.*\.spec\.ts/,
      dependencies: ['setup'],
    },
  ],
})

Parallel workers (advanced)

Chrome locks userDataDir, so multiple workers can't share the same path concurrently. Use cloneUserDataDirFrom plus a per-worker userDataDir to give each worker its own copy of the prepared profile:

export const test = createWalletTest({
  wallets: [{ type: 'metamask' }],
  userDataDir: ({ workerIndex }) => `.cache/wallet-w${workerIndex}`,
  cloneUserDataDirFrom: '.cache/wallet-setup',
})

Set workers: undefined (or higher) once you've validated parallel runs in your project — interaction between cloned profiles, MetaMask's locked-state recovery, and Playwright's side-panel detection is still being hardened.

Features

  • Easy Extension Setup - Download wallet extensions with a single command
  • Multi-Wallet Support - Test with multiple wallet extensions simultaneously
  • TypeScript Support - Full type safety and autocomplete
  • VS Code Integration - Works with Playwright Test for VS Code

Requirements

  • Node.js 24+
  • @playwright/test ^1.55.0

License

MIT

版本与发布记录

@avalix/chroma 共发布 22 个版本,首次发布于 2025/09/14;过去 12 个月发布了 12 个版本。

版本发布日期距今
1.2.0latest2026/07/093 个月前
1.1.02026/07/064 个月前
1.0.22026/06/224 个月前
1.0.12026/05/076 个月前
1.0.02026/05/076 个月前
0.0.162026/02/258 个月前

关于 @avalix/chroma 的常见问题

@avalix/chroma 是什么?

End-to-end testing library for Polkadot, Ethereum, and Solana wallet interactions

如何安装 @avalix/chroma?

在项目目录运行 npm install @avalix/chroma,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@playwright/test(^1.61.1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 chroma,可以用 npx chroma 直接运行。

@avalix/chroma 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@avalix/chroma 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@avalix/chroma 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@avalix/chroma 可以商用吗?

@avalix/chroma 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@avalix/chroma 的下载量有多少?

根据 npm 官方下载统计,@avalix/chroma 在 2026/10/07 – 2026/11/05 这 30 天内被下载 6,486 次,日均约 216 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@avalix/chroma 还在维护吗?

最新版本 1.2.0 发布于 2026/07/09(3 个月前);至今共发布 22 个版本,其中过去 12 个月发布了 12 个;首次发布于 2025/09/14。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。