@deeeed/metamask-harness 0.35.0 → 0.37.0

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 (73) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +9 -1
  3. package/adapters/extension/artifact-runtime-state.cjs +128 -0
  4. package/adapters/extension/check-infura-readiness.cjs +102 -0
  5. package/adapters/extension/inject.mjs +2 -0
  6. package/adapters/extension/launch-browser.cjs +22 -0
  7. package/adapters/extension/live.sh +103 -18
  8. package/adapters/extension/readiness.mjs +77 -36
  9. package/adapters/extension/snapshot-dist.sh +88 -3
  10. package/adapters/extension/start-watch.sh +15 -0
  11. package/adapters/extension/verify.sh +6 -2
  12. package/adapters/extension/wallet-fixture-state.cjs +3 -1
  13. package/adapters/manifest.json +25 -1
  14. package/adapters/mobile/bridge-runtime/cdp-bridge.cjs +73 -42
  15. package/adapters/mobile/reset-app-data.sh +154 -0
  16. package/adapters/shared/log-tui.mjs +1 -1
  17. package/dist/adapters/extension/artifact-integrity.js +38 -0
  18. package/dist/adapters/extension/extension-id.js +23 -4
  19. package/dist/adapters/extension/product-config.js +29 -1
  20. package/dist/adapters/extension/release-artifact.js +386 -0
  21. package/dist/adapters/extension/runtime-decision.js +161 -20
  22. package/dist/adapters/extension/runtime.js +127 -0
  23. package/dist/adapters/mobile/release-artifact-state.js +124 -0
  24. package/dist/adapters/mobile/release-artifact.js +295 -0
  25. package/dist/adapters.js +29 -4
  26. package/dist/cli-commands.js +1 -1
  27. package/dist/cli.js +2 -2
  28. package/dist/command-contract.js +17 -1
  29. package/dist/commands/call.js +2 -1
  30. package/dist/commands/device-target.js +5 -0
  31. package/dist/commands/fixtures.js +106 -31
  32. package/dist/commands/launch/extension.js +92 -7
  33. package/dist/commands/launch/index.js +13 -0
  34. package/dist/commands/launch/mobile.js +2 -0
  35. package/dist/commands/provision.js +2 -0
  36. package/dist/commands/run-engine.js +89 -5
  37. package/dist/commands/run.js +3 -1
  38. package/dist/commands/runtime-launch.js +178 -10
  39. package/dist/heal-bounds.js +1 -1
  40. package/dist/live-adapter-contract.js +3 -1
  41. package/dist/metamask-action-validation.js +47 -1
  42. package/dist/mm-harness-cli.js +37 -4
  43. package/dist/recipe-security.js +3 -0
  44. package/dist/run-diagnostics.js +1 -1
  45. package/docs/RECIPES.md +29 -0
  46. package/docs/RELEASE-QA-CAPABILITY-MAP.md +150 -0
  47. package/library/actions/extension/perps/perps.mjs +2 -0
  48. package/library/actions/extension/perps/read_snapshot.mjs +470 -0
  49. package/library/actions/extension/platform/cdp.mjs +6 -3
  50. package/library/actions/extension/wallet/import.mjs +201 -0
  51. package/library/actions/extension/wallet/reset.mjs +98 -0
  52. package/library/actions/extension/wallet/secret-input.mjs +98 -0
  53. package/library/actions/extension/wallet/state.mjs +1 -0
  54. package/library/actions/mobile/analytics/consent-settings.mjs +112 -0
  55. package/library/actions/mobile/analytics/set_consent.mjs +4 -112
  56. package/library/actions/mobile/platform/bridge.mjs +8 -0
  57. package/library/actions/mobile/platform/observe-ui.mjs +84 -2
  58. package/library/actions/mobile/ui/native-navigation.mjs +225 -0
  59. package/library/actions/mobile/ui/navigate.mjs +7 -0
  60. package/library/actions/mobile/wallet/import.mjs +328 -0
  61. package/library/actions/mobile/wallet/native-ui.mjs +493 -0
  62. package/library/actions/mobile/wallet/read_state.mjs +16 -0
  63. package/library/actions/mobile/wallet/reset-helper.mjs +99 -0
  64. package/library/actions/mobile/wallet/reset.mjs +20 -0
  65. package/library/actions/shared/ui/locators.mjs +7 -0
  66. package/library/actions/shared/wallet/import-source.mjs +101 -0
  67. package/library/manifests/extension.action-manifest.json +228 -0
  68. package/library/manifests/mobile.action-manifest.json +124 -0
  69. package/library/recipes/extension/runner/action-validation.recipe.json +12 -1
  70. package/library/recipes/wallet/import.recipe.json +102 -0
  71. package/library/recipes/wallet/reset-import.recipe.json +107 -0
  72. package/package.json +1 -1
  73. package/scripts/completions.sh +2 -2
@@ -32,7 +32,7 @@ function formatRunDiagnosticsForHuman(diagnostics, adapter) {
32
32
  async function beginRunDiagnostics(adapter, projectRoot) {
33
33
  const source = getAdapterSurface(adapter).appLogSource(projectRoot);
34
34
  if (!source) return null;
35
- const mobileIssueBuffer = adapter === "mobile" && armMobileIssueBuffer(projectRoot) ? { projectRoot } : void 0;
35
+ const mobileIssueBuffer = adapter === "mobile" && process.env.METAMASK_RECIPE_MOBILE_OPAQUE_RUNTIME !== "1" && armMobileIssueBuffer(projectRoot) ? { projectRoot } : void 0;
36
36
  if (adapter === "extension") {
37
37
  await ensureExtensionConsoleCapture(projectRoot).catch(() => void 0);
38
38
  }
package/docs/RECIPES.md CHANGED
@@ -58,6 +58,35 @@ mm-harness run recipe.json account="Account 2" --plan
58
58
  mm-harness run recipe.json account="Account 2"
59
59
  ```
60
60
 
61
+ Use the shared wallet setup recipe on either Mobile or Extension. `auto`
62
+ reuses a ready fixture-backed profile and otherwise completes visible
63
+ onboarding; `ui` requires a fresh onboarding state.
64
+
65
+ ```bash
66
+ mm-harness run wallet.import method=auto
67
+ mm-harness run wallet.import method=ui credential_source=environment
68
+ mm-harness run wallet.import method=ui metametrics=true 'interests=["trade_perpetuals"]'
69
+ ```
70
+
71
+ The UI path reads the primary mnemonic from `MM_HARNESS_WALLET_SRP` and the
72
+ password from `MM_HARNESS_WALLET_PASSWORD`, or from the canonical wallet
73
+ fixture. Secret values are redacted from commands and evidence. Visible imports
74
+ default to MetaMetrics off and skip Mobile's optional interests; password terms
75
+ are required and always accepted by the action.
76
+
77
+ To prove the full real-user recovery journey, delete the current wallet through
78
+ visible client UI and import it again:
79
+
80
+ ```bash
81
+ mm-harness run wallet.reset-import credential_source=fixture
82
+ ```
83
+
84
+ For fixture-backed development clients, `mm-harness fixtures reset` performs a
85
+ clean reset and reapplies the canonical fixture. Extension resets its owned
86
+ Chrome profile; Mobile clears only the selected app's data, preserves the
87
+ installed build, relaunches it, and then applies the fixture. Use
88
+ `wallet.reset-import` when the reset itself must be exercised through visible UI.
89
+
61
90
  ### Mobile device targeting
62
91
 
63
92
  Always pass `--device <name|udid|serial>` when more than one simulator/device may
@@ -0,0 +1,150 @@
1
+ # Release QA capability map
2
+
3
+ This document maps the Extension release checklists to durable recipe
4
+ capabilities. The baseline is `mm-harness` 0.36.0. It is a capability map, not
5
+ a claim that the listed release cases currently pass.
6
+
7
+ Source baseline: QA repository commit
8
+ [`77591c5`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/tree/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension).
9
+ The relevant sources are the Perps
10
+ [`checklist`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/perps-rc/perps-rc-regression.md)
11
+ and
12
+ [`runbook`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/perps-rc/runbook.md),
13
+ Assets
14
+ [`checklist`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/assets-rc/assets-rc-regression.md)
15
+ and
16
+ [`runbook`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/assets-rc/runbook.md),
17
+ Swap and Bridge
18
+ [`checklist`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/swap-bridge-rc/swap-bridge-rc-regression.md)
19
+ and
20
+ [`runbook`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/swap-bridge-rc/runbook.md),
21
+ and Networks
22
+ [`checklist`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/networks-regression-rc/networks-regression-rc.md)
23
+ and
24
+ [`runbook`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/networks-regression-rc/runbook.md).
25
+
26
+ Ratings:
27
+
28
+ - **AVAILABLE**: a typed capability supplies the required setup, operation, or
29
+ machine-checkable observation.
30
+ - **PARTIAL**: generic UI operations or a narrower domain action can perform
31
+ part of the case, but deterministic setup or a domain assertion is absent.
32
+ - **MISSING**: no durable recipe capability covers the case family.
33
+ - **TARGET**: being implemented in the current change; not present in 0.36.0.
34
+
35
+ ## Cross-cutting capabilities
36
+
37
+ | Requirement | 0.36.0 capability | Status |
38
+ | --- | --- | --- |
39
+ | Discover the typed surface | `mm-harness actions --adapter extension --json` exposes the schemas in the [Extension action manifest](../library/manifests/extension.action-manifest.json), so a plan can reject unsupported domain operations before launch. | **AVAILABLE** |
40
+ | Validate and launch the downloaded official RC artifact | Network discovery and download remain in the release-validation workflow, following the QA [`download-build.sh`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/assets-rc/scripts/download-build.sh) contract. | **TARGET**: verify a local Extension ZIP or Android APK against its trusted digest and declared product identity, then run it without using a checkout build. Extension adds safe extraction, cached tree integrity, and isolated launch. Android adds explicit-device install and launch; release recipes use native accessibility without a development bridge, Metro, or HUD. Downloaded iOS artifacts remain unsupported. |
41
+ | Start from an imported wallet or clean onboarding | [`metamask.wallet.import`](../library/actions/extension/wallet/import.mjs), [`metamask.wallet.reset`](../library/actions/extension/wallet/reset.mjs), and the shared [`import`](../library/recipes/wallet/import.recipe.json) and [`reset-import`](../library/recipes/wallet/reset-import.recipe.json) recipes can use visible UI and parameterized credential sources. | **AVAILABLE** |
42
+ | Drive and observe UI | The [Extension action manifest](../library/manifests/extension.action-manifest.json) exposes typed navigation, press, input, key, scroll, wait, screenshot, surface capture, locators, and CDP target selection. | **AVAILABLE** for mechanics; domain meaning remains **PARTIAL**. |
43
+ | Record evidence and a terminal verdict | Recipe traces, action results, screenshots, and artifact indexing exist. There is no release-plan completion gate equivalent to the QA [`validate-run-report.sh`](https://github.com/MetaMask/experimental-mm-qa-ai-tasks/blob/77591c5998fcf6368417fd5be01871e6c9c3dc5b/tasks/rc-extension/assets-rc/scripts/validate-run-report.sh), including canonical case-ID coverage and explicit remaining cases. | **PARTIAL** |
44
+ | Parameterized environment control | Wallet import choices and Extension analytics consent are typed. Domain fixtures, service doubles, geo eligibility, network catalogs, and remote stream scenarios are not general release-plan inputs. | **MISSING** |
45
+
46
+ ## Perps: 64 Critical cases
47
+
48
+ The existing Perps surface can prepare, read, assert, and close selected
49
+ positions and open orders, and place a basic order. See the
50
+ [`Extension manifest`](../library/manifests/extension.action-manifest.json) and
51
+ [`smoke recipe`](../library/recipes/extension/perps/smoke.recipe.json). It does
52
+ not reproduce the checklist's seeded account snapshot: balance, long and short
53
+ positions, limit orders, take-profit/stop-loss state, activity, watchlist, and
54
+ controlled provider responses and streams.
55
+
56
+ | Case family | Required start state | Required operations and assertions | 0.36.0 coverage |
57
+ | --- | --- | --- | --- |
58
+ | Feature, navigation, session (4) | Feature/eligibility combinations and accounts with different Perps state | Toggle gates, lock/unlock, switch accounts, navigate back; assert gating, account isolation, and route recovery | **PARTIAL**: wallet/account and generic navigation exist; deterministic gates and Perps session assertions are missing. |
59
+ | Perps home (8) | Seeded balance, positions, orders, watchlist, and history | Open cards and balance actions, mutate watchlist; assert all seeded summaries and recent activity | **PARTIAL**: position/order reads and assertions exist; account, market, watchlist, and activity observations are missing. |
60
+ | Market list (4) | Controlled catalog, categories, and price updates | Search, filter, sort, open a market; assert catalog and live values | **PARTIAL**: UI mechanics only; no market catalog or price assertion. |
61
+ | Market details (6) | Selected market data, candles, position, and market-specific order | Navigate and change chart range; assert header, stats, chart states, action mode, and selected-market orders | **PARTIAL**: route and selected order/position state only; market and chart observations are missing. |
62
+ | Order entry (12) | Known balance, constraints, price, leverage limits, and order outcomes | Edit side, amount, percent, leverage, limit price, TP/SL; submit market/limit orders; assert validation, preview, fill, resting order, and duplicate protection | **PARTIAL**: basic placement and open-order convergence exist; rich entry controls, limit/TP-SL inputs, validation, and outcome fields are missing. |
63
+ | Position management (11) | Seeded isolated position, margin, TP/SL, and resting order | Add/reduce exposure, add margin, edit TP/SL, cancel order; assert size, margin, liquidation price, TP/SL, and removal | **PARTIAL**: close positions/orders exists; modify, margin, TP/SL, and rich field assertions are missing. |
64
+ | Deposit (3) | Funded wallet and known Perps balance | Enter amount/Max and confirm; assert validation, pending/success, and resulting balances/activity | **MISSING** |
65
+ | Withdraw (4) | Known withdrawable balance | Enter amount/percent/Max and confirm; assert validation, destination, balance, and activity | **MISSING** |
66
+ | Activity and history (6) | Seeded trades, orders, funding, deposits, and withdrawals | Filter and open details; assert type-specific rows and agreement with home | **MISSING** |
67
+ | Streaming and resilience (4) | Controllable initial responses, updates, reconnects, and order events | Refresh, disconnect/reconnect, close/reopen; assert price, position, order, activity, and loading-state reconciliation | **MISSING** |
68
+ | Geo/compliance (1) | Ineligible trade state | Attempt a trade; assert blocking UI and no submitted order | **MISSING** |
69
+ | Responsive presentation (1) | Popup-width Perps views with populated content | Traverse core views and capture surfaces; assert no clipping or overlap | **PARTIAL**: screenshots and generic UI assertions exist; no reusable Perps presentation assertion. |
70
+
71
+ The aggregate Extension Perps snapshot is a **TARGET**. It exposes account,
72
+ market, position, open-order, activity, and watchlist observations in one typed,
73
+ read-only result when the Extension background test hook is present. An
74
+ untouched production artifact does not expose that hook, so official-artifact
75
+ Perps assertions still require a product-supported observation boundary. The
76
+ snapshot also does not create the required start state.
77
+
78
+ ## Assets: 22 Critical cases
79
+
80
+ | Case family | Required start state | Required operations and assertions | 0.36.0 coverage |
81
+ | --- | --- | --- | --- |
82
+ | Token list, prices, details, sorting (4) | Imported account with known live holdings across networks | Open and sort token list/details; assert holdings, fiat, change, chart, and market data | **PARTIAL**: wallet import and UI mechanics only; no asset reads or assertions. |
83
+ | Token import, hide, persistence, custom network (5) | Known ERC-20 contracts and custom network configuration | Search/import/hide/re-add/restart/remove network; assert visibility and persistence | **MISSING**: no token-list/import or custom-network domain actions. |
84
+ | Real-time and aggregate balances (2) | Known multi-chain balances and an externally triggered update | Observe stream and aggregate; assert prompt update and total | **MISSING** |
85
+ | EVM send and activity (3) | Two owned accounts with native/token funds and gas | Send token, native Max, and custom-gas transaction; assert confirmation, balances, gas behavior, and activity | **MISSING** |
86
+ | NFTs (3) | Owned indexed NFT plus owned and unowned contracts | Detect/import/filter/open media; assert ownership rejection, metadata, image, and network filter | **MISSING** |
87
+ | DeFi positions (2) | Account with known live protocol positions | Open list/details; assert protocol, supplied/borrowed assets, and USD totals | **MISSING** |
88
+ | Solana assets and send (2) | Imported Solana account with SOL and SPL balances | Inspect assets and send SPL; assert fiat, confirmation, balances, and activity | **MISSING** |
89
+ | Bitcoin balance (1) | Imported Bitcoin account with known balance | Open asset details; assert balance, fiat, and chart | **MISSING** |
90
+
91
+ ## Swap and Bridge: 39 cases (25 Critical, 14 Non-Critical)
92
+
93
+ These cases intentionally form a sequential, live-funds journey. A successful
94
+ step changes the next step's network and balances, so generic navigation alone
95
+ cannot establish or prove the required state transitions.
96
+
97
+ | Case family | Required start state | Required operations and assertions | 0.36.0 coverage |
98
+ | --- | --- | --- | --- |
99
+ | Random ERC-20 round trip on Ethereum (2 Critical) | Funded imported account and live token/quote services | Select eligible random token, swap amount then Max; assert quote, confirmation, balance deltas, and activity | **MISSING** |
100
+ | WETH round trip (2 Critical) | Funded Ethereum account | Swap ETH to WETH and Max back; assert quotes, wrapping result, balance deltas, and activity | **MISSING** |
101
+ | Gasless round trip (2 Critical) | Smart Transactions enabled and funded ETH/USDC balances | Execute full-balance gasless swaps; assert route, no stranded input, balances, and activity | **MISSING** |
102
+ | Ethereum to native Solana (2 Critical) | Funded Ethereum source and derived Solana destination | Bridge Max and await completion; assert destination asset is native SOL, balances, and activity | **MISSING** |
103
+ | Half/Max swaps across destination networks (12 Critical, 8 Non-Critical) | Balance delivered by the preceding bridge on each network | Pick supported random token, swap about half and Max back; assert quote/route, confirmation, balance deltas, and activity | **MISSING** |
104
+ | Sequential onward bridges (5 Critical, 4 Non-Critical) | Source balance produced by the preceding swap | Bridge Max to the specified next network and await completion; assert source/destination assets, balances, and activity | **MISSING** |
105
+ | Quote-only networks (2 Non-Critical) | Selected network and funded source asset | Request but do not submit a quote; assert supported routes, fees, and destination | **MISSING** |
106
+
107
+ ## Networks: 10 cases (7 Critical, 3 not marked Critical)
108
+
109
+ | Case family | Required start state | Required operations and assertions | 0.36.0 coverage |
110
+ | --- | --- | --- | --- |
111
+ | Custom-network asset rendering (4) | HyperEVM, INK, and XDC configurations plus known token contracts/balances | Add/select networks and tokens; assert decimals, render stability, logos, and token rows | **MISSING** |
112
+ | Fiat and price APIs (2) | Custom networks with supported native assets and conversion responses | Refresh/select network; assert conversion rates and fiat values | **MISSING** |
113
+ | Send Max and activity (2) | Funded HyperEVM/INK accounts and recipient | Send native Max; assert review amount, gas handling, completion, balance, and activity | **MISSING** |
114
+ | Bridge label, tracking, details (2) | Funded Monad account and a completed bridge route | Submit/open bridge activity; assert label, status tracking, route, fees, and details | **MISSING** |
115
+
116
+ ## Prioritized delivery order
117
+
118
+ 1. **Downloaded official artifact validation and launch — current target.**
119
+ Accept a local ZIP, trusted digest, and requested version from the
120
+ release-validation workflow; validate the manifest and extracted tree,
121
+ reuse a validated cache, and launch without modifying the source checkout
122
+ or original artifact. Prove onboarding, visible wallet import, normal popup
123
+ operation, and side-panel operation.
124
+ 2. **Aggregate Extension Perps snapshot — current target.** Add a typed,
125
+ read-only result for account, markets, positions, open orders, activity, and
126
+ watchlist, with selectors suitable for machine assertions. It is usable in
127
+ source-built runtimes that expose the background test hook; an untouched
128
+ production artifact must fail explicitly until it has a supported read-only
129
+ observation boundary.
130
+ 3. **Deterministic Perps start state.** Add setup-time, trace-visible provider
131
+ doubles and seeded balance, positions, limit orders, TP/SL, activity, and
132
+ watchlist. Keep setup outside the proof window and never mutate product
133
+ state to manufacture an assertion.
134
+ 4. **Complete Perps operations and assertions.** Add parameterized feature and
135
+ eligibility control, watchlist, rich order entry, position changes, margin,
136
+ TP/SL, deposits, withdrawals, activity filters, and stream recovery. Extend
137
+ shared Mobile/Extension vocabulary where both clients support the behavior.
138
+ 5. **Release-plan completion gate.** Validate canonical case IDs, verdict
139
+ counts, required evidence, and explicit remaining cases before reporting a
140
+ terminal result.
141
+ 6. **Assets and Networks domain surfaces.** Add shared network selection and
142
+ custom-network state first, then typed assets, balances, token import,
143
+ transaction/activity, NFT, DeFi, and non-EVM observations.
144
+ 7. **Swap and Bridge domain surface.** Add quote, route, submit, status,
145
+ balance-delta, and activity actions with explicit live-funds safeguards and
146
+ resumable sequential state.
147
+
148
+ Completing the two current targets does **not** provide full Perps parity. The
149
+ 64-case plan still depends on deterministic domain state, controlled provider
150
+ behavior, richer mutations and assertions, and a canonical completion gate.
@@ -1,5 +1,6 @@
1
1
  import { pathToFileURL } from 'node:url';
2
2
  import { dataTestId, marketSymbol, normalizeMarketSymbol, runAdapter, withExtensionPage } from '../platform/cdp.mjs';
3
+ import { readSnapshot } from './read_snapshot.mjs';
3
4
  import { readPerpsRuntimeStateExpression } from './state.mjs';
4
5
 
5
6
  function sleep(ms) {
@@ -832,6 +833,7 @@ export async function teardownState(input) {
832
833
  }
833
834
 
834
835
  const DIRECT_ACTIONS = new Map([
836
+ ['metamask.perps.read_snapshot', readSnapshot],
835
837
  ['metamask.perps.read_positions', readPositions],
836
838
  ['metamask.perps.read_orders', readOrders],
837
839
  ['metamask.perps.close_positions', closePositions],