@avalix/chroma 0.0.16 → 1.0.1
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 +104 -4
- package/dist/index.d.mts +115 -20
- package/dist/index.mjs +122 -162
- package/package.json +4 -5
- package/scripts/download-extensions.ts +17 -22
- package/src/context-playwright/index.test.ts +19 -29
- package/src/context-playwright/index.ts +50 -36
- package/src/context-playwright/types.ts +19 -17
- package/src/context-playwright/wallet-factory.test.ts +38 -0
- package/src/context-playwright/wallet-factory.ts +18 -81
- package/src/utils/download-extension.integration.test.ts +1 -1
- package/src/utils/download-extension.test.ts +16 -34
- package/src/utils/download-extension.ts +11 -7
- package/src/utils/find-extension-popup.ts +39 -0
- package/src/utils/test-defaults.ts +7 -0
- package/src/wallets/metamask.test.ts +12 -18
- package/src/wallets/metamask.ts +91 -60
- package/src/wallets/polkadot-js.test.ts +12 -18
- package/src/wallets/polkadot-js.ts +19 -54
- package/src/wallets/talisman.test.ts +12 -18
- package/src/wallets/talisman.ts +20 -49
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @avalix/chroma
|
|
2
2
|
|
|
3
|
-
End-to-end testing library for Polkadot wallet interactions using Playwright.
|
|
3
|
+
End-to-end testing library for Polkadot, Ethereum, and Solana wallet interactions using Playwright.
|
|
4
4
|
|
|
5
5
|
## Documentation
|
|
6
6
|
|
|
@@ -54,10 +54,10 @@ test('connect wallet and sign transaction', async ({ page, wallets }) => {
|
|
|
54
54
|
|
|
55
55
|
await page.goto('http://localhost:3000')
|
|
56
56
|
await page.click('button:has-text("Connect Wallet")')
|
|
57
|
-
await metamask.
|
|
57
|
+
await metamask.approve()
|
|
58
58
|
|
|
59
59
|
await page.click('button:has-text("Send Transaction")')
|
|
60
|
-
await metamask.
|
|
60
|
+
await metamask.approve()
|
|
61
61
|
|
|
62
62
|
await expect(page.locator('.transaction-success')).toBeVisible()
|
|
63
63
|
})
|
|
@@ -80,10 +80,110 @@ test('multi-wallet test', async ({ page, wallets }) => {
|
|
|
80
80
|
await talisman.importEthPrivateKey({ privateKey: '0x...', name: 'Bob' })
|
|
81
81
|
|
|
82
82
|
await page.goto('http://localhost:3000')
|
|
83
|
-
await metamask.
|
|
83
|
+
await metamask.approve()
|
|
84
84
|
})
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
+
### Setup Project Pattern
|
|
88
|
+
|
|
89
|
+
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](https://playwright.dev/docs/test-global-setup-teardown).
|
|
90
|
+
|
|
91
|
+
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).
|
|
92
|
+
|
|
93
|
+
#### 1. Setup project — seed once
|
|
94
|
+
|
|
95
|
+
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.
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
// metamask.setup.ts
|
|
99
|
+
import fs from 'node:fs'
|
|
100
|
+
import path from 'node:path'
|
|
101
|
+
import { createWalletTest } from '@avalix/chroma'
|
|
102
|
+
|
|
103
|
+
const SETUP_DIR = '.cache/wallet-setup'
|
|
104
|
+
const SENTINEL = path.join(SETUP_DIR, '.chroma-onboarded')
|
|
105
|
+
|
|
106
|
+
const setup = createWalletTest({
|
|
107
|
+
wallets: [{ type: 'metamask' }],
|
|
108
|
+
userDataDir: SETUP_DIR,
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
setup('seed metamask', async ({ wallets }) => {
|
|
112
|
+
if (fs.existsSync(SENTINEL))
|
|
113
|
+
return
|
|
114
|
+
|
|
115
|
+
await wallets.metamask.importSeedPhrase({
|
|
116
|
+
seedPhrase: 'test test test test test test test test test test test junk',
|
|
117
|
+
})
|
|
118
|
+
fs.writeFileSync(SENTINEL, '')
|
|
119
|
+
})
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### 2. Shared spec fixtures
|
|
123
|
+
|
|
124
|
+
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.
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
// fixtures.ts — shared by your spec files
|
|
128
|
+
import { createWalletTest } from '@avalix/chroma'
|
|
129
|
+
|
|
130
|
+
export const test = createWalletTest({
|
|
131
|
+
wallets: [{ type: 'metamask' }],
|
|
132
|
+
userDataDir: '.cache/wallet-setup',
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
export { expect } from '@playwright/test'
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
// some.spec.ts
|
|
140
|
+
import { test } from './fixtures'
|
|
141
|
+
|
|
142
|
+
test('connect and sign', async ({ page, wallets }) => {
|
|
143
|
+
const metamask = wallets.metamask
|
|
144
|
+
|
|
145
|
+
await page.goto('http://localhost:3000')
|
|
146
|
+
await metamask.unlock()
|
|
147
|
+
|
|
148
|
+
await page.click('button:has-text("Connect Wallet")')
|
|
149
|
+
await metamask.approve()
|
|
150
|
+
|
|
151
|
+
await page.click('button:has-text("Sign Message")')
|
|
152
|
+
await metamask.approve()
|
|
153
|
+
})
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
#### 3. Wire up the projects
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// playwright.config.ts
|
|
160
|
+
export default defineConfig({
|
|
161
|
+
workers: 1,
|
|
162
|
+
projects: [
|
|
163
|
+
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
|
|
164
|
+
{
|
|
165
|
+
name: 'metamask',
|
|
166
|
+
testMatch: /.*\.spec\.ts/,
|
|
167
|
+
dependencies: ['setup'],
|
|
168
|
+
},
|
|
169
|
+
],
|
|
170
|
+
})
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
#### Parallel workers (advanced)
|
|
174
|
+
|
|
175
|
+
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:
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
export const test = createWalletTest({
|
|
179
|
+
wallets: [{ type: 'metamask' }],
|
|
180
|
+
userDataDir: ({ workerIndex }) => `.cache/wallet-w${workerIndex}`,
|
|
181
|
+
cloneUserDataDirFrom: '.cache/wallet-setup',
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
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.
|
|
186
|
+
|
|
87
187
|
## Features
|
|
88
188
|
|
|
89
189
|
- **Easy Extension Setup** - Download wallet extensions with a single command
|
package/dist/index.d.mts
CHANGED
|
@@ -18,6 +18,7 @@ type JUnitReporterOptions = {
|
|
|
18
18
|
outputFile?: string;
|
|
19
19
|
stripANSIControlSequences?: boolean;
|
|
20
20
|
includeProjectInTestName?: boolean;
|
|
21
|
+
includeRetries?: boolean;
|
|
21
22
|
};
|
|
22
23
|
type JsonReporterOptions = {
|
|
23
24
|
outputFile?: string;
|
|
@@ -31,6 +32,7 @@ type HtmlReporterOptions = {
|
|
|
31
32
|
title?: string;
|
|
32
33
|
noSnippets?: boolean;
|
|
33
34
|
noCopyPrompt?: boolean;
|
|
35
|
+
doNotInlineAssets?: boolean;
|
|
34
36
|
};
|
|
35
37
|
type ReporterDescription = Readonly<['blob'] | ['blob', BlobReporterOptions] | ['dot'] | ['line'] | ['list'] | ['list', ListReporterOptions] | ['github'] | ['junit'] | ['junit', JUnitReporterOptions] | ['json'] | ['json', JsonReporterOptions] | ['html'] | ['html', HtmlReporterOptions] | ['null'] | [string] | [string, any]>;
|
|
36
38
|
type UseOptions<TestArgs, WorkerArgs> = Partial<WorkerArgs> & Partial<TestArgs>;
|
|
@@ -226,6 +228,12 @@ interface TestProject<TestArgs = {}, WorkerArgs = {}> {
|
|
|
226
228
|
* for details.
|
|
227
229
|
*/
|
|
228
230
|
pathTemplate?: string;
|
|
231
|
+
/**
|
|
232
|
+
* Controls how children of the snapshot root are matched against the actual accessibility tree. This is equivalent to
|
|
233
|
+
* adding a `/children` property at the top of every aria snapshot template. Individual snapshots can override this by
|
|
234
|
+
* including an explicit `/children` property.
|
|
235
|
+
*/
|
|
236
|
+
children?: "contain" | "equal" | "deep-equal";
|
|
229
237
|
};
|
|
230
238
|
/**
|
|
231
239
|
* Configuration for the
|
|
@@ -711,6 +719,10 @@ interface FullProject<TestArgs = {}, WorkerArgs = {}> {
|
|
|
711
719
|
* See [testProject.grepInvert](https://playwright.dev/docs/api/class-testproject#test-project-grep-invert).
|
|
712
720
|
*/
|
|
713
721
|
grepInvert: null | RegExp | Array<RegExp>;
|
|
722
|
+
/**
|
|
723
|
+
* See [testProject.ignoreSnapshots](https://playwright.dev/docs/api/class-testproject#test-project-ignore-snapshots).
|
|
724
|
+
*/
|
|
725
|
+
ignoreSnapshots: boolean;
|
|
714
726
|
/**
|
|
715
727
|
* See [testProject.metadata](https://playwright.dev/docs/api/class-testproject#test-project-metadata).
|
|
716
728
|
*/
|
|
@@ -1101,6 +1113,12 @@ interface TestConfig<TestArgs = {}, WorkerArgs = {}> {
|
|
|
1101
1113
|
* for details.
|
|
1102
1114
|
*/
|
|
1103
1115
|
pathTemplate?: string;
|
|
1116
|
+
/**
|
|
1117
|
+
* Controls how children of the snapshot root are matched against the actual accessibility tree. This is equivalent to
|
|
1118
|
+
* adding a `/children` property at the top of every aria snapshot template. Individual snapshots can override this by
|
|
1119
|
+
* including an explicit `/children` property.
|
|
1120
|
+
*/
|
|
1121
|
+
children?: "contain" | "equal" | "deep-equal";
|
|
1104
1122
|
};
|
|
1105
1123
|
/**
|
|
1106
1124
|
* Configuration for the
|
|
@@ -6708,6 +6726,7 @@ interface PlaywrightWorkerOptions {
|
|
|
6708
6726
|
* - `'retain-on-failure'`: Record trace for each test. When test run passes, remove the recorded trace.
|
|
6709
6727
|
* - `'retain-on-first-failure'`: Record trace for the first run of each test, but not for retries. When test run
|
|
6710
6728
|
* passes, remove the recorded trace.
|
|
6729
|
+
* - `'retain-on-failure-and-retries'`: Record trace for each test run. Retains all traces when an attempt fails.
|
|
6711
6730
|
*
|
|
6712
6731
|
* For more control, pass an object that specifies `mode` and trace features to enable.
|
|
6713
6732
|
*
|
|
@@ -6745,6 +6764,10 @@ interface PlaywrightWorkerOptions {
|
|
|
6745
6764
|
* down to fit into 800x800. If `viewport` is not configured explicitly the video size defaults to 800x450. Actual
|
|
6746
6765
|
* picture of each page will be scaled down if necessary to fit the specified size.
|
|
6747
6766
|
*
|
|
6767
|
+
* To annotate actions in the video, pass `show` with `action` and/or `test` sub-options. The `action` option controls
|
|
6768
|
+
* visual highlights on interacted elements with an optional `delay` in milliseconds (defaults to `500`). The `test`
|
|
6769
|
+
* option controls which test information is displayed as a status overlay.
|
|
6770
|
+
*
|
|
6748
6771
|
* **Usage**
|
|
6749
6772
|
*
|
|
6750
6773
|
* ```js
|
|
@@ -6763,10 +6786,22 @@ interface PlaywrightWorkerOptions {
|
|
|
6763
6786
|
video: VideoMode | /** deprecated */'retry-with-video' | {
|
|
6764
6787
|
mode: VideoMode;
|
|
6765
6788
|
size?: ViewportSize;
|
|
6789
|
+
show?: {
|
|
6790
|
+
actions?: {
|
|
6791
|
+
duration?: number;
|
|
6792
|
+
position?: 'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right';
|
|
6793
|
+
fontSize?: number;
|
|
6794
|
+
};
|
|
6795
|
+
test?: {
|
|
6796
|
+
level?: 'file' | 'title' | 'step';
|
|
6797
|
+
position?: 'top-left' | 'top' | 'top-right' | 'bottom-left' | 'bottom' | 'bottom-right';
|
|
6798
|
+
fontSize?: number;
|
|
6799
|
+
};
|
|
6800
|
+
};
|
|
6766
6801
|
};
|
|
6767
6802
|
}
|
|
6768
6803
|
type ScreenshotMode = 'off' | 'on' | 'only-on-failure' | 'on-first-failure';
|
|
6769
|
-
type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure';
|
|
6804
|
+
type TraceMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry' | 'on-all-retries' | 'retain-on-first-failure' | 'retain-on-failure-and-retries';
|
|
6770
6805
|
type VideoMode = 'off' | 'on' | 'retain-on-failure' | 'on-first-retry';
|
|
6771
6806
|
/**
|
|
6772
6807
|
* Playwright Test provides many options to configure test environment,
|
|
@@ -7518,6 +7553,11 @@ type ExcludeProps<A, B> = { [K in Exclude<keyof A, keyof B>]: A[K] };
|
|
|
7518
7553
|
type CustomProperties<T> = ExcludeProps<T, PlaywrightTestOptions & PlaywrightWorkerOptions & PlaywrightTestArgs & PlaywrightWorkerArgs>;
|
|
7519
7554
|
type PlaywrightTestProject<TestArgs = {}, WorkerArgs = {}> = Project<PlaywrightTestOptions & CustomProperties<TestArgs>, PlaywrightWorkerOptions & CustomProperties<WorkerArgs>>;
|
|
7520
7555
|
type PlaywrightTestConfig<TestArgs = {}, WorkerArgs = {}> = Config<PlaywrightTestOptions & CustomProperties<TestArgs>, PlaywrightWorkerOptions & CustomProperties<WorkerArgs>>;
|
|
7556
|
+
// Use the global URLPattern type if available (Node.js 22+, modern browsers),
|
|
7557
|
+
// otherwise fall back to `never` so it disappears from union types.
|
|
7558
|
+
type URLPattern = typeof globalThis extends {
|
|
7559
|
+
URLPattern: infer T;
|
|
7560
|
+
} ? T : never;
|
|
7521
7561
|
type AsymmetricMatcher = Record<string, any>;
|
|
7522
7562
|
interface AsymmetricMatchers {
|
|
7523
7563
|
/**
|
|
@@ -7703,7 +7743,11 @@ interface AsymmetricMatchers {
|
|
|
7703
7743
|
*/
|
|
7704
7744
|
interface GenericAssertions<R> {
|
|
7705
7745
|
/**
|
|
7706
|
-
* Makes the assertion check for the opposite condition.
|
|
7746
|
+
* Makes the assertion check for the opposite condition.
|
|
7747
|
+
*
|
|
7748
|
+
* **Usage**
|
|
7749
|
+
*
|
|
7750
|
+
* For example, the following code passes:
|
|
7707
7751
|
*
|
|
7708
7752
|
* ```js
|
|
7709
7753
|
* const value = 1;
|
|
@@ -7712,6 +7756,34 @@ interface GenericAssertions<R> {
|
|
|
7712
7756
|
*
|
|
7713
7757
|
*/
|
|
7714
7758
|
not: GenericAssertions<R>;
|
|
7759
|
+
/**
|
|
7760
|
+
* Use `resolves` to unwrap the value of a fulfilled promise so any other matcher can be chained. If the promise is
|
|
7761
|
+
* rejected the assertion fails.
|
|
7762
|
+
*
|
|
7763
|
+
* For example, this code tests that the promise resolves and that the resulting value is `'lemon'`:
|
|
7764
|
+
*
|
|
7765
|
+
* ```js
|
|
7766
|
+
* test('resolves to lemon', async () => {
|
|
7767
|
+
* await expect(Promise.resolve('lemon')).resolves.toBe('lemon');
|
|
7768
|
+
* });
|
|
7769
|
+
* ```
|
|
7770
|
+
*
|
|
7771
|
+
*/
|
|
7772
|
+
resolves: GenericAssertions<R>;
|
|
7773
|
+
/**
|
|
7774
|
+
* Use `.rejects` to unwrap the reason of a rejected promise so any other matcher can be chained. If the promise is
|
|
7775
|
+
* fulfilled the assertion fails.
|
|
7776
|
+
*
|
|
7777
|
+
* For example, this code tests that the promise rejects with reason `'octopus'`:
|
|
7778
|
+
*
|
|
7779
|
+
* ```js
|
|
7780
|
+
* test('rejects to octopus', async () => {
|
|
7781
|
+
* await expect(Promise.reject(new Error('octopus'))).rejects.toThrow('octopus');
|
|
7782
|
+
* });
|
|
7783
|
+
* ```
|
|
7784
|
+
*
|
|
7785
|
+
*/
|
|
7786
|
+
rejects: GenericAssertions<R>;
|
|
7715
7787
|
/**
|
|
7716
7788
|
* Compares value with
|
|
7717
7789
|
* [`expected`](https://playwright.dev/docs/api/class-genericassertions#generic-assertions-to-be-option-expected) by
|
|
@@ -8339,8 +8411,11 @@ interface APIResponseAssertions {
|
|
|
8339
8411
|
*/
|
|
8340
8412
|
toBeOK(): Promise<void>;
|
|
8341
8413
|
/**
|
|
8342
|
-
* Makes the assertion check for the opposite condition.
|
|
8343
|
-
*
|
|
8414
|
+
* Makes the assertion check for the opposite condition.
|
|
8415
|
+
*
|
|
8416
|
+
* **Usage**
|
|
8417
|
+
*
|
|
8418
|
+
* For example, this code tests that the response status is not successful:
|
|
8344
8419
|
*
|
|
8345
8420
|
* ```js
|
|
8346
8421
|
* await expect(response).not.toBeOK();
|
|
@@ -9304,8 +9379,11 @@ interface LocatorAssertions {
|
|
|
9304
9379
|
timeout?: number;
|
|
9305
9380
|
}): Promise<void>;
|
|
9306
9381
|
/**
|
|
9307
|
-
* Makes the assertion check for the opposite condition.
|
|
9308
|
-
*
|
|
9382
|
+
* Makes the assertion check for the opposite condition.
|
|
9383
|
+
*
|
|
9384
|
+
* **Usage**
|
|
9385
|
+
*
|
|
9386
|
+
* For example, this code tests that the Locator doesn't contain text `"error"`:
|
|
9309
9387
|
*
|
|
9310
9388
|
* ```js
|
|
9311
9389
|
* await expect(locator).not.toContainText('error');
|
|
@@ -9389,6 +9467,9 @@ interface PageAssertions {
|
|
|
9389
9467
|
* // Check for the page URL to contain 'doc', followed by an optional 's', followed by '/'
|
|
9390
9468
|
* await expect(page).toHaveURL(/docs?\//);
|
|
9391
9469
|
*
|
|
9470
|
+
* // Check for the page URL to match the URL pattern
|
|
9471
|
+
* await expect(page).toHaveURL(new URLPattern({ pathname: '/docs/*' }));
|
|
9472
|
+
*
|
|
9392
9473
|
* // Check for the predicate to be satisfied
|
|
9393
9474
|
* // For example: verify query strings
|
|
9394
9475
|
* await expect(page).toHaveURL(url => {
|
|
@@ -9404,7 +9485,7 @@ interface PageAssertions {
|
|
|
9404
9485
|
* against the current browser URL.
|
|
9405
9486
|
* @param options
|
|
9406
9487
|
*/
|
|
9407
|
-
toHaveURL(url: string | RegExp | ((url: URL) => boolean), options?: {
|
|
9488
|
+
toHaveURL(url: string | RegExp | URLPattern | ((url: URL) => boolean), options?: {
|
|
9408
9489
|
/**
|
|
9409
9490
|
* Whether to perform case-insensitive match.
|
|
9410
9491
|
* [`ignoreCase`](https://playwright.dev/docs/api/class-pageassertions#page-assertions-to-have-url-option-ignore-case)
|
|
@@ -9418,8 +9499,11 @@ interface PageAssertions {
|
|
|
9418
9499
|
timeout?: number;
|
|
9419
9500
|
}): Promise<void>;
|
|
9420
9501
|
/**
|
|
9421
|
-
* Makes the assertion check for the opposite condition.
|
|
9422
|
-
*
|
|
9502
|
+
* Makes the assertion check for the opposite condition.
|
|
9503
|
+
*
|
|
9504
|
+
* **Usage**
|
|
9505
|
+
*
|
|
9506
|
+
* For example, this code tests that the page URL doesn't contain `"error"`:
|
|
9423
9507
|
*
|
|
9424
9508
|
* ```js
|
|
9425
9509
|
* await expect(page).not.toHaveURL('error');
|
|
@@ -9956,9 +10040,8 @@ declare function createMetaMaskWallet(extensionId: string, context: BrowserConte
|
|
|
9956
10040
|
seedPhrase: string;
|
|
9957
10041
|
}) => Promise<void>;
|
|
9958
10042
|
unlock: () => Promise<void>;
|
|
9959
|
-
|
|
10043
|
+
approve: () => Promise<void>;
|
|
9960
10044
|
reject: () => Promise<void>;
|
|
9961
|
-
confirm: () => Promise<void>;
|
|
9962
10045
|
};
|
|
9963
10046
|
type PolkadotJsWalletInstance = ReturnType<typeof createPolkadotJsWallet>;
|
|
9964
10047
|
type TalismanWalletInstance = ReturnType<typeof createTalismanWallet>;
|
|
@@ -9973,31 +10056,43 @@ interface WalletAccount {
|
|
|
9973
10056
|
}
|
|
9974
10057
|
interface WalletConfig {
|
|
9975
10058
|
type: WalletType;
|
|
9976
|
-
downloadUrl?: string;
|
|
9977
10059
|
}
|
|
9978
10060
|
interface WalletTypeMap {
|
|
9979
10061
|
'polkadot-js': PolkadotJsWalletInstance;
|
|
9980
10062
|
'talisman': TalismanWalletInstance;
|
|
9981
10063
|
'metamask': MetaMaskWalletInstance;
|
|
9982
10064
|
}
|
|
9983
|
-
type Wallets = WalletTypeMap;
|
|
9984
10065
|
type ConfiguredWallets<T extends readonly WalletConfig[]> = { [K in T[number]['type']]: WalletTypeMap[K] };
|
|
9985
|
-
type ExtendedPage = Page & {
|
|
9986
|
-
__extensionContext: BrowserContext;
|
|
9987
|
-
__walletExtensionIds: Map<string, string>;
|
|
9988
|
-
};
|
|
9989
10066
|
interface ChromaTestOptions<T extends readonly WalletConfig[] = WalletConfig[]> {
|
|
9990
10067
|
wallets?: T;
|
|
9991
10068
|
headless?: boolean;
|
|
9992
10069
|
slowMo?: number;
|
|
10070
|
+
/**
|
|
10071
|
+
* Persistent profile dir for the browser context.
|
|
10072
|
+
* - Empty/undefined (default): temp dir is used; state is lost each run.
|
|
10073
|
+
* - String: shared profile path. Requires `workers: 1` if used by multiple workers.
|
|
10074
|
+
* - Function: receives the worker index, returns the path. Use for parallel
|
|
10075
|
+
* isolation (e.g. `({ workerIndex }) => `.cache/wallet-w${workerIndex}``).
|
|
10076
|
+
*/
|
|
10077
|
+
userDataDir?: string | ((info: {
|
|
10078
|
+
workerIndex: number;
|
|
10079
|
+
}) => string | Promise<string>);
|
|
10080
|
+
/**
|
|
10081
|
+
* If set, the source dir is copied into `userDataDir` before launch (target is
|
|
10082
|
+
* removed first). Use with the Playwright setup-project pattern: a setup
|
|
10083
|
+
* project writes to the source dir, then test projects clone it per worker so
|
|
10084
|
+
* each parallel worker boots from the same prepared state.
|
|
10085
|
+
* No-op if `userDataDir` resolves to an empty string.
|
|
10086
|
+
*/
|
|
10087
|
+
cloneUserDataDirFrom?: string;
|
|
9993
10088
|
}
|
|
9994
|
-
interface WalletFixtures<W =
|
|
9995
|
-
page:
|
|
10089
|
+
interface WalletFixtures<W = WalletTypeMap> {
|
|
10090
|
+
page: Page;
|
|
9996
10091
|
wallets: W;
|
|
9997
10092
|
}
|
|
9998
10093
|
interface WalletWorkerFixtures {
|
|
9999
10094
|
walletContext: BrowserContext;
|
|
10000
|
-
walletExtensionIds: Map<
|
|
10095
|
+
walletExtensionIds: Map<WalletType, string>;
|
|
10001
10096
|
}
|
|
10002
10097
|
//#endregion
|
|
10003
10098
|
//#region src/context-playwright/index.d.ts
|