@avalix/chroma 0.0.6 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  End-to-end testing library for Polkadot wallet interactions using Playwright.
4
4
 
5
- > **Current Status**: This library currently supports **Polkadot JS Extension** only. Support for other wallets like Talisman is planned for future releases.
5
+ > **⚠️ Active Development**: This library is currently under active development. The API may change and breaking changes can occur between versions. Please pin your version and review changelogs carefully when updating.
6
6
 
7
7
  ## Installation
8
8
 
@@ -12,6 +12,18 @@ npm install @avalix/chroma @playwright/test
12
12
 
13
13
  **Note**: `@playwright/test` is a peer dependency and must be installed separately to avoid conflicts.
14
14
 
15
+ ### Download Extensions
16
+
17
+ Before running your tests, you need to download the wallet extensions:
18
+
19
+ ```bash
20
+ npx @avalix/chroma download-extensions
21
+ ```
22
+
23
+ This will download the wallet extensions (Polkadot JS and Talisman) to `./.chroma` directory in your project root.
24
+
25
+ **Important**: You must run this command before running Playwright tests. If the extension is not found, tests will fail with a helpful error message.
26
+
15
27
  ## Quick Start
16
28
 
17
29
  ### Basic Usage
@@ -19,9 +31,11 @@ npm install @avalix/chroma @playwright/test
19
31
  ```typescript
20
32
  import { expect, test } from '@avalix/chroma'
21
33
 
22
- test('should connect wallet and sign transaction', async ({ page, importAccount, authorize, approveTx }) => {
34
+ test('should connect wallet and sign transaction', async ({ page, wallets }) => {
35
+ const polkadotJs = wallets['polkadot-js']
36
+
23
37
  // Import a test account
24
- await importAccount({
38
+ await polkadotJs.importMnemonic({
25
39
  seed: 'bottom drive obey lake curtain smoke basket hold race lonely fit walk',
26
40
  name: 'Test Account',
27
41
  password: 'securePassword123'
@@ -32,11 +46,11 @@ test('should connect wallet and sign transaction', async ({ page, importAccount,
32
46
 
33
47
  // Connect wallet
34
48
  await page.click('button:has-text("Connect Wallet")')
35
- await authorize()
49
+ await polkadotJs.authorize()
36
50
 
37
51
  // Perform transaction
38
52
  await page.click('button:has-text("Send Transaction")')
39
- await approveTx({ password: 'securePassword123' })
53
+ await polkadotJs.approveTx({ password: 'securePassword123' })
40
54
 
41
55
  // Verify transaction success
42
56
  await expect(page.locator('.transaction-success')).toBeVisible()
@@ -48,33 +62,71 @@ test('should connect wallet and sign transaction', async ({ page, importAccount,
48
62
  ```typescript
49
63
  import { createWalletTest, expect } from '@avalix/chroma'
50
64
 
51
- // Create test with custom configuration
52
65
  const customTest = createWalletTest({
53
- walletType: 'polkadot-js',
54
- walletConfig: {
55
- customPath: './my-custom-extension'
56
- },
66
+ wallets: [{ type: 'polkadot-js' }],
57
67
  headless: false,
58
68
  slowMo: 100
59
69
  })
60
70
 
61
- customTest('test with custom config', async ({ page, importAccount, authorize }) => {
62
- // Your test code here
63
- await importAccount({
71
+ customTest('test with custom config', async ({ page, wallets }) => {
72
+ const polkadotJs = wallets['polkadot-js']
73
+
74
+ await polkadotJs.importMnemonic({
64
75
  seed: 'your seed phrase here...',
65
76
  name: 'My Test Account'
66
77
  })
67
- // ... rest of your test
78
+ await page.goto('http://localhost:3000')
79
+ await polkadotJs.authorize()
80
+ })
81
+ ```
82
+
83
+ ### Multiple Wallets
84
+
85
+ ```typescript
86
+ import { createWalletTest, expect } from '@avalix/chroma'
87
+
88
+ // Test with multiple wallet extensions
89
+ const multiWalletTest = createWalletTest({
90
+ wallets: [
91
+ { type: 'polkadot-js' },
92
+ { type: 'talisman' }
93
+ ],
94
+ headless: false,
95
+ slowMo: 150
96
+ })
97
+
98
+ multiWalletTest('test with multiple wallets', async ({ page, wallets }) => {
99
+ const polkadotJs = wallets['polkadot-js']
100
+ const talisman = wallets.talisman
101
+
102
+ // Import to Polkadot JS
103
+ await polkadotJs.importMnemonic({
104
+ seed: 'bottom drive obey lake curtain smoke basket hold race lonely fit walk',
105
+ name: 'Alice'
106
+ })
107
+
108
+ // Import to Talisman using Ethereum private key
109
+ await talisman.importEthPrivateKey({
110
+ privateKey: '0x...',
111
+ name: 'Bob'
112
+ })
113
+
114
+ await page.goto('http://localhost:3000')
115
+
116
+ // Use specific wallet
117
+ await polkadotJs.authorize()
118
+ await polkadotJs.approveTx()
68
119
  })
69
120
  ```
70
121
 
71
122
  ## Features
72
123
 
73
- - 🔐 **Automatic Extension Setup**: Downloads and configures Polkadot JS extension automatically
124
+ - 🔐 **Easy Extension Setup**: Simple command to download wallet extensions
74
125
  - 🧪 **Test Fixtures**: Ready-to-use Playwright fixtures for wallet operations
75
126
  - 📝 **Account Management**: Import accounts with seed phrases and custom names
76
127
  - ✅ **Transaction Approval**: Approve transactions with password authentication
77
128
  - 🔗 **dApp Authorization**: Connect wallet to decentralized applications
129
+ - 🔀 **Multi-Wallet Support**: Test with multiple wallet extensions simultaneously
78
130
  - ⚙️ **Configurable**: Custom extension paths, headless mode, and slow motion settings
79
131
 
80
132
  ## API Reference
@@ -87,110 +139,152 @@ Pre-configured test function with Polkadot JS extension.
87
139
  ```typescript
88
140
  import { test } from '@avalix/chroma'
89
141
 
90
- test('my wallet test', async ({ page, importAccount, authorize, approveTx }) => {
91
- // Test implementation
142
+ test('my wallet test', async ({ page, wallets }) => {
143
+ const polkadotJs = wallets['polkadot-js']
144
+
145
+ await polkadotJs.importMnemonic({ seed: '...' })
146
+ await polkadotJs.authorize()
92
147
  })
93
148
  ```
94
149
 
95
150
  #### `createWalletTest(options?: ChromaTestOptions)`
96
- Create a custom test function with specific configuration.
151
+ Create a custom test function with specific configuration. Supports single and multi-wallet modes.
97
152
 
98
153
  ```typescript
99
154
  import { createWalletTest } from '@avalix/chroma'
100
155
 
156
+ // Single wallet (default)
157
+ const test = createWalletTest()
158
+
159
+ // Single wallet with custom config
101
160
  const customTest = createWalletTest({
102
- walletType: 'polkadot-js', // Currently only 'polkadot-js' is supported
103
- walletConfig: {
104
- customPath: './custom-extension', // Optional: path to custom extension
105
- downloadUrl: 'https://...' // Optional: custom download URL
106
- },
107
- headless: true, // Optional: run in headless mode
108
- slowMo: 150 // Optional: slow motion delay in ms (default: 150)
161
+ wallets: [{ type: 'polkadot-js' }],
162
+ headless: false,
163
+ slowMo: 150
164
+ })
165
+
166
+ // Multiple wallets
167
+ const multiTest = createWalletTest({
168
+ wallets: [
169
+ { type: 'polkadot-js' },
170
+ { type: 'talisman' }
171
+ ]
172
+ })
173
+
174
+ // Usage
175
+ test('example', async ({ page, wallets }) => {
176
+ const polkadotJs = wallets['polkadot-js']
177
+
178
+ await polkadotJs.importMnemonic({ seed: '...' })
179
+ await polkadotJs.authorize()
180
+ await polkadotJs.approveTx()
109
181
  })
110
182
  ```
111
183
 
112
184
  ### Test Fixtures
113
185
 
114
- #### `importAccount(options: WalletAccount)`
115
- Import a wallet account using seed phrase.
186
+ #### `page`
187
+ Playwright page instance with wallet extension(s) loaded.
188
+
189
+ #### `wallets`
190
+ Typed object containing wallet instances for each configured wallet. Provides full TypeScript autocomplete.
116
191
 
117
192
  ```typescript
193
+ // Base wallet instance (common methods)
194
+ interface BaseWalletInstance {
195
+ extensionId: string
196
+ importMnemonic: (options: WalletAccount) => Promise<void>
197
+ authorize: (options?: { accountName?: string }) => Promise<void>
198
+ approveTx: (options?: { password?: string }) => Promise<void>
199
+ }
200
+
201
+ // Polkadot-JS wallet instance
202
+ interface PolkadotJsWalletInstance extends BaseWalletInstance {
203
+ type: 'polkadot-js'
204
+ }
205
+
206
+ // Talisman wallet instance (with additional methods)
207
+ interface TalismanWalletInstance extends BaseWalletInstance {
208
+ type: 'talisman'
209
+ importEthPrivateKey: (options: { privateKey: string, name?: string, password?: string }) => Promise<void>
210
+ }
211
+
212
+ // Note: Talisman currently does not support importMnemonic - use importEthPrivateKey instead
213
+
214
+ // Wallets collection - each wallet has its specific type
215
+ interface Wallets {
216
+ 'polkadot-js': PolkadotJsWalletInstance
217
+ 'talisman': TalismanWalletInstance
218
+ }
219
+
118
220
  interface WalletAccount {
119
221
  seed: string
120
222
  name?: string // Default: 'Test Account'
121
223
  password?: string // Default: 'h3llop0lkadot!'
122
224
  }
123
-
124
- await importAccount({
125
- seed: 'your twelve word seed phrase here...',
126
- name: 'My Test Account',
127
- password: 'securePassword123'
128
- })
129
225
  ```
130
226
 
131
- #### `authorize()`
132
- Authorize the dApp to connect with the wallet. Call this after triggering wallet connection from your dApp.
227
+ **Usage:**
133
228
 
134
229
  ```typescript
135
- await authorize()
136
- ```
230
+ test('example', async ({ page, wallets }) => {
231
+ const polkadotJs = wallets['polkadot-js'] // Type: PolkadotJsWalletInstance
137
232
 
138
- #### `approveTx(options?)`
139
- Approve a transaction with the wallet password.
233
+ // Import mnemonic (available on all wallets)
234
+ await polkadotJs.importMnemonic({
235
+ seed: 'bottom drive obey lake curtain smoke basket hold race lonely fit walk',
236
+ name: 'Test Account',
237
+ password: 'securePassword123'
238
+ })
140
239
 
141
- ```typescript
142
- await approveTx({ password: 'myPassword' })
240
+ await page.goto('http://localhost:3000')
241
+ await polkadotJs.authorize()
242
+ await polkadotJs.approveTx({ password: 'securePassword123' })
243
+ })
143
244
 
144
- // Or use default password
145
- await approveTx()
146
- ```
245
+ // Talisman-specific features
246
+ test('talisman example', async ({ page, wallets }) => {
247
+ const talisman = wallets.talisman // Type: TalismanWalletInstance
147
248
 
148
- ### Utility Functions
249
+ // Talisman-specific method: import Ethereum private key
250
+ await talisman.importEthPrivateKey({
251
+ privateKey: '0x...',
252
+ name: 'My Account',
253
+ password: 'mypassword'
254
+ })
149
255
 
150
- #### `downloadAndExtractPolkadotExtension(targetDir?)`
151
- Download and extract Polkadot JS extension to specified directory.
256
+ // Common methods also available
257
+ await talisman.authorize({ accountName: 'My Account' })
258
+ await talisman.approveTx()
259
+ })
260
+ ```
152
261
 
153
- ```typescript
154
- import { downloadAndExtractPolkadotExtension } from '@avalix/chroma'
262
+ ## Configuration
155
263
 
156
- // Download to custom directory
157
- const extensionPath = await downloadAndExtractPolkadotExtension('./my-extensions')
264
+ ### Extension Download
265
+ Run the download command to get the required wallet extensions:
158
266
 
159
- // Download to default directory (./.chroma)
160
- const extensionPath = await downloadAndExtractPolkadotExtension()
267
+ ```bash
268
+ npx @avalix/chroma download-extensions
161
269
  ```
162
270
 
163
- ### TypeScript Types
271
+ Extensions will be downloaded to `./.chroma` directory in your project root. Add this directory to your `.gitignore`:
164
272
 
165
- ```typescript
166
- import type {
167
- ChromaTestOptions,
168
- WalletAccount,
169
- WalletConfig,
170
- WalletFixtures,
171
- WalletType
172
- } from '@avalix/chroma'
273
+ ```gitignore
274
+ .chroma/
173
275
  ```
174
276
 
175
- ## Configuration
176
-
177
- ### Default Directory
178
- The Polkadot JS extension will be automatically downloaded to `./.chroma` directory in your project root. You can customize this by:
179
-
180
- 1. Using `downloadAndExtractPolkadotExtension('./custom-path')`
181
- 2. Using `createWalletTest()` with `walletConfig.customPath`
182
-
183
277
  ### Browser Settings
184
278
  - **Headless Mode**: Disabled by default for better debugging
185
279
  - **Slow Motion**: 150ms delay between actions (configurable)
186
- - **Extension Loading**: Automatically loads only the Polkadot JS extension
280
+ - **Extension Loading**: Automatically loads configured wallet extensions
187
281
 
188
282
  ## Supported Wallets
189
283
 
190
284
  | Wallet | Status | Version |
191
285
  |--------|--------|---------|
192
286
  | Polkadot JS Extension | ✅ Supported | v0.61.7 |
193
- | Talisman | Planned | - |
287
+ | Talisman | Supported | v3.0.5 |
194
288
  | SubWallet | ⏳ Planned | - |
195
289
 
196
290
  ## Requirements
@@ -201,8 +295,9 @@ The Polkadot JS extension will be automatically downloaded to `./.chroma` direct
201
295
  ## Contributing
202
296
 
203
297
  This project is in active development. Currently focusing on:
204
- - Polkadot JS Extension support
298
+ - Polkadot JS Extension and Talisman support
205
299
  - Core testing fixtures
300
+ - Additional wallet integrations
206
301
  - Documentation improvements
207
302
 
208
303
  ## License
package/dist/index.d.ts CHANGED
@@ -1,40 +1,64 @@
1
- import { BrowserContext, BrowserContext as BrowserContext$1, Page, Page as Page$1, expect, test as test$1 } from "@playwright/test";
1
+ import { BrowserContext, Page, expect } from "@playwright/test";
2
+ import * as playwright_test0 from "playwright/test";
2
3
 
3
- //#region src/context-playwright/index.d.ts
4
- type WalletType = "polkadot-js" | "talisman";
5
- interface WalletConfig {
6
- downloadUrl?: string;
7
- customPath?: string;
8
- }
4
+ //#region src/context-playwright/types.d.ts
5
+ type WalletType = 'polkadot-js' | 'talisman';
9
6
  interface WalletAccount {
10
7
  seed: string;
11
8
  name?: string;
12
9
  password?: string;
13
10
  }
14
- interface ChromaTestOptions {
15
- walletType?: WalletType;
16
- walletConfig?: WalletConfig;
17
- headless?: boolean;
18
- slowMo?: number;
19
- }
20
- interface ExtendedPage extends Page$1 {
21
- __extensionContext: BrowserContext$1;
22
- __extensionId: string;
11
+ interface WalletConfig {
12
+ type: WalletType;
13
+ downloadUrl?: string;
23
14
  }
24
- interface WalletFixtures {
25
- page: ExtendedPage;
26
- walletType: WalletType;
27
- walletConfig: WalletConfig;
28
- importAccount: (options: WalletAccount) => Promise<void>;
29
- authorize: () => Promise<void>;
15
+ interface BaseWalletInstance {
16
+ extensionId: string;
17
+ importMnemonic: (options: WalletAccount) => Promise<void>;
18
+ authorize: (options?: {
19
+ accountName?: string;
20
+ }) => Promise<void>;
30
21
  approveTx: (options?: {
31
22
  password?: string;
32
23
  }) => Promise<void>;
33
24
  }
34
- declare function createWalletTest(options?: ChromaTestOptions): ReturnType<typeof test$1.extend<WalletFixtures>>;
35
- declare const test: ReturnType<typeof createWalletTest>;
25
+ interface PolkadotJsWalletInstance extends BaseWalletInstance {
26
+ type: 'polkadot-js';
27
+ }
28
+ interface TalismanWalletInstance extends BaseWalletInstance {
29
+ type: 'talisman';
30
+ importEthPrivateKey: (options: {
31
+ privateKey: string;
32
+ name?: string;
33
+ password?: string;
34
+ }) => Promise<void>;
35
+ }
36
+ interface WalletTypeMap {
37
+ 'polkadot-js': PolkadotJsWalletInstance;
38
+ 'talisman': TalismanWalletInstance;
39
+ }
40
+ type Wallets = WalletTypeMap;
41
+ type ConfiguredWallets<T extends readonly WalletConfig[]> = { [K in T[number]['type']]: WalletTypeMap[K] };
42
+ type ExtendedPage = Page & {
43
+ __extensionContext: BrowserContext;
44
+ __walletExtensionIds: Map<string, string>;
45
+ };
46
+ interface ChromaTestOptions<T extends readonly WalletConfig[] = WalletConfig[]> {
47
+ wallets?: T;
48
+ headless?: boolean;
49
+ slowMo?: number;
50
+ }
51
+ interface WalletFixtures<W = Wallets> {
52
+ page: ExtendedPage;
53
+ wallets: W;
54
+ }
55
+ interface WalletWorkerFixtures {
56
+ walletContext: BrowserContext;
57
+ walletExtensionIds: Map<string, string>;
58
+ }
36
59
  //#endregion
37
- //#region src/context-playwright/download-polkadot-js.d.ts
38
- declare function downloadAndExtractPolkadotExtension(targetDir?: string): Promise<string>;
60
+ //#region src/context-playwright/index.d.ts
61
+ declare function createWalletTest<const T extends readonly WalletConfig[]>(options?: ChromaTestOptions<T>): playwright_test0.TestType<playwright_test0.PlaywrightTestArgs & playwright_test0.PlaywrightTestOptions & WalletFixtures<T extends readonly WalletConfig[] ? ConfiguredWallets<T> : WalletTypeMap>, playwright_test0.PlaywrightWorkerArgs & playwright_test0.PlaywrightWorkerOptions & WalletWorkerFixtures>;
62
+ declare const test: ReturnType<typeof createWalletTest>;
39
63
  //#endregion
40
- export { type BrowserContext, type ChromaTestOptions, type Page, type WalletAccount, type WalletConfig, type WalletFixtures, type WalletType, createWalletTest, downloadAndExtractPolkadotExtension, expect, test };
64
+ export { createWalletTest, expect, test };