Skip to main content

Overview

Chroma extends Playwright’s test fixtures to provide wallet-specific functionality. Fixtures are automatically set up and torn down for each test.

Test-scoped fixtures

These fixtures are recreated for each test.

page

An extended Playwright page with wallet extension context. Type: ExtendedPage
type ExtendedPage = Page & {
  __extensionContext: BrowserContext
  __walletExtensionIds: Map<string, string>
}
__extensionContext
BrowserContext
The browser context that contains loaded wallet extensions
__walletExtensionIds
Map<string, string>
Map of wallet type to Chrome extension ID
Usage:
test('navigate with extension context', async ({ page }) => {
  await page.goto('https://polkadot.js.org/apps/')
  
  // Access extension context if needed
  const extensionId = page.__walletExtensionIds.get('polkadot-js')
  console.log('Extension ID:', extensionId)
})

wallets

Wallet instances for interacting with wallet extensions. Type: ConfiguredWallets<T> (based on your configuration) The wallets object contains instances for each wallet you configured:
const test = createWalletTest() // Defaults to polkadot-js

test('example', async ({ wallets }) => {
  // wallets is { 'polkadot-js': PolkadotJsWalletInstance }
  await wallets['polkadot-js'].importMnemonic({
    seed: 'your mnemonic here',
    name: 'Test Account',
  })
})
See Wallet instances for detailed method documentation.

Worker-scoped fixtures

These fixtures are created once per worker process and persist across all tests in that worker.

walletContext

The Playwright browser context with wallet extensions loaded. Type: BrowserContext Scope: Worker (persists across tests) This context is created with:
  • All configured wallet extensions loaded
  • Persistent storage enabled
  • Custom Chrome arguments for extension support
Usage: You typically don’t need to use this directly, as the page fixture provides access to it via page.__extensionContext.
test('access browser context', async ({ walletContext }) => {
  // Get all pages in the context
  const pages = walletContext.pages()
  
  // Create a new page
  const newPage = await walletContext.newPage()
})
Don’t close the walletContext or its pages manually, as they’re shared across tests in the worker.

walletExtensionIds

A map of wallet types to their Chrome extension IDs. Type: Map<string, string> Scope: Worker (persists across tests) Usage:
test('get extension IDs', async ({ walletExtensionIds }) => {
  const polkadotJsId = walletExtensionIds.get('polkadot-js')
  const talismanId = walletExtensionIds.get('talisman')
  
  console.log('Polkadot-JS extension ID:', polkadotJsId)
  console.log('Talisman extension ID:', talismanId)
})

Fixture lifecycle

1

Worker startup

When a worker process starts:
  1. walletContext is created with all extensions loaded
  2. walletExtensionIds map is populated by detecting service workers
2

Test execution

For each test:
  1. page fixture is created from the worker’s context
  2. wallets fixture creates wallet instances using the extension IDs
  3. Test runs with access to all fixtures
3

Test cleanup

After each test:
  • page and wallets fixtures are cleaned up
  • walletContext and walletExtensionIds persist for the next test
4

Worker shutdown

When the worker exits:
  • walletContext is closed
  • All browser resources are released

Example

Complete example using all fixtures:
import { createWalletTest } from '@avalix/chroma'

const test = createWalletTest({
  wallets: [
    { type: 'polkadot-js' },
    { type: 'talisman' },
  ] as const,
})

test('complete fixture example', async ({
  page,
  wallets,
  walletContext,
  walletExtensionIds,
}) => {
  // Log extension IDs
  console.log('Extension IDs:', Object.fromEntries(walletExtensionIds))
  
  // Import accounts
  await wallets['polkadot-js'].importMnemonic({
    seed: 'test seed phrase',
    name: 'Test Account',
  })
  
  // Navigate to your dApp
  await page.goto('http://localhost:3000')
  
  // Authorize wallet connection
  await wallets['polkadot-js'].authorize()
  
  // Interact with your dApp
  await page.click('button:has-text("Send Transaction")')
  
  // Approve transaction in wallet
  await wallets['polkadot-js'].approveTx({ password: 'test' })
})

Build docs developers (and LLMs) love