@deeeed/metamask-harness 0.36.0 → 0.38.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.
- package/CHANGELOG.md +51 -0
- package/adapters/extension/artifact-runtime-state.cjs +138 -0
- package/adapters/extension/inject.mjs +2 -0
- package/adapters/extension/launch-browser.cjs +24 -0
- package/adapters/extension/live.sh +82 -12
- package/adapters/extension/readiness.mjs +77 -36
- package/adapters/extension/snapshot-dist.sh +88 -3
- package/adapters/extension/verify.sh +6 -2
- package/adapters/manifest.json +17 -1
- package/adapters/shared/log-tui.mjs +1 -1
- package/dist/adapters/extension/artifact-integrity.js +38 -0
- package/dist/adapters/extension/extension-id.js +23 -4
- package/dist/adapters/extension/release-artifact.js +386 -0
- package/dist/adapters/extension/runtime-decision.js +164 -20
- package/dist/adapters/extension/runtime.js +169 -3
- package/dist/adapters/mobile/provision.js +38 -3
- package/dist/adapters/mobile/release-artifact-state.js +124 -0
- package/dist/adapters/mobile/release-artifact.js +295 -0
- package/dist/adapters.js +78 -6
- package/dist/app-lifecycle.js +4 -3
- package/dist/command-contract.js +16 -0
- package/dist/commands/call.js +6 -2
- package/dist/commands/launch/extension.js +74 -9
- package/dist/commands/launch/index.js +3 -0
- package/dist/commands/launch/mobile.js +2 -0
- package/dist/commands/provision.js +2 -0
- package/dist/commands/run-engine.js +109 -14
- package/dist/commands/run.js +4 -2
- package/dist/commands/runtime-launch.js +178 -10
- package/dist/heal-bounds.js +1 -1
- package/dist/live-adapter-contract.js +3 -1
- package/dist/metamask-action-validation.js +47 -1
- package/dist/mm-harness-cli.js +31 -1
- package/dist/recipe-security.js +40 -0
- package/dist/run-diagnostics.js +1 -1
- package/dist/runner.js +3 -0
- package/docs/RELEASE-QA-CAPABILITY-MAP.md +125 -0
- package/library/actions/extension/assets/finish_send.mjs +128 -0
- package/library/actions/extension/assets/import_custom_token.mjs +227 -0
- package/library/actions/extension/assets/prepare_send.mjs +53 -0
- package/library/actions/extension/assets/read_details.mjs +57 -0
- package/library/actions/extension/assets/read_visible_state.mjs +50 -0
- package/library/actions/extension/assets/review_send.mjs +23 -0
- package/library/actions/extension/assets/select_network_scope.mjs +30 -0
- package/library/actions/extension/assets/send.mjs +104 -0
- package/library/actions/extension/assets/set_custom_gas.mjs +56 -0
- package/library/actions/extension/assets/set_token_visibility.mjs +129 -0
- package/library/actions/extension/assets/verify_sorting.mjs +89 -0
- package/library/actions/extension/networks/add_chainlist.mjs +94 -0
- package/library/actions/extension/networks/add_custom.mjs +123 -0
- package/library/actions/extension/networks/custom_network.mjs +103 -0
- package/library/actions/extension/networks/read_visible_state.mjs +50 -0
- package/library/actions/extension/networks/remove_custom.mjs +68 -0
- package/library/actions/extension/perps/close_orders.mjs +1 -0
- package/library/actions/extension/perps/close_visible_position.mjs +133 -0
- package/library/actions/extension/perps/compare_provider_market.mjs +109 -0
- package/library/actions/extension/perps/edit_margin.mjs +82 -0
- package/library/actions/extension/perps/open_balance_action.mjs +58 -0
- package/library/actions/extension/perps/open_position_action.mjs +80 -0
- package/library/actions/extension/perps/perps.mjs +196 -2
- package/library/actions/extension/perps/place_order.mjs +5 -2
- package/library/actions/extension/perps/read_eligibility.mjs +34 -0
- package/library/actions/extension/perps/read_funds_confirmation.mjs +69 -0
- package/library/actions/extension/perps/read_snapshot.mjs +470 -0
- package/library/actions/extension/perps/read_visible_state.mjs +98 -0
- package/library/actions/extension/perps/select_activity_filter.mjs +44 -0
- package/library/actions/extension/perps/select_market_filter.mjs +71 -0
- package/library/actions/extension/perps/set_market_favorite.mjs +47 -0
- package/library/actions/extension/perps/update_position_tpsl.mjs +106 -0
- package/library/actions/extension/platform/cdp.mjs +109 -3
- package/library/actions/extension/settings/set_basic_functionality.mjs +58 -0
- package/library/actions/extension/swap_bridge/read_visible_state.mjs +71 -0
- package/library/actions/extension/swap_bridge/select_assets.mjs +103 -0
- package/library/actions/extension/swap_bridge/set_amount.mjs +36 -0
- package/library/actions/extension/swap_bridge/set_max_amount.mjs +58 -0
- package/library/actions/extension/swap_bridge/set_slippage.mjs +121 -0
- package/library/actions/extension/swap_bridge/submit_transaction.mjs +363 -0
- package/library/actions/extension/ui/activate_and_observe.mjs +96 -0
- package/library/actions/extension/ui/navigate.mjs +264 -8
- package/library/actions/extension/wallet/ensure_unlocked.mjs +2 -6
- package/library/actions/extension/wallet/import.mjs +13 -46
- package/library/actions/extension/wallet/lock.mjs +35 -0
- package/library/actions/extension/wallet/secret-input.mjs +98 -0
- package/library/actions/extension/wallet/select_account.mjs +71 -7
- package/library/actions/mobile/assets/read_visible_state.mjs +37 -0
- package/library/actions/mobile/perps/read_visible_state.mjs +31 -0
- package/library/actions/mobile/platform/native-session-name.mjs +5 -0
- package/library/actions/mobile/platform/observe-ui.mjs +86 -2
- package/library/actions/mobile/swap_bridge/native-session.mjs +45 -0
- package/library/actions/mobile/swap_bridge/read_visible_state.mjs +31 -0
- package/library/actions/mobile/swap_bridge/select_assets.mjs +94 -0
- package/library/actions/mobile/swap_bridge/set_amount.mjs +73 -0
- package/library/actions/mobile/ui/native-navigation.mjs +265 -0
- package/library/actions/mobile/ui/navigate.mjs +10 -1
- package/library/actions/mobile/wallet/ensure_unlocked.mjs +17 -0
- package/library/actions/mobile/wallet/import.mjs +71 -2
- package/library/actions/mobile/wallet/native-ui.mjs +512 -0
- package/library/actions/mobile/wallet/read_state.mjs +16 -0
- package/library/actions/mobile/wallet/reset.mjs +17 -4
- package/library/actions/shared/assets/visible-state.mjs +176 -0
- package/library/actions/shared/networks/visible-state.mjs +70 -0
- package/library/actions/shared/perps/visible-state.mjs +354 -0
- package/library/actions/shared/swap-bridge/transaction.mjs +54 -0
- package/library/actions/shared/swap-bridge/visible-state.mjs +97 -0
- package/library/actions/shared/ui/locators.mjs +7 -0
- package/library/manifests/extension.action-manifest.json +1366 -184
- package/library/manifests/mobile.action-manifest.json +235 -1
- package/library/recipes/assets/release-custom-gas-send.recipe.json +88 -0
- package/library/recipes/assets/release-custom-network-token-persistence.recipe.json +106 -0
- package/library/recipes/assets/release-native-max-cancel.recipe.json +70 -0
- package/library/recipes/assets/release-native-max-send.recipe.json +78 -0
- package/library/recipes/assets/release-own-account-send.recipe.json +80 -0
- package/library/recipes/assets/release-token-address-import.recipe.json +47 -0
- package/library/recipes/assets/release-token-details.recipe.json +48 -0
- package/library/recipes/assets/release-token-hide-readd.recipe.json +55 -0
- package/library/recipes/assets/release-token-list.recipe.json +75 -0
- package/library/recipes/assets/release-token-persistence.recipe.json +73 -0
- package/library/recipes/assets/release-token-search-import.recipe.json +40 -0
- package/library/recipes/assets/release-token-sorting.recipe.json +29 -0
- package/library/recipes/extension/networks/release-balance-stability.recipe.json +51 -0
- package/library/recipes/extension/perps/release-live-limit-order.recipe.json +104 -0
- package/library/recipes/extension/perps/release-order-entry.recipe.json +155 -0
- package/library/recipes/extension/perps/release-order-validation.recipe.json +220 -0
- package/library/recipes/extension/runner/action-validation.recipe.json +12 -1
- package/library/recipes/perps/release-activity-filters.recipe.json +51 -0
- package/library/recipes/perps/release-funds-flows.recipe.json +76 -0
- package/library/recipes/perps/release-live-market-order.recipe.json +122 -0
- package/library/recipes/perps/release-market-details.recipe.json +83 -0
- package/library/recipes/perps/release-market-search.recipe.json +79 -0
- package/library/recipes/perps/release-watchlist.recipe.json +99 -0
- package/library/recipes/swap-bridge/release-custom-slippage.recipe.json +90 -0
- package/library/recipes/swap-bridge/release-live-max-swap.recipe.json +99 -0
- package/library/recipes/swap-bridge/release-live-swap.recipe.json +101 -0
- package/library/recipes/swap-bridge/release-max-quote.recipe.json +72 -0
- package/library/recipes/swap-bridge/release-quote.recipe.json +72 -0
- package/library/recipes/swap-bridge/release-surface.recipe.json +43 -0
- package/library/recipes/wallet/import.recipe.json +20 -1
- package/library/recipes/wallet/reset-import.recipe.json +20 -1
- package/package.json +6 -5
- package/scripts/validate-release-report.mjs +319 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Perps release order entry",
|
|
4
|
+
"description": "Exercises the live Perps order form through semantic visible controls without submitting an order.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"market": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"default": "BTC"
|
|
12
|
+
},
|
|
13
|
+
"amount": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"default": "10"
|
|
16
|
+
},
|
|
17
|
+
"leverage": {
|
|
18
|
+
"type": "string",
|
|
19
|
+
"default": "5"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"workflow": {
|
|
24
|
+
"entry": "open-perps",
|
|
25
|
+
"nodes": {
|
|
26
|
+
"open-perps": {
|
|
27
|
+
"action": "ui.navigate",
|
|
28
|
+
"page": "perps",
|
|
29
|
+
"intent": "Reset transient Perps navigation state",
|
|
30
|
+
"next": "open-market-list"
|
|
31
|
+
},
|
|
32
|
+
"open-market-list": {
|
|
33
|
+
"action": "ui.navigate",
|
|
34
|
+
"page": "perps-market-list",
|
|
35
|
+
"intent": "Show the live Perps market list",
|
|
36
|
+
"next": "open-market"
|
|
37
|
+
},
|
|
38
|
+
"open-market": {
|
|
39
|
+
"action": "ui.navigate",
|
|
40
|
+
"page": "perps-market",
|
|
41
|
+
"market": "{{params.market}}",
|
|
42
|
+
"intent": "Open the requested Perps market",
|
|
43
|
+
"next": "open-long"
|
|
44
|
+
},
|
|
45
|
+
"open-long": {
|
|
46
|
+
"action": "ui.press",
|
|
47
|
+
"test_id": "perps-long-cta-button",
|
|
48
|
+
"intent": "Open a new long market order",
|
|
49
|
+
"next": "wait-order-entry"
|
|
50
|
+
},
|
|
51
|
+
"wait-order-entry": {
|
|
52
|
+
"action": "ui.wait_for",
|
|
53
|
+
"test_id": "perps-order-entry-page",
|
|
54
|
+
"expected": "visible",
|
|
55
|
+
"timeout_ms": 10000,
|
|
56
|
+
"intent": "Confirm the order form finished opening",
|
|
57
|
+
"next": "assert-long"
|
|
58
|
+
},
|
|
59
|
+
"assert-long": {
|
|
60
|
+
"action": "metamask.perps.read_visible_state",
|
|
61
|
+
"surface": "order-entry",
|
|
62
|
+
"market": "{{params.market}}",
|
|
63
|
+
"direction": "long",
|
|
64
|
+
"order_type": "market",
|
|
65
|
+
"require_test_ids": [
|
|
66
|
+
"direction-tab-long",
|
|
67
|
+
"direction-tab-short",
|
|
68
|
+
"order-type-market",
|
|
69
|
+
"order-type-limit",
|
|
70
|
+
"amount-input-field",
|
|
71
|
+
"leverage-input",
|
|
72
|
+
"auto-close-toggle",
|
|
73
|
+
"submit-order-button"
|
|
74
|
+
],
|
|
75
|
+
"max_items": 150,
|
|
76
|
+
"intent": "Prove the long market form and its semantic controls",
|
|
77
|
+
"next": "set-amount"
|
|
78
|
+
},
|
|
79
|
+
"set-amount": {
|
|
80
|
+
"action": "ui.set_input",
|
|
81
|
+
"selector": "[data-testid=\"amount-input-field\"] input",
|
|
82
|
+
"value": "{{params.amount}}",
|
|
83
|
+
"intent": "Enter the USD order amount through the amount field",
|
|
84
|
+
"next": "set-leverage"
|
|
85
|
+
},
|
|
86
|
+
"set-leverage": {
|
|
87
|
+
"action": "ui.set_input",
|
|
88
|
+
"selector": "[data-testid=\"leverage-input\"] input",
|
|
89
|
+
"value": "{{params.leverage}}",
|
|
90
|
+
"intent": "Enter leverage through the leverage field",
|
|
91
|
+
"next": "assert-configured"
|
|
92
|
+
},
|
|
93
|
+
"assert-configured": {
|
|
94
|
+
"action": "metamask.perps.read_visible_state",
|
|
95
|
+
"surface": "order-entry",
|
|
96
|
+
"market": "{{params.market}}",
|
|
97
|
+
"direction": "long",
|
|
98
|
+
"order_type": "market",
|
|
99
|
+
"amount": "{{params.amount}}",
|
|
100
|
+
"leverage": "{{params.leverage}}",
|
|
101
|
+
"submit_enabled": true,
|
|
102
|
+
"max_items": 150,
|
|
103
|
+
"intent": "Prove amount, leverage, and submit eligibility update together",
|
|
104
|
+
"next": "select-short"
|
|
105
|
+
},
|
|
106
|
+
"select-short": {
|
|
107
|
+
"action": "ui.press",
|
|
108
|
+
"test_id": "direction-tab-short",
|
|
109
|
+
"intent": "Switch the same order form to Short",
|
|
110
|
+
"next": "assert-short"
|
|
111
|
+
},
|
|
112
|
+
"assert-short": {
|
|
113
|
+
"action": "metamask.perps.read_visible_state",
|
|
114
|
+
"surface": "order-entry",
|
|
115
|
+
"market": "{{params.market}}",
|
|
116
|
+
"direction": "short",
|
|
117
|
+
"order_type": "market",
|
|
118
|
+
"amount": "{{params.amount}}",
|
|
119
|
+
"submit_enabled": true,
|
|
120
|
+
"max_items": 150,
|
|
121
|
+
"intent": "Prove direction changes without losing configured values",
|
|
122
|
+
"next": "select-limit"
|
|
123
|
+
},
|
|
124
|
+
"select-limit": {
|
|
125
|
+
"action": "ui.press",
|
|
126
|
+
"test_id": "order-type-limit",
|
|
127
|
+
"intent": "Switch the order form to Limit",
|
|
128
|
+
"next": "assert-limit"
|
|
129
|
+
},
|
|
130
|
+
"assert-limit": {
|
|
131
|
+
"action": "metamask.perps.read_visible_state",
|
|
132
|
+
"surface": "order-entry",
|
|
133
|
+
"market": "{{params.market}}",
|
|
134
|
+
"direction": "short",
|
|
135
|
+
"order_type": "limit",
|
|
136
|
+
"amount": "{{params.amount}}",
|
|
137
|
+
"require_test_ids": ["limit-price-input", "limit-price-mid-button"],
|
|
138
|
+
"max_items": 150,
|
|
139
|
+
"intent": "Prove Limit mode exposes its price controls",
|
|
140
|
+
"next": "capture"
|
|
141
|
+
},
|
|
142
|
+
"capture": {
|
|
143
|
+
"action": "ui.screenshot",
|
|
144
|
+
"path": "screenshots/perps-order-entry.png",
|
|
145
|
+
"label": "Perps release order entry",
|
|
146
|
+
"intent": "Preserve reviewer-visible proof of the configured order form",
|
|
147
|
+
"next": "done"
|
|
148
|
+
},
|
|
149
|
+
"done": {
|
|
150
|
+
"action": "end",
|
|
151
|
+
"status": "pass"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Perps release order validation",
|
|
4
|
+
"description": "Exercises Perps minimum amount, percent, leverage, keyboard, and auto-close validation through semantic visible controls without submitting an order.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"properties": {
|
|
9
|
+
"market": {
|
|
10
|
+
"type": "string",
|
|
11
|
+
"default": "BTC"
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"workflow": {
|
|
16
|
+
"entry": "open-perps",
|
|
17
|
+
"nodes": {
|
|
18
|
+
"open-perps": {
|
|
19
|
+
"action": "ui.navigate",
|
|
20
|
+
"page": "perps",
|
|
21
|
+
"intent": "Reset transient Perps navigation state",
|
|
22
|
+
"next": "open-market-list"
|
|
23
|
+
},
|
|
24
|
+
"open-market-list": {
|
|
25
|
+
"action": "ui.navigate",
|
|
26
|
+
"page": "perps-market-list",
|
|
27
|
+
"intent": "Show the live Perps market list",
|
|
28
|
+
"next": "open-market"
|
|
29
|
+
},
|
|
30
|
+
"open-market": {
|
|
31
|
+
"action": "ui.navigate",
|
|
32
|
+
"page": "perps-market",
|
|
33
|
+
"market": "{{params.market}}",
|
|
34
|
+
"intent": "Open the requested Perps market",
|
|
35
|
+
"next": "open-long"
|
|
36
|
+
},
|
|
37
|
+
"open-long": {
|
|
38
|
+
"action": "ui.press",
|
|
39
|
+
"test_id": "perps-long-cta-button",
|
|
40
|
+
"intent": "Open a new long market order",
|
|
41
|
+
"next": "wait-order-entry"
|
|
42
|
+
},
|
|
43
|
+
"wait-order-entry": {
|
|
44
|
+
"action": "ui.wait_for",
|
|
45
|
+
"test_id": "perps-order-entry-page",
|
|
46
|
+
"expected": "visible",
|
|
47
|
+
"timeout_ms": 10000,
|
|
48
|
+
"intent": "Confirm the order form finished opening",
|
|
49
|
+
"next": "enter-below-minimum"
|
|
50
|
+
},
|
|
51
|
+
"enter-below-minimum": {
|
|
52
|
+
"action": "ui.set_input",
|
|
53
|
+
"selector": "[data-testid=\"amount-input-field\"] input",
|
|
54
|
+
"value": "1",
|
|
55
|
+
"intent": "Enter an amount below the market minimum",
|
|
56
|
+
"next": "assert-below-minimum"
|
|
57
|
+
},
|
|
58
|
+
"assert-below-minimum": {
|
|
59
|
+
"action": "metamask.perps.read_visible_state",
|
|
60
|
+
"surface": "order-entry",
|
|
61
|
+
"market": "{{params.market}}",
|
|
62
|
+
"direction": "long",
|
|
63
|
+
"order_type": "market",
|
|
64
|
+
"amount": "1",
|
|
65
|
+
"submit_enabled": false,
|
|
66
|
+
"max_items": 150,
|
|
67
|
+
"intent": "Prove the below-minimum amount cannot be submitted",
|
|
68
|
+
"next": "enter-valid-amount"
|
|
69
|
+
},
|
|
70
|
+
"enter-valid-amount": {
|
|
71
|
+
"action": "ui.set_input",
|
|
72
|
+
"selector": "[data-testid=\"amount-input-field\"] input",
|
|
73
|
+
"value": "10",
|
|
74
|
+
"intent": "Enter the minimum valid USD amount",
|
|
75
|
+
"next": "enter-percent"
|
|
76
|
+
},
|
|
77
|
+
"enter-percent": {
|
|
78
|
+
"action": "ui.set_input",
|
|
79
|
+
"selector": "[data-testid=\"balance-percent-input\"] input",
|
|
80
|
+
"value": "50",
|
|
81
|
+
"intent": "Enter a midpoint balance percentage",
|
|
82
|
+
"next": "assert-percent"
|
|
83
|
+
},
|
|
84
|
+
"assert-percent": {
|
|
85
|
+
"action": "metamask.perps.read_visible_state",
|
|
86
|
+
"surface": "order-entry",
|
|
87
|
+
"market": "{{params.market}}",
|
|
88
|
+
"direction": "long",
|
|
89
|
+
"order_type": "market",
|
|
90
|
+
"percent": "50",
|
|
91
|
+
"submit_enabled": true,
|
|
92
|
+
"max_items": 150,
|
|
93
|
+
"intent": "Prove percent input updates a valid order summary",
|
|
94
|
+
"next": "enter-min-leverage"
|
|
95
|
+
},
|
|
96
|
+
"enter-min-leverage": {
|
|
97
|
+
"action": "ui.set_input",
|
|
98
|
+
"selector": "[data-testid=\"leverage-input\"] input",
|
|
99
|
+
"value": "1",
|
|
100
|
+
"intent": "Enter minimum leverage",
|
|
101
|
+
"next": "assert-min-leverage"
|
|
102
|
+
},
|
|
103
|
+
"assert-min-leverage": {
|
|
104
|
+
"action": "metamask.perps.read_visible_state",
|
|
105
|
+
"surface": "order-entry",
|
|
106
|
+
"market": "{{params.market}}",
|
|
107
|
+
"leverage": "1",
|
|
108
|
+
"max_items": 150,
|
|
109
|
+
"intent": "Prove minimum leverage is accepted",
|
|
110
|
+
"next": "raise-with-keyboard"
|
|
111
|
+
},
|
|
112
|
+
"raise-with-keyboard": {
|
|
113
|
+
"action": "ui.key_press",
|
|
114
|
+
"key": "ArrowUp",
|
|
115
|
+
"intent": "Raise leverage with the keyboard",
|
|
116
|
+
"next": "assert-keyboard-leverage"
|
|
117
|
+
},
|
|
118
|
+
"assert-keyboard-leverage": {
|
|
119
|
+
"action": "metamask.perps.read_visible_state",
|
|
120
|
+
"surface": "order-entry",
|
|
121
|
+
"market": "{{params.market}}",
|
|
122
|
+
"leverage": "2",
|
|
123
|
+
"max_items": 150,
|
|
124
|
+
"intent": "Prove the keyboard changes leverage by one step",
|
|
125
|
+
"next": "enter-max-leverage"
|
|
126
|
+
},
|
|
127
|
+
"enter-max-leverage": {
|
|
128
|
+
"action": "ui.set_input",
|
|
129
|
+
"selector": "[data-testid=\"leverage-input\"] input",
|
|
130
|
+
"value": "40",
|
|
131
|
+
"intent": "Enter the market maximum leverage",
|
|
132
|
+
"next": "assert-max-leverage"
|
|
133
|
+
},
|
|
134
|
+
"assert-max-leverage": {
|
|
135
|
+
"action": "metamask.perps.read_visible_state",
|
|
136
|
+
"surface": "order-entry",
|
|
137
|
+
"market": "{{params.market}}",
|
|
138
|
+
"leverage": "40",
|
|
139
|
+
"max_items": 150,
|
|
140
|
+
"intent": "Prove maximum leverage is accepted",
|
|
141
|
+
"next": "enable-auto-close"
|
|
142
|
+
},
|
|
143
|
+
"enable-auto-close": {
|
|
144
|
+
"action": "ui.press",
|
|
145
|
+
"selector": "label:has([data-testid=\"auto-close-toggle\"])",
|
|
146
|
+
"intent": "Enable take-profit and stop-loss controls",
|
|
147
|
+
"next": "assert-auto-close"
|
|
148
|
+
},
|
|
149
|
+
"assert-auto-close": {
|
|
150
|
+
"action": "metamask.perps.read_visible_state",
|
|
151
|
+
"surface": "order-entry",
|
|
152
|
+
"market": "{{params.market}}",
|
|
153
|
+
"auto_close": true,
|
|
154
|
+
"require_test_ids": [
|
|
155
|
+
"tp-price-input",
|
|
156
|
+
"tp-percent-input",
|
|
157
|
+
"sl-price-input",
|
|
158
|
+
"sl-percent-input"
|
|
159
|
+
],
|
|
160
|
+
"max_items": 150,
|
|
161
|
+
"intent": "Prove auto-close exposes linked take-profit and stop-loss fields",
|
|
162
|
+
"next": "enter-invalid-take-profit"
|
|
163
|
+
},
|
|
164
|
+
"enter-invalid-take-profit": {
|
|
165
|
+
"action": "ui.set_input",
|
|
166
|
+
"selector": "[data-testid=\"tp-price-input\"] input",
|
|
167
|
+
"value": "1000",
|
|
168
|
+
"intent": "Enter a take-profit below the long entry price",
|
|
169
|
+
"next": "assert-invalid-take-profit"
|
|
170
|
+
},
|
|
171
|
+
"assert-invalid-take-profit": {
|
|
172
|
+
"action": "metamask.perps.read_visible_state",
|
|
173
|
+
"surface": "order-entry",
|
|
174
|
+
"market": "{{params.market}}",
|
|
175
|
+
"auto_close": true,
|
|
176
|
+
"submit_enabled": false,
|
|
177
|
+
"require_test_ids": ["tp-validation-error"],
|
|
178
|
+
"max_items": 150,
|
|
179
|
+
"intent": "Prove an unsafe long take-profit is blocked",
|
|
180
|
+
"next": "enter-valid-take-profit"
|
|
181
|
+
},
|
|
182
|
+
"enter-valid-take-profit": {
|
|
183
|
+
"action": "ui.set_input",
|
|
184
|
+
"selector": "[data-testid=\"tp-price-input\"] input",
|
|
185
|
+
"value": "70000",
|
|
186
|
+
"intent": "Enter a take-profit above the long entry price",
|
|
187
|
+
"next": "enter-invalid-stop-loss"
|
|
188
|
+
},
|
|
189
|
+
"enter-invalid-stop-loss": {
|
|
190
|
+
"action": "ui.set_input",
|
|
191
|
+
"selector": "[data-testid=\"sl-price-input\"] input",
|
|
192
|
+
"value": "100000",
|
|
193
|
+
"intent": "Enter a stop-loss above the long entry price",
|
|
194
|
+
"next": "assert-invalid-stop-loss"
|
|
195
|
+
},
|
|
196
|
+
"assert-invalid-stop-loss": {
|
|
197
|
+
"action": "metamask.perps.read_visible_state",
|
|
198
|
+
"surface": "order-entry",
|
|
199
|
+
"market": "{{params.market}}",
|
|
200
|
+
"auto_close": true,
|
|
201
|
+
"submit_enabled": false,
|
|
202
|
+
"require_test_ids": ["sl-validation-error"],
|
|
203
|
+
"max_items": 150,
|
|
204
|
+
"intent": "Prove an unsafe long stop-loss is blocked",
|
|
205
|
+
"next": "capture"
|
|
206
|
+
},
|
|
207
|
+
"capture": {
|
|
208
|
+
"action": "ui.screenshot",
|
|
209
|
+
"path": "screenshots/perps-order-validation.png",
|
|
210
|
+
"label": "Perps release order validation",
|
|
211
|
+
"intent": "Preserve reviewer-visible proof of the validation controls",
|
|
212
|
+
"next": "done"
|
|
213
|
+
},
|
|
214
|
+
"done": {
|
|
215
|
+
"action": "end",
|
|
216
|
+
"status": "pass"
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
@@ -158,11 +158,22 @@
|
|
|
158
158
|
},
|
|
159
159
|
"perps-navigate-market": {
|
|
160
160
|
"action": "ui.navigate",
|
|
161
|
-
"next": "
|
|
161
|
+
"next": "read-snapshot",
|
|
162
162
|
"intent": "Show the ETH Perps market details",
|
|
163
163
|
"page": "perps-market",
|
|
164
164
|
"market": "ETH"
|
|
165
165
|
},
|
|
166
|
+
"read-snapshot": {
|
|
167
|
+
"action": "metamask.perps.read_snapshot",
|
|
168
|
+
"include": [
|
|
169
|
+
"markets"
|
|
170
|
+
],
|
|
171
|
+
"markets": [
|
|
172
|
+
"ETH"
|
|
173
|
+
],
|
|
174
|
+
"next": "start-state",
|
|
175
|
+
"intent": "Read a bounded live Perps market snapshot"
|
|
176
|
+
},
|
|
166
177
|
"ensure-clean": {
|
|
167
178
|
"action": "metamask.perps.ensure_positions",
|
|
168
179
|
"market": "ETH",
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Perps release activity filters",
|
|
4
|
+
"description": "Opens live Perps activity and exercises the Trades, Orders, Funding, and Deposits filters through semantic visible controls.",
|
|
5
|
+
"workflow": {
|
|
6
|
+
"entry": "open-activity",
|
|
7
|
+
"nodes": {
|
|
8
|
+
"open-activity": {
|
|
9
|
+
"action": "ui.navigate",
|
|
10
|
+
"page": "perps-activity",
|
|
11
|
+
"intent": "Open the full live Perps activity surface",
|
|
12
|
+
"next": "trades"
|
|
13
|
+
},
|
|
14
|
+
"trades": {
|
|
15
|
+
"action": "metamask.perps.select_activity_filter",
|
|
16
|
+
"filter": "trades",
|
|
17
|
+
"intent": "Show only trade-related Perps activity",
|
|
18
|
+
"next": "orders"
|
|
19
|
+
},
|
|
20
|
+
"orders": {
|
|
21
|
+
"action": "metamask.perps.select_activity_filter",
|
|
22
|
+
"filter": "orders",
|
|
23
|
+
"intent": "Show only order-related Perps activity",
|
|
24
|
+
"next": "funding"
|
|
25
|
+
},
|
|
26
|
+
"funding": {
|
|
27
|
+
"action": "metamask.perps.select_activity_filter",
|
|
28
|
+
"filter": "funding",
|
|
29
|
+
"intent": "Show only Perps funding activity",
|
|
30
|
+
"next": "deposits"
|
|
31
|
+
},
|
|
32
|
+
"deposits": {
|
|
33
|
+
"action": "metamask.perps.select_activity_filter",
|
|
34
|
+
"filter": "deposits",
|
|
35
|
+
"intent": "Show only Perps deposit and withdrawal activity",
|
|
36
|
+
"next": "capture"
|
|
37
|
+
},
|
|
38
|
+
"capture": {
|
|
39
|
+
"action": "ui.screenshot",
|
|
40
|
+
"path": "screenshots/perps-activity-filters.png",
|
|
41
|
+
"label": "Perps activity filters",
|
|
42
|
+
"intent": "Preserve reviewer-visible proof of the activity surface",
|
|
43
|
+
"next": "done"
|
|
44
|
+
},
|
|
45
|
+
"done": {
|
|
46
|
+
"action": "end",
|
|
47
|
+
"status": "pass"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Perps release funds flows",
|
|
4
|
+
"description": "Opens the live Perps deposit and withdraw confirmations, proves their loaded amount contexts, and dismisses each without submitting funds.",
|
|
5
|
+
"workflow": {
|
|
6
|
+
"entry": "open-perps-deposit",
|
|
7
|
+
"nodes": {
|
|
8
|
+
"open-perps-deposit": {
|
|
9
|
+
"action": "ui.navigate",
|
|
10
|
+
"page": "perps",
|
|
11
|
+
"intent": "Show Perps home before opening Add funds",
|
|
12
|
+
"next": "open-deposit"
|
|
13
|
+
},
|
|
14
|
+
"open-deposit": {
|
|
15
|
+
"action": "metamask.perps.open_balance_action",
|
|
16
|
+
"balance_action": "add-funds",
|
|
17
|
+
"intent": "Open the Perps Add funds confirmation",
|
|
18
|
+
"next": "read-deposit"
|
|
19
|
+
},
|
|
20
|
+
"read-deposit": {
|
|
21
|
+
"action": "metamask.perps.read_funds_confirmation",
|
|
22
|
+
"mode": "deposit",
|
|
23
|
+
"intent": "Prove the deposit amount, token, fee, and time context loaded",
|
|
24
|
+
"next": "dismiss-deposit"
|
|
25
|
+
},
|
|
26
|
+
"dismiss-deposit": {
|
|
27
|
+
"action": "ui.press",
|
|
28
|
+
"test_id": "wallet-initiated-header-back-button",
|
|
29
|
+
"intent": "Dismiss the deposit without submitting funds",
|
|
30
|
+
"next": "open-perps-withdraw"
|
|
31
|
+
},
|
|
32
|
+
"open-perps-withdraw": {
|
|
33
|
+
"action": "ui.navigate",
|
|
34
|
+
"page": "perps",
|
|
35
|
+
"intent": "Show Perps home before opening Withdraw",
|
|
36
|
+
"next": "open-withdraw"
|
|
37
|
+
},
|
|
38
|
+
"open-withdraw": {
|
|
39
|
+
"action": "metamask.perps.open_balance_action",
|
|
40
|
+
"balance_action": "withdraw",
|
|
41
|
+
"intent": "Open the Perps Withdraw confirmation",
|
|
42
|
+
"next": "read-withdraw"
|
|
43
|
+
},
|
|
44
|
+
"read-withdraw": {
|
|
45
|
+
"action": "metamask.perps.read_funds_confirmation",
|
|
46
|
+
"mode": "withdraw",
|
|
47
|
+
"intent": "Prove available balance, receive token, fee, time, and final amount loaded",
|
|
48
|
+
"next": "enter-zero"
|
|
49
|
+
},
|
|
50
|
+
"enter-zero": {
|
|
51
|
+
"action": "ui.set_input",
|
|
52
|
+
"test_id": "custom-amount-input",
|
|
53
|
+
"value": "0",
|
|
54
|
+
"intent": "Enter zero to exercise withdrawal validation",
|
|
55
|
+
"next": "assert-zero"
|
|
56
|
+
},
|
|
57
|
+
"assert-zero": {
|
|
58
|
+
"action": "metamask.perps.read_funds_confirmation",
|
|
59
|
+
"mode": "withdraw",
|
|
60
|
+
"expected_submit_enabled": false,
|
|
61
|
+
"intent": "Prove zero remains non-submittable",
|
|
62
|
+
"next": "dismiss-withdraw"
|
|
63
|
+
},
|
|
64
|
+
"dismiss-withdraw": {
|
|
65
|
+
"action": "ui.press",
|
|
66
|
+
"test_id": "wallet-initiated-header-back-button",
|
|
67
|
+
"intent": "Dismiss the withdrawal without submitting funds",
|
|
68
|
+
"next": "done"
|
|
69
|
+
},
|
|
70
|
+
"done": {
|
|
71
|
+
"action": "end",
|
|
72
|
+
"status": "pass"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://farmslot.io/schemas/recipe-v1.schema.json",
|
|
3
|
+
"title": "Perps release live market order",
|
|
4
|
+
"description": "Places one small live Perps market order through visible product controls and proves the resulting position and activity.",
|
|
5
|
+
"paramsSchema": {
|
|
6
|
+
"type": "object",
|
|
7
|
+
"additionalProperties": false,
|
|
8
|
+
"required": ["confirm_live"],
|
|
9
|
+
"properties": {
|
|
10
|
+
"market": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"default": "BTC"
|
|
13
|
+
},
|
|
14
|
+
"amount": {
|
|
15
|
+
"type": "integer",
|
|
16
|
+
"minimum": 10,
|
|
17
|
+
"default": 10
|
|
18
|
+
},
|
|
19
|
+
"leverage": {
|
|
20
|
+
"type": "integer",
|
|
21
|
+
"minimum": 1,
|
|
22
|
+
"default": 3
|
|
23
|
+
},
|
|
24
|
+
"confirm_live": {
|
|
25
|
+
"type": "boolean"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"workflow": {
|
|
30
|
+
"entry": "open-perps",
|
|
31
|
+
"nodes": {
|
|
32
|
+
"open-perps": {
|
|
33
|
+
"action": "ui.navigate",
|
|
34
|
+
"page": "perps",
|
|
35
|
+
"intent": "Show the live Perps home surface",
|
|
36
|
+
"next": "assert-clean"
|
|
37
|
+
},
|
|
38
|
+
"assert-clean": {
|
|
39
|
+
"action": "metamask.perps.read_visible_state",
|
|
40
|
+
"surface": "home",
|
|
41
|
+
"maximum_position_count": 0,
|
|
42
|
+
"require_features": ["balance", "market-list"],
|
|
43
|
+
"max_items": 150,
|
|
44
|
+
"intent": "Prove there is no open position before placing the order",
|
|
45
|
+
"next": "open-market-list"
|
|
46
|
+
},
|
|
47
|
+
"open-market-list": {
|
|
48
|
+
"action": "ui.navigate",
|
|
49
|
+
"page": "perps-market-list",
|
|
50
|
+
"intent": "Show the live Perps market list",
|
|
51
|
+
"next": "open-market"
|
|
52
|
+
},
|
|
53
|
+
"open-market": {
|
|
54
|
+
"action": "ui.navigate",
|
|
55
|
+
"page": "perps-market",
|
|
56
|
+
"market": "{{params.market}}",
|
|
57
|
+
"intent": "Open the requested Perps market",
|
|
58
|
+
"next": "submit-once"
|
|
59
|
+
},
|
|
60
|
+
"submit-once": {
|
|
61
|
+
"action": "metamask.perps.place_order",
|
|
62
|
+
"market": "{{params.market}}",
|
|
63
|
+
"side": "long",
|
|
64
|
+
"amount": "{{params.amount}}",
|
|
65
|
+
"leverage": "{{params.leverage}}",
|
|
66
|
+
"order_type": "market",
|
|
67
|
+
"confirm_live": "{{params.confirm_live}}",
|
|
68
|
+
"timeout_ms": 45000,
|
|
69
|
+
"intent": "Submit the authorized order exactly once",
|
|
70
|
+
"next": "wait-position"
|
|
71
|
+
},
|
|
72
|
+
"wait-position": {
|
|
73
|
+
"action": "ui.wait_for",
|
|
74
|
+
"test_id": "perps-position-size-value",
|
|
75
|
+
"expected": "visible",
|
|
76
|
+
"timeout_ms": 45000,
|
|
77
|
+
"intent": "Confirm the filled position becomes visible",
|
|
78
|
+
"next": "assert-position"
|
|
79
|
+
},
|
|
80
|
+
"assert-position": {
|
|
81
|
+
"action": "metamask.perps.read_visible_state",
|
|
82
|
+
"surface": "market-details",
|
|
83
|
+
"market": "{{params.market}}",
|
|
84
|
+
"minimum_position_count": 1,
|
|
85
|
+
"maximum_order_count": 0,
|
|
86
|
+
"minimum_activity_count": 1,
|
|
87
|
+
"require_test_ids": ["perps-position-size-value", "perps-position-leverage"],
|
|
88
|
+
"max_items": 150,
|
|
89
|
+
"intent": "Prove the filled position appears once with market activity",
|
|
90
|
+
"next": "capture-open"
|
|
91
|
+
},
|
|
92
|
+
"capture-open": {
|
|
93
|
+
"action": "ui.screenshot",
|
|
94
|
+
"path": "screenshots/perps-live-position.png",
|
|
95
|
+
"label": "Perps live position",
|
|
96
|
+
"intent": "Preserve reviewer-visible proof of the filled live position",
|
|
97
|
+
"next": "close-position"
|
|
98
|
+
},
|
|
99
|
+
"close-position": {
|
|
100
|
+
"action": "metamask.perps.close_visible_position",
|
|
101
|
+
"market": "{{params.market}}",
|
|
102
|
+
"confirm_live": "{{params.confirm_live}}",
|
|
103
|
+
"intent": "Close the live position after proving it",
|
|
104
|
+
"next": "assert-closed"
|
|
105
|
+
},
|
|
106
|
+
"assert-closed": {
|
|
107
|
+
"action": "metamask.perps.read_visible_state",
|
|
108
|
+
"surface": "market-details",
|
|
109
|
+
"market": "{{params.market}}",
|
|
110
|
+
"maximum_position_count": 0,
|
|
111
|
+
"minimum_activity_count": 1,
|
|
112
|
+
"max_items": 150,
|
|
113
|
+
"intent": "Prove the position was removed and close activity was recorded",
|
|
114
|
+
"next": "done"
|
|
115
|
+
},
|
|
116
|
+
"done": {
|
|
117
|
+
"action": "end",
|
|
118
|
+
"status": "pass"
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|