@skrillex1224/android-toolkit 1.0.7 → 1.0.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/browser.js +1 -1
- package/dist/browser.js.map +1 -1
- package/dist/index.cjs +55 -18
- package/dist/index.cjs.map +2 -2
- package/dist/index.js +55 -18
- package/dist/index.js.map +3 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28,7 +28,7 @@ var Code = Object.freeze({
|
|
|
28
28
|
ContentUnavailable: 30010003,
|
|
29
29
|
SourceExtractionFailed: 30010004,
|
|
30
30
|
AutomationFailed: 30010005,
|
|
31
|
-
|
|
31
|
+
AppRuntimeUnavailable: 30010008,
|
|
32
32
|
AppNotInstalled: 30010009
|
|
33
33
|
});
|
|
34
34
|
var Status = Object.freeze({
|
|
@@ -1008,7 +1008,10 @@ async function pressEnter2(ctx) {
|
|
|
1008
1008
|
}
|
|
1009
1009
|
async function scroll(ctx, selector, direction, options = {}) {
|
|
1010
1010
|
const node = await DeviceView.find(ctx, selector, options);
|
|
1011
|
-
|
|
1011
|
+
await scrollBounds(ctx, node.bounds, direction, options);
|
|
1012
|
+
}
|
|
1013
|
+
async function scrollBounds(ctx, bounds2, direction, options = {}) {
|
|
1014
|
+
const box = bounds2;
|
|
1012
1015
|
const ratio = Number(options.swipeRatio || 0.72);
|
|
1013
1016
|
const durationMs = Number(options.durationMs || 360);
|
|
1014
1017
|
const x = box.centerX;
|
|
@@ -1035,6 +1038,9 @@ async function scrollUntilStable(ctx, selector, direction, options = {}) {
|
|
|
1035
1038
|
const maxSwipes = Math.max(1, Number(options.maxSwipes || 20));
|
|
1036
1039
|
const stableRoundsTarget = Math.max(1, Number(options.stableRounds || 2));
|
|
1037
1040
|
const hashSource = String(options.stability || options.hashSource || "view");
|
|
1041
|
+
if (hashSource === "screenshot") {
|
|
1042
|
+
return scrollUntilScreenshotStable(ctx, selector, direction, options, maxSwipes, stableRoundsTarget, hashSource);
|
|
1043
|
+
}
|
|
1038
1044
|
let lastHash = "";
|
|
1039
1045
|
let stableRounds = 0;
|
|
1040
1046
|
for (let index = 0; index < maxSwipes; index += 1) {
|
|
@@ -1042,7 +1048,7 @@ async function scrollUntilStable(ctx, selector, direction, options = {}) {
|
|
|
1042
1048
|
if (currentHash === lastHash) {
|
|
1043
1049
|
stableRounds += 1;
|
|
1044
1050
|
if (stableRounds >= stableRoundsTarget) {
|
|
1045
|
-
return { swipes: index, stableRounds, hash: currentHash, hashSource };
|
|
1051
|
+
return { swipes: index, stableRounds, hash: currentHash, hashSource, capped: false };
|
|
1046
1052
|
}
|
|
1047
1053
|
} else {
|
|
1048
1054
|
stableRounds = 0;
|
|
@@ -1050,7 +1056,27 @@ async function scrollUntilStable(ctx, selector, direction, options = {}) {
|
|
|
1050
1056
|
}
|
|
1051
1057
|
await scroll(ctx, selector, direction, options);
|
|
1052
1058
|
}
|
|
1053
|
-
return { swipes: maxSwipes, stableRounds, hash: lastHash, hashSource };
|
|
1059
|
+
return { swipes: maxSwipes, stableRounds, hash: lastHash, hashSource, capped: true };
|
|
1060
|
+
}
|
|
1061
|
+
async function scrollUntilScreenshotStable(ctx, selector, direction, options, maxSwipes, stableRoundsTarget, hashSource) {
|
|
1062
|
+
const node = await DeviceView.find(ctx, selector, options);
|
|
1063
|
+
const bounds2 = node.bounds;
|
|
1064
|
+
let lastHash = await scrollStateHash(ctx, selector, options, hashSource);
|
|
1065
|
+
let stableRounds = 0;
|
|
1066
|
+
for (let index = 0; index < maxSwipes; index += 1) {
|
|
1067
|
+
await scrollBounds(ctx, bounds2, direction, options);
|
|
1068
|
+
const currentHash = await scrollStateHash(ctx, selector, options, hashSource);
|
|
1069
|
+
if (currentHash === lastHash) {
|
|
1070
|
+
stableRounds += 1;
|
|
1071
|
+
if (stableRounds >= stableRoundsTarget) {
|
|
1072
|
+
return { swipes: index + 1, stableRounds, hash: currentHash, hashSource, capped: false };
|
|
1073
|
+
}
|
|
1074
|
+
} else {
|
|
1075
|
+
stableRounds = 0;
|
|
1076
|
+
lastHash = currentHash;
|
|
1077
|
+
}
|
|
1078
|
+
}
|
|
1079
|
+
return { swipes: maxSwipes, stableRounds, hash: lastHash, hashSource, capped: true };
|
|
1054
1080
|
}
|
|
1055
1081
|
async function scrollStateHash(ctx, selector, options, hashSource) {
|
|
1056
1082
|
if (hashSource === "screenshot") {
|
|
@@ -1135,8 +1161,8 @@ async function query(ctx, options = {}) {
|
|
|
1135
1161
|
const dbPaths = await resolveDeviceDbPaths(ctx, config);
|
|
1136
1162
|
if (dbPaths.length === 0) {
|
|
1137
1163
|
throw new CrawlerError({
|
|
1138
|
-
message: "
|
|
1139
|
-
code: Code.
|
|
1164
|
+
message: "app_runtime_unavailable: sqlite database not found",
|
|
1165
|
+
code: Code.AppRuntimeUnavailable,
|
|
1140
1166
|
context: { dbDir: config.dbDir, dbPath: config.dbPath, dbNamePrefix: config.dbNamePrefix }
|
|
1141
1167
|
});
|
|
1142
1168
|
}
|
|
@@ -1185,8 +1211,8 @@ async function resolveDeviceDbPaths(ctx, config) {
|
|
|
1185
1211
|
maxBuffer: 2 * 1024 * 1024
|
|
1186
1212
|
}).catch((error) => {
|
|
1187
1213
|
throw new CrawlerError({
|
|
1188
|
-
message: `
|
|
1189
|
-
code: Code.
|
|
1214
|
+
message: `app_runtime_unavailable: sqlite dbDir unavailable ${error?.message || String(error)}`,
|
|
1215
|
+
code: Code.AppRuntimeUnavailable,
|
|
1190
1216
|
context: { dbDir: config.dbDir }
|
|
1191
1217
|
});
|
|
1192
1218
|
});
|
|
@@ -1211,8 +1237,8 @@ async function pullDatabaseSnapshot(ctx, dbPath, localDir) {
|
|
|
1211
1237
|
await adbSuShell(ctx, copyCommand, { timeoutMs: 3e4, maxBuffer: 4 * 1024 * 1024 });
|
|
1212
1238
|
await adbPull(adbPath, serial, remoteDb, localDb).catch((error) => {
|
|
1213
1239
|
throw new CrawlerError({
|
|
1214
|
-
message: `
|
|
1215
|
-
code: Code.
|
|
1240
|
+
message: `app_runtime_unavailable: sqlite snapshot pull failed ${error?.message || String(error)}`,
|
|
1241
|
+
code: Code.AppRuntimeUnavailable,
|
|
1216
1242
|
context: { dbPath }
|
|
1217
1243
|
});
|
|
1218
1244
|
});
|
|
@@ -1671,17 +1697,28 @@ async function captureScreen(ctx, options = {}) {
|
|
|
1671
1697
|
const frameBuffers = [];
|
|
1672
1698
|
const seen = /* @__PURE__ */ new Set();
|
|
1673
1699
|
const targetSelector = options.selector || { id: "message_list" };
|
|
1674
|
-
|
|
1700
|
+
const shouldHideKeyboard = options.hideKeyboard !== false;
|
|
1701
|
+
if (shouldHideKeyboard) await Device.hideKeyboard(ctx, { attempts: 2, settleMs: 350 }).catch(() => {
|
|
1675
1702
|
});
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1703
|
+
try {
|
|
1704
|
+
const topResult = await DeviceInput.scrollToTop(ctx, targetSelector, {
|
|
1705
|
+
maxSwipes: Number(options.scrollToTopMaxSwipes || 12),
|
|
1706
|
+
stableRounds: Number(options.scrollToTopStableRounds || 2),
|
|
1707
|
+
settleMs: 400,
|
|
1708
|
+
stability: options.scrollStability || options.stability || "view"
|
|
1709
|
+
});
|
|
1710
|
+
Logger.info("captureScreen scrollToTop", {
|
|
1711
|
+
swipes: topResult?.swipes,
|
|
1712
|
+
stableRounds: topResult?.stableRounds,
|
|
1713
|
+
hashSource: topResult?.hashSource,
|
|
1714
|
+
capped: topResult?.capped === true
|
|
1715
|
+
});
|
|
1716
|
+
} catch (error) {
|
|
1717
|
+
if (options.strictScrollToTop === true) throw error;
|
|
1681
1718
|
Logger.warn("captureScreen scrollToTop skipped", { message: error?.message || String(error) });
|
|
1682
|
-
}
|
|
1719
|
+
}
|
|
1683
1720
|
for (let index = 0; index < DEFAULT_CAPTURE_COUNT; index += 1) {
|
|
1684
|
-
await Device.hideKeyboard(ctx, { attempts: 1, settleMs: 250 }).catch(() => {
|
|
1721
|
+
if (shouldHideKeyboard) await Device.hideKeyboard(ctx, { attempts: 1, settleMs: 250 }).catch(() => {
|
|
1685
1722
|
});
|
|
1686
1723
|
await sleep(DEFAULT_SETTLE_MS);
|
|
1687
1724
|
const png = await Device.screenshotPng(ctx);
|