@deeeed/metamask-harness 0.15.1 → 0.15.2

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 CHANGED
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.15.2 - 2026-07-13
6
+
7
+ ### Fixed
8
+
9
+ - Mobile `ui.press text=<visible text>` now invokes the app bridge's text-content press path, while `test_id`, `testID`, and `selector` continue to use exact testID matching; ambiguous target combinations fail before bridge execution.
10
+
5
11
  ## 0.15.1 - 2026-07-13
6
12
 
7
13
  ### Fixed
@@ -254,6 +254,21 @@ const COMMANDS = {
254
254
  return { ...result, testId, deviceName };
255
255
  },
256
256
 
257
+ async 'press-text'(client, args, { deviceName } = {}) {
258
+ const text = args[0];
259
+ if (!text) {
260
+ throw new Error('Usage: press-text <text>');
261
+ }
262
+ const expr = `(function() {
263
+ if (typeof globalThis.__AGENTIC__?.pressText !== 'function') {
264
+ return { ok: false, error: 'The app bridge does not expose pressText' };
265
+ }
266
+ return globalThis.__AGENTIC__.pressText(${JSON.stringify(text)});
267
+ })()`;
268
+ const result = await cdpEval(client, expr);
269
+ return { ...result, text, deviceName };
270
+ },
271
+
257
272
  async 'scroll-view'(client, args, { deviceName } = {}) {
258
273
  let testId;
259
274
  let offset = 300;
@@ -678,6 +693,7 @@ Commands:
678
693
  get-selected-account Get the currently selected account
679
694
  switch-account <address> Switch to account by address
680
695
  press-test-id <testId> Press a component by its testID prop
696
+ press-text <text> Press a component containing visible text
681
697
  scroll-view [--test-id <id>] [--offset <n>] [--animated]
682
698
  Scroll a ScrollView/FlatList
683
699
  set-input <testId> <value> Set text input value by testID (calls onChangeText)
package/dist/adapters.js CHANGED
@@ -287,8 +287,15 @@ async function handleMobileNavigate(payload, context) {
287
287
  return isRecord(live.result) ? { ...live.result, liveAdapter: live.script } : live.result;
288
288
  }
289
289
  async function handleMobilePress(payload, context) {
290
- const target = firstScalarText(payload, ["test_id", "testID", "selector", "text"], "ui.press");
291
- return bridgeCommand(mobileUiInput(context, "press", payload), ["press-test-id", target]);
290
+ const identifiers = ["test_id", "testID", "selector"].map((field) => optionalScalarText(payload[field], `ui.press.${field}`)).filter((value) => value !== void 0);
291
+ const text = optionalScalarText(payload.text, "ui.press.text");
292
+ if (identifiers.length + Number(text !== void 0) !== 1) {
293
+ throw new Error("ui.press requires exactly one of: test_id, testID, selector, text.");
294
+ }
295
+ const target = text ?? identifiers[0];
296
+ if (target.trim() === "") throw new Error("ui.press target must be non-empty.");
297
+ const input = mobileUiInput(context, "press", payload);
298
+ return text !== void 0 ? bridgeCommand(input, ["press-text", target]) : bridgeCommand(input, ["press-test-id", target]);
292
299
  }
293
300
  async function handleMobileSetInput(payload, context) {
294
301
  const input = mobileUiInput(context, "set_input", payload);
@@ -185,4 +185,4 @@ ui.screenshot
185
185
 
186
186
  Navigation supports a small discoverable `page` alias set (`home`, `perps`, `perps-market`) plus raw React Navigation route/params fallback. Check the action manifest before hardcoding routes.
187
187
 
188
- Read-only position checks use `Engine.context.PerpsController.getPositions()` through Hermes CDP. State-changing Perps actions use supported controller APIs (`placeOrder`, `closePositions`) through the same app bridge rather than mutating Redux/React/local storage. UI actions delegate to existing bridge capabilities such as `press-test-id` and `scroll-view`. Screenshot capture uses `xcrun simctl io <simulator> screenshot` for iOS simulator proof.
188
+ Read-only position checks use `Engine.context.PerpsController.getPositions()` through Hermes CDP. State-changing Perps actions use supported controller APIs (`placeOrder`, `closePositions`) through the same app bridge rather than mutating Redux/React/local storage. Mobile `ui.press` uses `press-test-id` for `test_id`/`testID`/`selector` and `press-text` for visible `text`; scrolling uses `scroll-view`. Screenshot capture uses `xcrun simctl io <simulator> screenshot` for iOS simulator proof.
@@ -156,13 +156,38 @@
156
156
  ]
157
157
  },
158
158
  "ui.press": {
159
- "description": "Press/tap/click a UI target through the platform adapter.",
159
+ "description": "Press a React Native component by exact testID/test_id, a legacy selector identifier, or contained visible text.",
160
+ "schema": {
161
+ "type": "object",
162
+ "properties": {
163
+ "action": { "const": "ui.press" },
164
+ "test_id": { "type": "string", "minLength": 1 },
165
+ "testID": { "type": "string", "minLength": 1 },
166
+ "selector": { "type": "string", "minLength": 1 },
167
+ "text": { "type": "string", "minLength": 1 }
168
+ },
169
+ "oneOf": [
170
+ { "required": ["test_id"] },
171
+ { "required": ["testID"] },
172
+ { "required": ["selector"] },
173
+ { "required": ["text"] }
174
+ ]
175
+ },
160
176
  "examples": [
161
177
  {
178
+ "description": "Press by stable React Native testID",
179
+ "node": {
180
+ "action": "ui.press",
181
+ "test_id": "perps-tab",
182
+ "intent": "Open Perps through its stable testID"
183
+ }
184
+ },
185
+ {
186
+ "description": "Press a component that is reachable only by visible text",
162
187
  "node": {
163
188
  "action": "ui.press",
164
- "target": "Perps",
165
- "intent": "Press/tap/click a UI target through the platform adapter"
189
+ "text": "Ethereum",
190
+ "intent": "Press the component containing the visible Ethereum label"
166
191
  }
167
192
  }
168
193
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deeeed/metamask-harness",
3
- "version": "0.15.1",
3
+ "version": "0.15.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mm-harness": "bin/mm-harness"