| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- /**
- * probe-dump.js — 把当前屏幕的控件树完整 dump 到一个文本文件
- *
- * 为什么不用 `uiautomator dump`:TikTok 的页面一直在动(视频、动画),
- * uiautomator 等不到 idle state 就直接失败(实测 "could not get idle state")。
- * 而 AutoX 的无障碍读取不需要 idle,且**与引擎最终用的是同一套读取路径** ——
- * 探针看到的和引擎将来看到的完全一致。
- *
- * 用法:adb 启动本脚本,几秒后读 /sdcard/tiktok_app/probe-dump.txt
- */
- var OUT = "/sdcard/tiktok_app/probe-dump.txt";
- function clean(v) {
- if (v === null || v === undefined) { return ""; }
- return String(v).replace(/[\u200b-\u200f\u202a-\u202e\ufeff]/g, "").replace(/\s+/g, " ").replace(/^\s+|\s+$/g, "");
- }
- function collect() {
- var lines = [];
- var start = auto.root;
- if (!start) { return ["root=null"]; }
- var stack = [{ node: start, depth: 0 }];
- var count = 0;
- while (stack.length > 0 && count < 2000) {
- var item = stack.pop();
- var node = item.node;
- if (!node) { continue; }
- count += 1;
- var box = null;
- var text = "", desc = "", cls = "", rid = "", clickable = false, scrollable = false, editable = false, selected = false;
- try { box = node.bounds(); } catch (e) { box = null; }
- try { text = clean(node.text()); } catch (e) { }
- try { desc = clean(node.desc()); } catch (e) { }
- try { cls = String(node.className()); } catch (e) { }
- try { rid = String(node.id() || ""); } catch (e) { }
- try { clickable = node.clickable() === true; } catch (e) { }
- try { scrollable = node.scrollable() === true; } catch (e) { }
- try { editable = node.className() === "android.widget.EditText"; } catch (e) { }
- try { selected = node.selected() === true; } catch (e) { }
- var visible = false;
- try { visible = node.isVisibleToUser() === true; } catch (e) { visible = true; }
- if (visible && (text !== "" || desc !== "" || clickable || scrollable)) {
- var short = cls.split(".").pop();
- var shortId = rid.indexOf("/") >= 0 ? rid.split("/").pop() : rid;
- lines.push([
- item.depth,
- short,
- shortId,
- box ? ("[" + box.left + "," + box.top + "][" + box.right + "," + box.bottom + "]") : "[]",
- clickable ? "CLK" : "-",
- scrollable ? "SCR" : "-",
- editable ? "EDT" : "-",
- selected ? "SEL" : "-",
- JSON.stringify(text),
- JSON.stringify(desc)
- ].join(" "));
- }
- var childCount = 0;
- try { childCount = node.childCount(); } catch (e) { childCount = 0; }
- for (var i = childCount - 1; i >= 0; i -= 1) {
- try { stack.push({ node: node.child(i), depth: item.depth + 1 }); } catch (e) { }
- }
- }
- lines.unshift("total=" + count + " screen=" + device.width + "x" + device.height +
- " pkg=" + (auto.root ? auto.root.packageName() : "?"));
- return lines;
- }
- var lines = collect();
- files.ensureDir("/sdcard/tiktok_app/");
- files.write(OUT, lines.join("\n") + "\n");
- console.log("probe written: " + OUT + " lines=" + lines.length);
|