@swmansion/argent 0.24.1-next.8 → 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.8";
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.8";
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.8";
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@swmansion/argent",
3
- "version": "0.24.1-next.8",
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",