@marigoldlabs/web3-tester 0.1.1 → 0.4.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.
Files changed (80) hide show
  1. package/.env.example +26 -17
  2. package/LICENSE +21 -0
  3. package/README.md +167 -41
  4. package/dist/anvil.d.ts +90 -2
  5. package/dist/anvil.d.ts.map +1 -1
  6. package/dist/anvil.js +215 -13
  7. package/dist/anvil.js.map +1 -1
  8. package/dist/contracts/test-erc20.d.ts +227 -0
  9. package/dist/contracts/test-erc20.d.ts.map +1 -0
  10. package/dist/contracts/test-erc20.js +8 -0
  11. package/dist/contracts/test-erc20.js.map +1 -0
  12. package/dist/erc20.d.ts +38 -0
  13. package/dist/erc20.d.ts.map +1 -0
  14. package/dist/erc20.js +229 -0
  15. package/dist/erc20.js.map +1 -0
  16. package/dist/fixtures.d.ts +44 -2
  17. package/dist/fixtures.d.ts.map +1 -1
  18. package/dist/fixtures.js +162 -17
  19. package/dist/fixtures.js.map +1 -1
  20. package/dist/index.d.ts +17 -5
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +7 -1
  23. package/dist/index.js.map +1 -1
  24. package/dist/injected-provider.d.ts.map +1 -1
  25. package/dist/injected-provider.js +142 -79
  26. package/dist/injected-provider.js.map +1 -1
  27. package/dist/live-fixtures.d.ts +32 -3
  28. package/dist/live-fixtures.d.ts.map +1 -1
  29. package/dist/live-fixtures.js +64 -27
  30. package/dist/live-fixtures.js.map +1 -1
  31. package/dist/matchers.d.ts +90 -0
  32. package/dist/matchers.d.ts.map +1 -0
  33. package/dist/matchers.js +268 -0
  34. package/dist/matchers.js.map +1 -0
  35. package/dist/metamask-extension.d.ts +34 -0
  36. package/dist/metamask-extension.d.ts.map +1 -0
  37. package/dist/metamask-extension.js +97 -0
  38. package/dist/metamask-extension.js.map +1 -0
  39. package/dist/mock-wallet-controller.d.ts +205 -3
  40. package/dist/mock-wallet-controller.d.ts.map +1 -1
  41. package/dist/mock-wallet-controller.js +843 -46
  42. package/dist/mock-wallet-controller.js.map +1 -1
  43. package/dist/private-key-rpc-client.d.ts +1730 -0
  44. package/dist/private-key-rpc-client.d.ts.map +1 -1
  45. package/dist/private-key-rpc-client.js +105 -12
  46. package/dist/private-key-rpc-client.js.map +1 -1
  47. package/dist/real-wallet-cache.d.ts +65 -0
  48. package/dist/real-wallet-cache.d.ts.map +1 -0
  49. package/dist/real-wallet-cache.js +245 -0
  50. package/dist/real-wallet-cache.js.map +1 -0
  51. package/dist/real-wallet-fixtures.d.ts +52 -0
  52. package/dist/real-wallet-fixtures.d.ts.map +1 -0
  53. package/dist/real-wallet-fixtures.js +73 -0
  54. package/dist/real-wallet-fixtures.js.map +1 -0
  55. package/dist/real-wallet-setup.d.ts +4 -0
  56. package/dist/real-wallet-setup.d.ts.map +1 -0
  57. package/dist/real-wallet-setup.js +5 -0
  58. package/dist/real-wallet-setup.js.map +1 -0
  59. package/dist/real-wallet.d.ts +124 -15
  60. package/dist/real-wallet.d.ts.map +1 -1
  61. package/dist/real-wallet.js +1682 -138
  62. package/dist/real-wallet.js.map +1 -1
  63. package/dist/transactions.d.ts +118 -0
  64. package/dist/transactions.d.ts.map +1 -0
  65. package/dist/transactions.js +207 -0
  66. package/dist/transactions.js.map +1 -0
  67. package/dist/types.d.ts +1 -0
  68. package/dist/types.d.ts.map +1 -1
  69. package/dist/walletconnect.d.ts +206 -0
  70. package/dist/walletconnect.d.ts.map +1 -0
  71. package/dist/walletconnect.js +359 -0
  72. package/dist/walletconnect.js.map +1 -0
  73. package/examples/live-sepolia.spec.ts +21 -2
  74. package/examples/local-wallet.spec.ts +1 -1
  75. package/package.json +62 -6
  76. package/docs/API.md +0 -223
  77. package/docs/ARCHITECTURE.md +0 -81
  78. package/docs/CONSUMING_FROM_FJORD.md +0 -123
  79. package/docs/FJORD_LIVE_QA.md +0 -87
  80. package/docs/RELEASE_CHECKLIST.md +0 -55
package/package.json CHANGED
@@ -1,10 +1,23 @@
1
1
  {
2
2
  "name": "@marigoldlabs/web3-tester",
3
- "version": "0.1.1",
4
- "private": false,
3
+ "version": "0.4.1",
5
4
  "type": "module",
6
5
  "description": "A Playwright, Anvil, and Viem based Web3 E2E harness with an injected programmable wallet provider.",
7
- "license": "UNLICENSED",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "playwright",
9
+ "anvil",
10
+ "viem",
11
+ "metamask",
12
+ "walletconnect",
13
+ "web3",
14
+ "ethereum",
15
+ "e2e",
16
+ "testing",
17
+ "wallet",
18
+ "eip-1193",
19
+ "dapp"
20
+ ],
8
21
  "repository": {
9
22
  "type": "git",
10
23
  "url": "git+https://github.com/AndyMarigoldLabs/web3-tester.git"
@@ -24,6 +37,22 @@
24
37
  "types": "./dist/anvil.d.ts",
25
38
  "import": "./dist/anvil.js"
26
39
  },
40
+ "./erc20": {
41
+ "types": "./dist/erc20.d.ts",
42
+ "import": "./dist/erc20.js"
43
+ },
44
+ "./matchers": {
45
+ "types": "./dist/matchers.d.ts",
46
+ "import": "./dist/matchers.js"
47
+ },
48
+ "./walletconnect": {
49
+ "types": "./dist/walletconnect.d.ts",
50
+ "import": "./dist/walletconnect.js"
51
+ },
52
+ "./transactions": {
53
+ "types": "./dist/transactions.d.ts",
54
+ "import": "./dist/transactions.js"
55
+ },
27
56
  "./fixtures": {
28
57
  "types": "./dist/fixtures.d.ts",
29
58
  "import": "./dist/fixtures.js"
@@ -43,30 +72,57 @@
43
72
  "./real-wallet": {
44
73
  "types": "./dist/real-wallet.d.ts",
45
74
  "import": "./dist/real-wallet.js"
46
- }
75
+ },
76
+ "./real-wallet-fixtures": {
77
+ "types": "./dist/real-wallet-fixtures.d.ts",
78
+ "import": "./dist/real-wallet-fixtures.js"
79
+ },
80
+ "./metamask-extension": {
81
+ "types": "./dist/metamask-extension.d.ts",
82
+ "import": "./dist/metamask-extension.js"
83
+ },
84
+ "./package.json": "./package.json"
85
+ },
86
+ "engines": {
87
+ "node": ">=20.0.0"
47
88
  },
48
89
  "files": [
49
90
  "dist",
50
- "docs",
51
91
  "examples",
52
92
  "README.md",
93
+ "LICENSE",
53
94
  ".env.example"
54
95
  ],
55
96
  "scripts": {
56
97
  "build": "tsc -p tsconfig.build.json",
98
+ "build:contracts": "node scripts/build-contracts.mjs",
57
99
  "clean": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\"",
58
100
  "prepare": "npm run build",
59
- "test": "playwright test",
101
+ "test": "playwright test --project=library",
102
+ "test:fjord": "playwright test --project=fjord",
103
+ "test:all": "playwright test",
104
+ "smoke:real-wallet": "node scripts/real-wallet-smoke.mjs",
60
105
  "typecheck": "tsc --noEmit",
61
106
  "verify": "npm run typecheck && npm run build && npm test"
62
107
  },
63
108
  "peerDependencies": {
64
109
  "@playwright/test": ">=1.56.0",
110
+ "@walletconnect/sign-client": ">=2.17 <3",
111
+ "@walletconnect/types": ">=2.17 <3",
112
+ "@walletconnect/utils": ">=2.17 <3",
65
113
  "viem": ">=2.39.3 <3"
66
114
  },
115
+ "peerDependenciesMeta": {
116
+ "@walletconnect/sign-client": { "optional": true },
117
+ "@walletconnect/types": { "optional": true },
118
+ "@walletconnect/utils": { "optional": true }
119
+ },
67
120
  "devDependencies": {
68
121
  "@playwright/test": "^1.56.1",
69
122
  "@types/node": "^24.10.1",
123
+ "@walletconnect/sign-client": "^2.23.9",
124
+ "@walletconnect/types": "^2.23.9",
125
+ "@walletconnect/utils": "^2.23.9",
70
126
  "typescript": "^5.9.3",
71
127
  "viem": "^2.52.0"
72
128
  }
package/docs/API.md DELETED
@@ -1,223 +0,0 @@
1
- # API Reference
2
-
3
- This package exposes two Playwright fixture families and one real-wallet adapter:
4
-
5
- - `fixtures`: local deterministic Anvil tests.
6
- - `live-fixtures`: live Sepolia tests that sign with a runtime-only private key.
7
- - `real-wallet`: persistent Chromium and MetaMask automation for fully in-UI Web3 tests.
8
-
9
- ## Local Fixtures
10
-
11
- ```ts
12
- import { expect, test } from '@marigoldlabs/web3-tester/fixtures';
13
- ```
14
-
15
- Fixtures:
16
-
17
- | Fixture | Scope | Description |
18
- | --- | --- | --- |
19
- | `wallet` | test | `MockWalletController` injected into the page before app scripts run. |
20
- | `chain` | worker | `ChainController` connected to the worker's Anvil node. |
21
- | `anvil` | worker | Running `AnvilInstance`. |
22
- | `walletOptions` | option | Per-test overrides for wallet identity and behavior. |
23
- | `anvilOptions` | option | Worker-level Anvil runtime overrides. |
24
-
25
- Each `wallet` test snapshots chain state before test code runs and reverts after the test finishes.
26
-
27
- ## Live Fixtures
28
-
29
- ```ts
30
- import { expect, test } from '@marigoldlabs/web3-tester/live-fixtures';
31
- ```
32
-
33
- Fixtures:
34
-
35
- | Fixture | Scope | Description |
36
- | --- | --- | --- |
37
- | `wallet` | test | `MockWalletController` backed by a real Sepolia private-key signer. |
38
- | `liveClient` | test | `PrivateKeyRpcClient` for Sepolia RPC and transaction submission. |
39
-
40
- Required environment:
41
-
42
- ```bash
43
- FJORD_PRIVATE_KEY=<runtime-only-private-key>
44
- ```
45
-
46
- Optional:
47
-
48
- ```bash
49
- SEPOLIA_RPC_URL=https://...
50
- ```
51
-
52
- ## Real Wallet
53
-
54
- ```ts
55
- import { launchRealWallet } from '@marigoldlabs/web3-tester/real-wallet';
56
-
57
- const session = await launchRealWallet({
58
- extensionPath: process.env.FJORD_REAL_WALLET_EXTENSION_PATH as string,
59
- profileDir: process.env.FJORD_REAL_WALLET_PROFILE_DIR as string,
60
- expectedAddress: process.env.FJORD_REAL_WALLET_ADDRESS,
61
- setup: process.env.FJORD_REAL_WALLET_PASSWORD
62
- ? {
63
- password: process.env.FJORD_REAL_WALLET_PASSWORD,
64
- seedPhrase: process.env.FJORD_REAL_WALLET_SECRET_RECOVERY_PHRASE,
65
- }
66
- : undefined,
67
- });
68
- ```
69
-
70
- `launchRealWallet` starts a persistent Chromium context with the configured unpacked MetaMask extension. `profileDir` can be either a dedicated Playwright user data directory or a Chrome profile directory such as `Default` or `Profile 1`; Chrome profile paths are mapped back to their user data root and launched with `--profile-directory`.
71
-
72
- Options:
73
-
74
- | Option | Description |
75
- | --- | --- |
76
- | `extensionPath` | Required path to the unpacked MetaMask extension. |
77
- | `profileDir` | Required persistent Chromium user data directory, or a Chrome profile directory. |
78
- | `baseURL` | Optional Playwright base URL for pages opened from the returned context. |
79
- | `expectedAddress` | Optional account address assertion after unlock/import. |
80
- | `extensionName` | Extension name used to resolve the extension ID. Defaults to `MetaMask`. |
81
- | `headless` | Chromium headless setting. Defaults to `false` because extensions require headed Chromium in normal use. |
82
- | `setup.password` | Password used to unlock MetaMask, or to import a seed phrase when onboarding is visible. |
83
- | `setup.seedPhrase` | Seed phrase used only if MetaMask opens on onboarding. |
84
- | `slowMo` | Optional Playwright slow-motion delay. |
85
-
86
- Returned session methods:
87
-
88
- | Method | Description |
89
- | --- | --- |
90
- | `connectToDapp(accounts?)` | Approves a dapp connection request in MetaMask. |
91
- | `confirmSignature()` | Confirms a pending signature request. |
92
- | `confirmTransaction(options?)` | Confirms a pending transaction request. |
93
- | `approveTokenPermission(options?)` | Approves a pending ERC-20 spending permission request. |
94
- | `rejectSignature()` | Rejects a pending signature request. |
95
- | `rejectTransaction()` | Rejects a pending transaction request. |
96
- | `getAccountAddress()` | Returns the selected MetaMask account. |
97
- | `close()` | Closes the persistent browser context. |
98
-
99
- ## MockWalletController
100
-
101
- ```ts
102
- const wallet = new MockWalletController(page, rpcClient, {
103
- accounts: ['0x...'],
104
- chainId: 31337,
105
- autoApprove: true,
106
- connected: true,
107
- });
108
- await wallet.injectMockProvider();
109
- ```
110
-
111
- Properties:
112
-
113
- | Property | Type | Description |
114
- | --- | --- | --- |
115
- | `primaryAccount` | `Address` | First exposed account. |
116
- | `currentChainId` | `Hex` | Current EIP-1193 chain ID. |
117
- | `providerInfo` | `WalletProviderInfo` | Primary EIP-6963 provider metadata. |
118
- | `providerInfos` | `WalletProviderInfo[]` | All announced provider metadata. |
119
-
120
- Methods:
121
-
122
- | Method | Description |
123
- | --- | --- |
124
- | `injectMockProvider()` | Adds the RPC bridge and injects `window.ethereum`. |
125
- | `autoApprove(enabled)` | Toggles automatic approval for future signing methods. |
126
- | `simulateRejection(methods?, message?)` | Rejects the next matching request with code `4001`. |
127
- | `setAccounts(accounts)` | Updates accounts and emits `accountsChanged`. |
128
- | `disconnect()` | Emits `accountsChanged` and `disconnect`. |
129
- | `reconnect()` | Emits `connect` and `accountsChanged`. |
130
- | `switchNetwork(chainId)` | Updates chain ID and emits `chainChanged`. |
131
-
132
- Supported wallet methods include:
133
-
134
- - `eth_accounts`
135
- - `eth_requestAccounts`
136
- - `eth_chainId`
137
- - `net_version`
138
- - `wallet_getPermissions`
139
- - `wallet_requestPermissions`
140
- - `wallet_switchEthereumChain`
141
- - `wallet_addEthereumChain`
142
- - `wallet_watchAsset`
143
- - `metamask_getProviderState`
144
- - `eth_sendTransaction`
145
- - `personal_sign`
146
- - `eth_sign`
147
- - `eth_signTypedData`
148
- - `eth_signTypedData_v3`
149
- - `eth_signTypedData_v4`
150
-
151
- Unhandled methods are forwarded to the configured RPC client.
152
-
153
- ## ChainController
154
-
155
- `ChainController` wraps a Viem Anvil test client.
156
-
157
- | Method | Description |
158
- | --- | --- |
159
- | `snapshot()` | Calls `evm_snapshot`. |
160
- | `revert(id)` | Calls `evm_revert`. |
161
- | `accounts()` | Returns Anvil default accounts. |
162
- | `request(request)` | Sends a raw JSON-RPC request. |
163
- | `impersonateAccount(address)` | Starts Anvil account impersonation. |
164
- | `stopImpersonatingAccount(address)` | Stops Anvil account impersonation. |
165
- | `setBalance(address, value)` | Sets an account balance. |
166
- | `fastForward(seconds)` | Increases time and mines one block. |
167
- | `mine(blocks)` | Mines blocks. |
168
-
169
- The underlying Viem test client is available as `chain.client` for advanced calls.
170
-
171
- ## AnvilInstance
172
-
173
- ```ts
174
- const anvil = await AnvilInstance.start({
175
- runtime: 'docker',
176
- port: 8546,
177
- chainId: 31337,
178
- });
179
-
180
- await anvil.stop();
181
- ```
182
-
183
- Options:
184
-
185
- | Option | Description |
186
- | --- | --- |
187
- | `runtime` | `binary` or `docker`. |
188
- | `executable` | Anvil binary path for `binary` runtime. |
189
- | `dockerImage` | Foundry Docker image. |
190
- | `host` | Host interface. |
191
- | `port` | Host RPC port. |
192
- | `chainId` | Local chain ID. |
193
- | `accounts` | Number of generated accounts. |
194
- | `balance` | ETH balance per generated account. |
195
- | `mnemonic` | Deterministic mnemonic. |
196
- | `blockTime` | Optional automatic mining interval. |
197
- | `forkUrl` | Optional fork RPC URL. |
198
- | `timeoutMs` | Startup timeout. |
199
- | `silent` | Suppress or stream Anvil logs. |
200
-
201
- ## PrivateKeyRpcClient
202
-
203
- `PrivateKeyRpcClient` is for live-chain QA only.
204
-
205
- ```ts
206
- const client = new PrivateKeyRpcClient({
207
- privateKey: process.env.FJORD_PRIVATE_KEY as `0x${string}`,
208
- rpcUrl: process.env.SEPOLIA_RPC_URL,
209
- });
210
- ```
211
-
212
- It supports:
213
-
214
- - `personal_sign`
215
- - `eth_sign`
216
- - `eth_signTypedData_v4`
217
- - `eth_sendTransaction`
218
- - read-only RPC forwarding through Viem public client
219
-
220
- It records sent transaction hashes in:
221
-
222
- - `sentTransactions`
223
- - `sentTransactionRequests`
@@ -1,81 +0,0 @@
1
- # Architecture
2
-
3
- Web3 Tester replaces extension automation with a programmable provider and deterministic chain control.
4
-
5
- ## Local Test Flow
6
-
7
- 1. Playwright creates a worker.
8
- 2. The worker fixture starts Anvil on a unique port.
9
- 3. The test fixture snapshots Anvil state with `evm_snapshot`.
10
- 4. `MockWalletController` exposes a Playwright function bridge.
11
- 5. `page.addInitScript` injects `window.ethereum` before dApp scripts load.
12
- 6. The dApp sends EIP-1193 requests to `window.ethereum.request`.
13
- 7. The injected provider forwards requests through the Playwright bridge.
14
- 8. The Node-side controller approves, rejects, emits events, or forwards RPC to Anvil.
15
- 9. The fixture reverts the chain with `evm_revert`.
16
- 10. The worker fixture stops Anvil after worker completion.
17
-
18
- ## Why This Avoids Synpress-Style Flakiness
19
-
20
- No browser extension is installed. There is no extension popup, no wallet UI selector, no browser-extension process boundary, and no cached wallet profile. Tests exercise the dApp's wallet integration contract directly.
21
-
22
- ## Browser Injection
23
-
24
- The injected provider implements the wallet behavior expected by most dApps:
25
-
26
- - `window.ethereum`
27
- - `request`
28
- - `send`
29
- - `sendAsync`
30
- - `on`
31
- - `once`
32
- - `removeListener`
33
- - `removeAllListeners`
34
- - `_metamask.isUnlocked`
35
- - EIP-6963 `announceProvider`
36
-
37
- The injected script is installed with `page.addInitScript`, so it exists before the application bundle executes. It is also evaluated immediately for pages that have already loaded.
38
-
39
- ## RPC Boundary
40
-
41
- Browser code cannot access Node objects directly. The harness uses:
42
-
43
- ```ts
44
- page.exposeFunction('__invisibleWalletRpcBridge', async (request) => {
45
- return controller.handleRpcRequest(request);
46
- });
47
- ```
48
-
49
- The browser receives only a serialized success or error envelope. Provider-shaped errors are rehydrated in the browser with their original `code`, `message`, and optional `data`.
50
-
51
- ## Chain Isolation
52
-
53
- Local tests isolate state with both process and chain controls:
54
-
55
- - One Anvil node per Playwright worker.
56
- - One chain snapshot per `wallet` test.
57
- - A revert after each `wallet` test.
58
- - Unique worker ports derived from `ANVIL_PORT + workerIndex`.
59
-
60
- This prevents nonce bleeding and lets Playwright run tests in parallel.
61
-
62
- ## Live Sepolia Mode
63
-
64
- Live mode intentionally does not use Anvil snapshots. It uses a runtime-only private key through `PrivateKeyRpcClient` and sends real Sepolia transactions only when an explicit opt-in flag is set.
65
-
66
- Live mutation specs should always:
67
-
68
- - Check the required opt-in env var.
69
- - Use unique QA names.
70
- - Record transaction hashes.
71
- - Avoid committing any private key.
72
- - Continue to the next doc line after a product failure.
73
-
74
- ## Package Boundaries
75
-
76
- Reusable package code lives in `src/`. Fjord-specific tests and reports live outside the package export surface:
77
-
78
- - Exported: `src/*`
79
- - Not exported: `tests/*`, `reports/*`, `tmp/*`, `tools/*`
80
-
81
- The `files` field in `package.json` keeps install output focused on `dist`, `docs`, `examples`, `README.md`, and `.env.example`.
@@ -1,123 +0,0 @@
1
- # Consuming Web3 Tester From Fjord V4
2
-
3
- This guide covers adding the published package to Fjord v4 as a dependency.
4
-
5
- ## Install
6
-
7
- ```bash
8
- npm install --save-dev @marigoldlabs/web3-tester
9
- ```
10
-
11
- For a pinned dependency, use an exact package version:
12
-
13
- ```bash
14
- npm install --save-dev @marigoldlabs/web3-tester@<version>
15
- ```
16
-
17
- ## Playwright Config
18
-
19
- Use Fjord's existing Playwright config if it already exists. The important parts are:
20
-
21
- ```ts
22
- import { defineConfig, devices } from '@playwright/test';
23
-
24
- export default defineConfig({
25
- fullyParallel: true,
26
- retries: process.env.CI ? 2 : 0,
27
- use: {
28
- baseURL: process.env.DAPP_URL ?? 'http://localhost:3000',
29
- trace: 'on-first-retry',
30
- },
31
- projects: [
32
- {
33
- name: 'chromium',
34
- use: { ...devices['Desktop Chrome'] },
35
- },
36
- ],
37
- });
38
- ```
39
-
40
- ## Local Deterministic Tests
41
-
42
- ```ts
43
- import { expect, test } from '@marigoldlabs/web3-tester/fixtures';
44
-
45
- test('connects through the injected provider', async ({ page, wallet }) => {
46
- await page.goto('/');
47
-
48
- await page.getByRole('button', { name: /connect wallet/i }).click();
49
- await page.getByText('Mock Wallet').click();
50
-
51
- await expect(page.getByText(wallet.primaryAccount.slice(0, 6))).toBeVisible();
52
- });
53
- ```
54
-
55
- ## Test Options
56
-
57
- Customize provider identity for wallet selector coverage:
58
-
59
- ```ts
60
- test.use({
61
- walletOptions: {
62
- providerInfo: { name: 'MetaMask', rdns: 'io.metamask' },
63
- additionalProviders: [
64
- { name: 'Rabby', rdns: 'io.rabby' },
65
- { name: 'Rainbow', rdns: 'me.rainbow' },
66
- ],
67
- },
68
- });
69
- ```
70
-
71
- Customize Anvil:
72
-
73
- ```ts
74
- test.use({
75
- anvilOptions: {
76
- runtime: 'docker',
77
- chainId: 31337,
78
- forkUrl: process.env.ANVIL_FORK_URL,
79
- },
80
- });
81
- ```
82
-
83
- ## Live Sepolia Tests
84
-
85
- ```ts
86
- import { expect, test } from '@marigoldlabs/web3-tester/live-fixtures';
87
-
88
- test.skip(!process.env.FJORD_PRIVATE_KEY, 'FJORD_PRIVATE_KEY is required.');
89
-
90
- test('loads the Sepolia account', async ({ page, wallet }) => {
91
- await page.goto('/');
92
- await expect(page.getByText(wallet.primaryAccount.slice(0, 6))).toBeVisible();
93
- });
94
- ```
95
-
96
- Run with:
97
-
98
- ```powershell
99
- $env:FJORD_PRIVATE_KEY = '<runtime-only-key>'
100
- $env:SEPOLIA_RPC_URL = '<optional-rpc-url>'
101
- npm test
102
- ```
103
-
104
- ## Mutation Gates
105
-
106
- Use explicit flags for anything that spends funds or mutates backend state:
107
-
108
- ```powershell
109
- $env:FJORD_RUN_TRANSACTIONS = 'true'
110
- $env:FJORD_MUTATE_STATE = 'true'
111
- $env:FJORD_PUBLISH_SALES = 'true'
112
- $env:FJORD_ADMIN_MUTATE = 'true'
113
- ```
114
-
115
- Keep destructive or expensive tests behind separate flags so normal CI remains read-only.
116
-
117
- ## CI Recommendations
118
-
119
- - Run deterministic Anvil tests on every PR.
120
- - Run live Sepolia read-only tests on a scheduled job or protected branch.
121
- - Run live mutation tests manually with approval.
122
- - Store `FJORD_PRIVATE_KEY` and `SEPOLIA_RPC_URL` only as CI secrets.
123
- - Pin the npm dependency to an exact version once Fjord depends on it.
@@ -1,87 +0,0 @@
1
- # Fjord V4 Live QA
2
-
3
- The Fjord QA specs in `tests/fjord*.spec.ts` are the working executable version of the manual QA document.
4
-
5
- Target:
6
-
7
- ```text
8
- https://v4.fjordfoundry.com
9
- ```
10
-
11
- Network:
12
-
13
- ```text
14
- Sepolia
15
- ```
16
-
17
- Any legacy "mainnet" wording in the manual QA doc is treated as Sepolia for this test harness.
18
-
19
- ## Test Categories
20
-
21
- | Category | Specs | Default behavior |
22
- | --- | --- | --- |
23
- | Public read-only | `fjord-public`, `fjord`, public parts of other specs | Runs without private key where possible. |
24
- | Live wallet read-only | `fjord-live-sepolia`, `fjord-auth-edge`, `fjord-partials-live` | Requires `FJORD_PRIVATE_KEY`. |
25
- | Live transaction | `fjord-live-transaction` | Requires `FJORD_RUN_TRANSACTIONS=true`. |
26
- | Live mutations | `fjord-live-mutations` | Requires `FJORD_MUTATE_STATE=true`. |
27
- | Sale publishing | `fjord-live-mutations` publish branch | Requires `FJORD_PUBLISH_SALES=true`. |
28
- | Admin mutations | `fjord-admin-mutations` | Requires `FJORD_ADMIN_MUTATE=true`. |
29
-
30
- ## Read-Only Run
31
-
32
- ```powershell
33
- $env:FJORD_PRIVATE_KEY = '<runtime-only-key>'
34
- $env:DAPP_URL = 'https://v4.fjordfoundry.com'
35
- npm test -- --reporter=list tests/fjord-public.spec.ts tests/fjord-live-sepolia.spec.ts tests/fjord-auth-edge.spec.ts tests/fjord-partials-live.spec.ts
36
- ```
37
-
38
- ## Live Mutation Run
39
-
40
- ```powershell
41
- $env:FJORD_PRIVATE_KEY = '<runtime-only-key>'
42
- $env:DAPP_URL = 'https://v4.fjordfoundry.com'
43
- $env:FJORD_MUTATE_STATE = 'true'
44
- $env:FJORD_QA_RUN_ID = 'YYYYMMDDXX'
45
- npm test -- --reporter=list tests/fjord-live-mutations.spec.ts
46
- ```
47
-
48
- ## Sale Publish Attempt
49
-
50
- ```powershell
51
- $env:FJORD_PRIVATE_KEY = '<runtime-only-key>'
52
- $env:FJORD_MUTATE_STATE = 'true'
53
- $env:FJORD_PUBLISH_SALES = 'true'
54
- $env:FJORD_QA_RUN_ID = 'YYYYMMDDPX'
55
- npm test -- --reporter=list tests/fjord-live-mutations.spec.ts
56
- ```
57
-
58
- ## Admin Mutation Attempt
59
-
60
- ```powershell
61
- $env:FJORD_PRIVATE_KEY = '<runtime-only-key>'
62
- $env:FJORD_ADMIN_MUTATE = 'true'
63
- npm test -- --reporter=list tests/fjord-admin-mutations.spec.ts
64
- ```
65
-
66
- ## Reporting Rules
67
-
68
- - Record `PASS`, `FAIL`, `PARTIAL`, `BLOCKED`, `NOT RUN`, or `N/A` for every doc line.
69
- - When a line fails, note the observable behavior and continue to the next line.
70
- - Do not collapse a doc mismatch into a product failure if the live UI has moved the control.
71
- - Never paste private keys into reports.
72
- - Include transaction hashes and deployed QA addresses when they help debugging.
73
-
74
- ## Current Report Artifacts
75
-
76
- - `reports/fjord-full-line-by-line-qa-2026-05-14.md`
77
- - `reports/fjord-qa-results-2026-05-14.md`
78
-
79
- ## Known Findings From The 2026-05-14 Run
80
-
81
- - ERC-20 deployment from the Fjord UI succeeded.
82
- - Token supply input minted raw units rather than the expected human-token amount.
83
- - Fixed-price sale draft creation reached review.
84
- - The review step did not show the documented full sale summary.
85
- - Publishing submitted an ERC-20 approval transaction but did not continue to pool creation.
86
- - Saved QA drafts were not listed in the resume dialog.
87
- - `/admin/cache` failed loading admin data with backend `401`.
@@ -1,55 +0,0 @@
1
- # Release Checklist
2
-
3
- Use this before publishing a new version or pinning it inside Fjord v4.
4
-
5
- ## Required
6
-
7
- - `npm run typecheck`
8
- - `npm run build`
9
- - `npm test`
10
- - `rg -n "FJORD_PRIVATE_KEY\\s*=\\s*0x[0-9a-fA-F]{64}|PRIVATE_KEY=.*[0-9a-fA-F]{64}" . -g "!node_modules/**" -g "!dist/**" -g "!.npm-cache/**"`
11
- - Confirm `.env` is ignored.
12
- - Confirm `dist/` is generated locally but not required in source review unless the team wants committed build output.
13
-
14
- ## Dependency Consumer Check
15
-
16
- From a clean consumer repo:
17
-
18
- ```bash
19
- npm install --save-dev @marigoldlabs/web3-tester@<version>
20
- ```
21
-
22
- Then import:
23
-
24
- ```ts
25
- import { expect, test } from '@marigoldlabs/web3-tester/fixtures';
26
- ```
27
-
28
- Run one provider smoke test.
29
-
30
- ## Live QA Check
31
-
32
- Run live tests only with runtime secrets:
33
-
34
- ```powershell
35
- $env:FJORD_PRIVATE_KEY = '<runtime-only-key>'
36
- $env:DAPP_URL = 'https://v4.fjordfoundry.com'
37
- npm test -- --reporter=list tests/fjord-live-sepolia.spec.ts
38
- ```
39
-
40
- Mutation runs require explicit flags and should not be part of default CI.
41
-
42
- ## Push
43
-
44
- ```bash
45
- git status --short
46
- git add .
47
- git commit -m "Document and package Web3 tester"
48
- git push -u origin main
49
- ```
50
-
51
- ## Publish
52
-
53
- ```bash
54
- npm publish --access public
55
- ```