@swmansion/argent 0.24.1-next.7 → 0.24.1-next.9

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/dist/cli-cmds.mjs CHANGED
@@ -21837,7 +21837,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
21837
21837
  var SESSION_ID2 = randomUUID5();
21838
21838
  function readCliVersion() {
21839
21839
  if (true) {
21840
- return "0.24.1-next.7";
21840
+ return "0.24.1-next.9";
21841
21841
  }
21842
21842
  return "0.0.0";
21843
21843
  }
@@ -16690,7 +16690,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
16690
16690
  var SESSION_ID = randomUUID4();
16691
16691
  function readCliVersion() {
16692
16692
  if (true) {
16693
- return "0.24.1-next.7";
16693
+ return "0.24.1-next.9";
16694
16694
  }
16695
16695
  return "0.0.0";
16696
16696
  }
@@ -94682,7 +94682,7 @@ var _CI_VENDOR_COUNT_FOR_TEST = vendors_default.length;
94682
94682
  var SESSION_ID = (0, import_node_crypto3.randomUUID)();
94683
94683
  function readCliVersion() {
94684
94684
  if (true) {
94685
- return "0.24.1-next.7";
94685
+ return "0.24.1-next.9";
94686
94686
  }
94687
94687
  return "0.0.0";
94688
94688
  }
@@ -112176,17 +112176,27 @@ var SCROLL_CLASSES = /* @__PURE__ */ new Set([
112176
112176
  "androidx.recyclerview.widget.RecyclerView",
112177
112177
  "android.widget.ListView"
112178
112178
  ]);
112179
- function isUiAutomatorScrollable(attrs) {
112179
+ function isUiAutomatorScrollable(attrs, inWebView = false) {
112180
+ if (inWebView) return attrIsTrue(attrs, "scrollable");
112180
112181
  return SCROLL_CLASSES.has(attrs.class ?? "") || attrIsTrue(attrs, "scrollable");
112181
112182
  }
112182
112183
  var WEBVIEW_CLASSES = /* @__PURE__ */ new Set(["android.webkit.WebView", "android.webkit.WebViewChromium"]);
112184
+ function hasGestureFlag(attrs) {
112185
+ return attrIsTrue(attrs, "clickable") || attrIsTrue(attrs, "long-clickable") || attrIsTrue(attrs, "checkable") || attrIsTrue(attrs, "scrollable");
112186
+ }
112187
+ function deriveWebRole(cls, attrs, label, hasRawChildren) {
112188
+ if (cls === "android.view.View" && label && !hasRawChildren && !hasGestureFlag(attrs)) {
112189
+ return "StaticText";
112190
+ }
112191
+ const role = deriveUiAutomatorRole(cls);
112192
+ if (role === "ScrollView" && !attrIsTrue(attrs, "scrollable")) return "List";
112193
+ return role;
112194
+ }
112183
112195
  function attrIsTrue(attrs, key2) {
112184
112196
  return attrs[key2] === "true";
112185
112197
  }
112186
112198
  function isInteractive(attrs) {
112187
- if (attrIsTrue(attrs, "clickable") || attrIsTrue(attrs, "long-clickable") || attrIsTrue(attrs, "checkable") || attrIsTrue(attrs, "scrollable")) {
112188
- return true;
112189
- }
112199
+ if (hasGestureFlag(attrs)) return true;
112190
112200
  if (attrIsTrue(attrs, "focusable") && labelOf(attrs) !== "") return true;
112191
112201
  return false;
112192
112202
  }
@@ -112264,7 +112274,7 @@ function makeUiNode(attrs, role, pixelBounds, label, children) {
112264
112274
  return out;
112265
112275
  }
112266
112276
  function pruneSubtree(root, opts) {
112267
- const stack = [{ parsed: root, scrollClip: null, visited: false }];
112277
+ const stack = [{ parsed: root, scrollClip: null, inWebView: false, visited: false }];
112268
112278
  const outputs = /* @__PURE__ */ new Map();
112269
112279
  while (stack.length > 0) {
112270
112280
  const top = stack[stack.length - 1];
@@ -112272,22 +112282,31 @@ function pruneSubtree(root, opts) {
112272
112282
  top.visited = true;
112273
112283
  const attrs = top.parsed.attrs;
112274
112284
  const myBounds = parseUiAutomatorBounds(attrs.bounds ?? "");
112275
- const isScroll = isUiAutomatorScrollable(attrs);
112285
+ const isScroll = isUiAutomatorScrollable(attrs, top.inWebView);
112276
112286
  const childClip = isScroll && myBounds ? myBounds : top.scrollClip;
112287
+ const childInWebView = top.inWebView || WEBVIEW_CLASSES.has(attrs.class ?? "");
112277
112288
  for (let i = top.parsed.children.length - 1; i >= 0; i--) {
112278
112289
  const c = top.parsed.children[i];
112279
112290
  if (c.tag === "node") {
112280
- stack.push({ parsed: c, scrollClip: childClip, visited: false });
112291
+ stack.push({
112292
+ parsed: c,
112293
+ scrollClip: childClip,
112294
+ inWebView: childInWebView,
112295
+ visited: false
112296
+ });
112281
112297
  }
112282
112298
  }
112283
112299
  } else {
112284
- outputs.set(top.parsed, computeNodeOutput(top.parsed, top.scrollClip, outputs, opts));
112300
+ outputs.set(
112301
+ top.parsed,
112302
+ computeNodeOutput(top.parsed, top.scrollClip, top.inWebView, outputs, opts)
112303
+ );
112285
112304
  stack.pop();
112286
112305
  }
112287
112306
  }
112288
112307
  return outputs.get(root) ?? [];
112289
112308
  }
112290
- function computeNodeOutput(parsed, scrollClip, outputs, opts) {
112309
+ function computeNodeOutput(parsed, scrollClip, inWebView, outputs, opts) {
112291
112310
  const attrs = parsed.attrs;
112292
112311
  const cls = attrs.class ?? "";
112293
112312
  if (NOISY_CLASSES.has(cls)) return [];
@@ -112309,9 +112328,26 @@ function computeNodeOutput(parsed, scrollClip, outputs, opts) {
112309
112328
  }
112310
112329
  }
112311
112330
  if (WEBVIEW_CLASSES.has(cls)) {
112312
- if (!visible) return [];
112313
- const own = labelOf(attrs);
112314
- return [makeUiNode(attrs, "WebView", bounds, "[web-view] " + (own || "(no label)"), [])];
112331
+ if (!visible) return keptChildren;
112332
+ let label2 = labelOf(attrs);
112333
+ let children = keptChildren;
112334
+ const inner = children.length === 1 && children[0].webHost ? children[0] : void 0;
112335
+ if (inner) {
112336
+ children = inner.children;
112337
+ if (!label2 && inner.label) label2 = inner.label;
112338
+ }
112339
+ if (!label2 && children.length === 0) label2 = "(no web content exposed)";
112340
+ const node2 = makeUiNode(attrs, "WebView", bounds, label2, children);
112341
+ node2.webHost = true;
112342
+ if (inner) {
112343
+ node2.clickable ||= inner.clickable;
112344
+ node2.longClickable ||= inner.longClickable;
112345
+ node2.scrollable ||= inner.scrollable;
112346
+ if (!node2.identifier && inner.identifier) node2.identifier = inner.identifier;
112347
+ }
112348
+ const hidden = hiddenInScroll + (inner?.scrollHidden ?? 0);
112349
+ if (hidden > 0) node2.scrollHidden = hidden;
112350
+ return [node2];
112315
112351
  }
112316
112352
  const interactive = isInteractive(attrs);
112317
112353
  let label = labelOf(attrs);
@@ -112344,7 +112380,13 @@ function computeNodeOutput(parsed, scrollClip, outputs, opts) {
112344
112380
  (c) => !(c.role === "StaticText" && c.label && lower.includes(c.label.toLowerCase()) && !c.clickable)
112345
112381
  );
112346
112382
  }
112347
- const node = makeUiNode(attrs, deriveUiAutomatorRole(cls), bounds, label, keptChildren);
112383
+ const role = inWebView ? deriveWebRole(
112384
+ cls,
112385
+ attrs,
112386
+ label,
112387
+ parsed.children.some((c) => c.tag === "node")
112388
+ ) : deriveUiAutomatorRole(cls);
112389
+ const node = makeUiNode(attrs, role, bounds, label, keptChildren);
112348
112390
  if (hiddenInScroll > 0) node.scrollHidden = hiddenInScroll;
112349
112391
  return [node];
112350
112392
  }
@@ -113252,7 +113294,10 @@ async function describeAndroid(registry2, serial, _bundleId, isTv) {
113252
113294
  devtools.getHierarchy(),
113253
113295
  devtools.getScreenSize()
113254
113296
  ]);
113255
- const tree2 = parseUiAutomatorDump(xml, size2.width, size2.height);
113297
+ const tree2 = await awaitWebViewPublished(
113298
+ parseUiAutomatorDump(xml, size2.width, size2.height),
113299
+ async () => parseUiAutomatorDump((await devtools.getHierarchy()).xml, size2.width, size2.height)
113300
+ );
113256
113301
  return { tree: tree2, source: "android-devtools", hint };
113257
113302
  } catch (serviceErr) {
113258
113303
  console.debug(
@@ -113260,16 +113305,32 @@ async function describeAndroid(registry2, serial, _bundleId, isTv) {
113260
113305
  );
113261
113306
  }
113262
113307
  }
113308
+ const [size, raw] = await Promise.all([getAndroidScreenSize(serial), uiautomatorDump(serial)]);
113309
+ const tree = await awaitWebViewPublished(
113310
+ parseDump(raw, size),
113311
+ async () => parseDump(await uiautomatorDump(serial), size)
113312
+ );
113313
+ return { tree, source: "uiautomator", hint };
113314
+ }
113315
+ var WEBVIEW_PUBLISH_STEP_MS = 250;
113316
+ var WEBVIEW_PUBLISH_BUDGET_MS = 1500;
113317
+ async function awaitWebViewPublished(first, read) {
113318
+ let tree = first;
113319
+ for (let waited = 0; waited < WEBVIEW_PUBLISH_BUDGET_MS && hasUnreadWebView(tree); ) {
113320
+ await new Promise((r) => setTimeout(r, WEBVIEW_PUBLISH_STEP_MS));
113321
+ waited += WEBVIEW_PUBLISH_STEP_MS;
113322
+ tree = await read();
113323
+ }
113324
+ return tree;
113325
+ }
113326
+ async function uiautomatorDump(serial) {
113263
113327
  const randomSuffix = `${Date.now().toString(36)}-${Math.floor(Math.random() * 1e9).toString(36)}`;
113264
113328
  const dumpPath = `/data/local/tmp/argent-ui-dump-${randomSuffix}.xml`;
113265
- const [size, rawBuf] = await Promise.all([
113266
- getAndroidScreenSize(serial),
113267
- adbExecOutBinary(
113268
- serial,
113269
- `uiautomator dump --compressed ${dumpPath} >/dev/null && cat ${dumpPath}; rm -f ${dumpPath}`,
113270
- { timeoutMs: 2e4 }
113271
- )
113272
- ]);
113329
+ const rawBuf = await adbExecOutBinary(
113330
+ serial,
113331
+ `uiautomator dump --compressed ${dumpPath} >/dev/null && cat ${dumpPath}; rm -f ${dumpPath}`,
113332
+ { timeoutMs: 2e4 }
113333
+ );
113273
113334
  const raw = rawBuf.toString("utf-8");
113274
113335
  const trimmed = raw.trim();
113275
113336
  if (/^ERROR:/i.test(trimmed) || !trimmed.includes("<hierarchy") && /error/i.test(trimmed)) {
@@ -113285,9 +113346,17 @@ async function describeAndroid(registry2, serial, _bundleId, isTv) {
113285
113346
  }
113286
113347
  );
113287
113348
  }
113349
+ return raw;
113350
+ }
113351
+ function parseDump(raw, size) {
113288
113352
  const oriented = orientScreenSize(size, parseDumpRotation(raw));
113289
- const tree = parseUiAutomatorDump(raw, oriented.width, oriented.height);
113290
- return { tree, source: "uiautomator", hint };
113353
+ return parseUiAutomatorDump(raw, oriented.width, oriented.height);
113354
+ }
113355
+ function hasUnreadWebView(node) {
113356
+ if (node.children.length === 0 && (node.role === "WebView" || node.label === "Web View")) {
113357
+ return true;
113358
+ }
113359
+ return node.children.some(hasUnreadWebView);
113291
113360
  }
113292
113361
 
113293
113362
  // ../tool-server/src/preview.ts
@@ -131935,6 +132004,7 @@ function timeoutCause(condition, lastTrustedReadAt, finalRead, pollIntervalMs) {
131935
132004
  }
131936
132005
  var capability21 = {
131937
132006
  apple: { simulator: true, device: true },
132007
+ appleRemote: { simulator: true },
131938
132008
  android: { emulator: true, device: true, unknown: true },
131939
132009
  chromium: { app: true },
131940
132010
  vega: { vvd: true }
@@ -131977,7 +132047,7 @@ function timeoutNote(params, lastTree, fetchError, lastData) {
131977
132047
  }
131978
132048
  function createAwaitUiElementTool(registry2) {
131979
132049
  async function fetchTree2(device, params, services, isTvOs, androidIsTv) {
131980
- if (device.platform === "ios") {
132050
+ if (device.platform === "ios" || device.platform === "ios-remote") {
131981
132051
  if (device.kind === "device") {
131982
132052
  return describeIosDevice(registry2, device);
131983
132053
  }
@@ -132040,6 +132110,7 @@ tap/navigation to wait for the next screen, or before tapping an element that ap
132040
132110
  const device = resolveDevice(params.udid);
132041
132111
  assertSupported(AWAIT_UI_ELEMENT_TOOL_ID, capability21, device);
132042
132112
  if (device.platform === "ios") await ensureDeps(iosRequires);
132113
+ else if (device.platform === "ios-remote") await ensureDeps(["sim-remote"]);
132043
132114
  else if (device.platform === "android") await ensureDeps(androidRequires);
132044
132115
  else if (device.platform === "vega") await ensureDeps(vegaRequires);
132045
132116
  const isTvOs = device.platform === "ios" && device.kind !== "device" && await isTvOsSimulator(device.id);
@@ -134712,6 +134783,7 @@ var zodSchema39 = external_exports.object({
134712
134783
  });
134713
134784
  var capability24 = {
134714
134785
  apple: { simulator: true, device: true },
134786
+ appleRemote: { simulator: true },
134715
134787
  android: { emulator: true, device: true, unknown: true },
134716
134788
  chromium: { app: true }
134717
134789
  };
@@ -134730,7 +134802,7 @@ function treeSignature(root) {
134730
134802
  }
134731
134803
  function createAwaitScreenIdleTool(registry2) {
134732
134804
  function fetchTree2(device, services, isTvOs, androidIsTv) {
134733
- if (device.platform === "ios") {
134805
+ if (device.platform === "ios" || device.platform === "ios-remote") {
134734
134806
  if (device.kind === "device") {
134735
134807
  return describeIosDevice(registry2, device);
134736
134808
  }
@@ -134769,6 +134841,7 @@ still before the timeout. Use after a launch/navigation to wait for the UI to re
134769
134841
  const device = resolveDevice(params.udid);
134770
134842
  assertSupported(AWAIT_SCREEN_IDLE_TOOL_ID, capability24, device);
134771
134843
  if (device.platform === "ios") await ensureDeps(iosRequires);
134844
+ else if (device.platform === "ios-remote") await ensureDeps(["sim-remote"]);
134772
134845
  else if (device.platform === "android") await ensureDeps(androidRequires);
134773
134846
  const isTvOs = device.platform === "ios" && device.kind !== "device" && await isTvOsSimulator(device.id);
134774
134847
  const androidIsTv = device.platform === "android" && await isAndroidTv(device.id);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.24.1-next.7",
3
+ "version": "0.24.1-next.9",
4
4
  "mcpName": "io.github.software-mansion/argent",
5
5
  "description": "MCP server for iOS Simulator and Android Emulator control",
6
6
  "license": "Apache-2.0",