assistsx-js 0.2.1 → 0.2.3

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.
@@ -0,0 +1,4367 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/step-flow/index.ts
21
+ var step_flow_exports = {};
22
+ __export(step_flow_exports, {
23
+ StepFlow: () => StepFlow,
24
+ assignFlowPayload: () => assignFlowPayload,
25
+ buildFlowInitialData: () => buildFlowInitialData,
26
+ createFinishHandoff: () => createFinishHandoff,
27
+ createFlowDispatcher: () => createFlowDispatcher,
28
+ createLaunchState: () => createLaunchState,
29
+ flowEnd: () => flowEnd,
30
+ flowEvent: () => flowEvent,
31
+ flowRepeat: () => flowRepeat,
32
+ getFlowPayload: () => getFlowPayload
33
+ });
34
+ module.exports = __toCommonJS(step_flow_exports);
35
+
36
+ // src/step-flow/outcome.ts
37
+ function flowEvent(name) {
38
+ return { type: "event", name };
39
+ }
40
+ function flowRepeat() {
41
+ return { type: "repeat" };
42
+ }
43
+ function flowEnd() {
44
+ return { type: "end" };
45
+ }
46
+
47
+ // src/step-flow/payload.ts
48
+ function asFlowData(step) {
49
+ return step.data;
50
+ }
51
+ function getFlowPayload(step) {
52
+ const data = asFlowData(step);
53
+ const payload = data.payload;
54
+ if (payload !== null && payload !== void 0 && typeof payload === "object" && !Array.isArray(payload)) {
55
+ return payload;
56
+ }
57
+ return {};
58
+ }
59
+ function assignFlowPayload(step, partial) {
60
+ const data = asFlowData(step);
61
+ const current = getFlowPayload(step);
62
+ data.payload = { ...current, ...partial };
63
+ }
64
+
65
+ // src/step-flow/legacy-handoff.ts
66
+ function createFinishHandoff(dispatcher, nextState) {
67
+ return async (step) => {
68
+ const data = step.data;
69
+ if (!data.__flow) {
70
+ data.__flow = { state: nextState };
71
+ } else {
72
+ data.__flow.state = nextState;
73
+ }
74
+ return step.next(dispatcher);
75
+ };
76
+ }
77
+ function createLaunchState(dispatcher, launchImpl, nextState, legacyDataKeys = ["appName", "packageName"]) {
78
+ return {
79
+ run: async (step) => {
80
+ const payload = getFlowPayload(step);
81
+ for (const key of legacyDataKeys) {
82
+ if (payload[key] !== void 0) {
83
+ step.data[key] = payload[key];
84
+ }
85
+ }
86
+ step.data.finishMethod = createFinishHandoff(
87
+ dispatcher,
88
+ nextState
89
+ );
90
+ return { type: "legacy", impl: launchImpl };
91
+ },
92
+ on: {}
93
+ };
94
+ }
95
+
96
+ // src/bounds.ts
97
+ var Bounds = class _Bounds {
98
+ // 构造函数
99
+ constructor(left, top, right, bottom, width, height, centerX, centerY, exactCenterX, exactCenterY, isEmpty) {
100
+ this.left = left;
101
+ this.top = top;
102
+ this.right = right;
103
+ this.bottom = bottom;
104
+ this.width = width;
105
+ this.height = height;
106
+ this.centerX = centerX;
107
+ this.centerY = centerY;
108
+ this.exactCenterX = exactCenterX;
109
+ this.exactCenterY = exactCenterY;
110
+ this.isEmpty = isEmpty;
111
+ }
112
+ /**
113
+ * 判断该 Bounds 是否在屏幕内(满足基本几何有效性)
114
+ * @returns {boolean}
115
+ */
116
+ isInScreen() {
117
+ return this.centerX > 0 && this.centerY > 0 && this.height > 0 && this.width > 0;
118
+ }
119
+ // 从普通对象创建 Bounds 实例
120
+ static from(data) {
121
+ return new _Bounds(
122
+ data.left,
123
+ data.top,
124
+ data.right,
125
+ data.bottom,
126
+ data.width,
127
+ data.height,
128
+ data.centerX,
129
+ data.centerY,
130
+ data.exactCenterX,
131
+ data.exactCenterY,
132
+ data.isEmpty
133
+ );
134
+ }
135
+ // 从 JSON 字符串创建实例
136
+ static fromJSON(json) {
137
+ const data = JSON.parse(json);
138
+ return _Bounds.from(data);
139
+ }
140
+ static fromData(data) {
141
+ if (data == null) {
142
+ return new _Bounds(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true);
143
+ }
144
+ if (typeof data !== "object" || Array.isArray(data)) {
145
+ throw new Error(
146
+ `Bounds.fromData: Expected object, but got ${typeof data}. Value: ${JSON.stringify(data)}`
147
+ );
148
+ }
149
+ return new _Bounds(
150
+ data.left,
151
+ data.top,
152
+ data.right,
153
+ data.bottom,
154
+ data.width,
155
+ data.height,
156
+ data.centerX,
157
+ data.centerY,
158
+ data.exactCenterX,
159
+ data.exactCenterY,
160
+ data.isEmpty
161
+ );
162
+ }
163
+ // 转换为普通对象
164
+ toJSON() {
165
+ return {
166
+ left: this.left,
167
+ top: this.top,
168
+ right: this.right,
169
+ bottom: this.bottom,
170
+ width: this.width,
171
+ height: this.height,
172
+ centerX: this.centerX,
173
+ centerY: this.centerY,
174
+ exactCenterX: this.exactCenterX,
175
+ exactCenterY: this.exactCenterY,
176
+ isEmpty: this.isEmpty
177
+ };
178
+ }
179
+ // 克隆方法
180
+ clone() {
181
+ return new _Bounds(
182
+ this.left,
183
+ this.top,
184
+ this.right,
185
+ this.bottom,
186
+ this.width,
187
+ this.height,
188
+ this.centerX,
189
+ this.centerY,
190
+ this.exactCenterX,
191
+ this.exactCenterY,
192
+ this.isEmpty
193
+ );
194
+ }
195
+ };
196
+
197
+ // src/call-method.ts
198
+ var CallMethod = {
199
+ takeScreenshot: "takeScreenshot",
200
+ takeScreenshotSave: "takeScreenshotSave",
201
+ takeScreenshotToFile: "takeScreenshotToFile",
202
+ overlayToast: "overlayToast",
203
+ setNodeText: "setNodeText",
204
+ findByTags: "findByTags",
205
+ findById: "findById",
206
+ findByText: "findByText",
207
+ findByTextAllMatch: "findByTextAllMatch",
208
+ containsText: "containsText",
209
+ getAllText: "getAllText",
210
+ findFirstParentByTags: "findFirstParentByTags",
211
+ getAllNodes: "getAllNodes",
212
+ getNodes: "getNodes",
213
+ findFirstParentClickable: "findFirstParentClickable",
214
+ getChildren: "getChildren",
215
+ getBoundsInScreen: "getBoundsInScreen",
216
+ isVisible: "isVisible",
217
+ click: "click",
218
+ longClick: "longClick",
219
+ back: "back",
220
+ home: "home",
221
+ notifications: "notifications",
222
+ recentApps: "recentApps",
223
+ paste: "paste",
224
+ focus: "focus",
225
+ selectionText: "selectionText",
226
+ scrollForward: "scrollForward",
227
+ launchApp: "launchApp",
228
+ getPackageName: "getPackageName",
229
+ getScreenSize: "getScreenSize",
230
+ getAppScreenSize: "getAppScreenSize",
231
+ scrollBackward: "scrollBackward",
232
+ setOverlayFlags: "setOverlayFlags",
233
+ scanQR: "scanQR",
234
+ loadWebViewOverlay: "loadWebViewOverlay",
235
+ closeOverlay: "closeOverlay",
236
+ recognizeTextInScreenshot: "recognizeTextInScreenshot",
237
+ clickByGesture: "clickByGesture",
238
+ clickNodeByGesture: "clickNodeByGesture",
239
+ doubleClickNodeByGesture: "doubleClickNodeByGesture",
240
+ performLinearGesture: "performLinearGesture",
241
+ longPressGestureAutoPaste: "longPressGestureAutoPaste",
242
+ getAppInfo: "getAppInfo",
243
+ getMacAddress: "getMacAddress",
244
+ getAndroidID: "getAndroidID",
245
+ getUniqueDeviceId: "getUniqueDeviceId",
246
+ addAccessibilityEventFilter: "addAccessibilityEventFilter",
247
+ setAccessibilityEventFilters: "setAccessibilityEventFilters",
248
+ httpRequest: "httpRequest",
249
+ getDeviceInfo: "getDeviceInfo",
250
+ getNetworkType: "getNetworkType",
251
+ isAppInstalled: "isAppInstalled",
252
+ getClipboardLatestText: "getClipboardLatestText",
253
+ getClipboardText: "getClipboardText",
254
+ openUrlInBrowser: "openUrlInBrowser",
255
+ keepScreenOn: "keepScreenOn",
256
+ clearKeepScreenOn: "clearKeepScreenOn",
257
+ download: "download",
258
+ audioPlayFromFile: "audioPlayFromFile",
259
+ audioStop: "audioStop",
260
+ audioPlayRingtone: "audioPlayRingtone",
261
+ audioStopRingtone: "audioStopRingtone",
262
+ // 通讯录相关方法
263
+ addContact: "addContact",
264
+ getAllContacts: "getAllContacts",
265
+ // 节点树相关方法
266
+ saveRootNodeTreeJson: "saveRootNodeTreeJson"
267
+ };
268
+
269
+ // src/call-response.ts
270
+ var CallResponse = class {
271
+ constructor(code, data, callbackId) {
272
+ this.code = code;
273
+ this.data = data;
274
+ this.callbackId = callbackId;
275
+ }
276
+ // 判断是否成功
277
+ isSuccess() {
278
+ return this.code === 0;
279
+ }
280
+ // 获取数据,如果数据为空则抛出错误
281
+ getData() {
282
+ if (this.data === null) {
283
+ throw new Error("Data is null");
284
+ }
285
+ return this.data;
286
+ }
287
+ // 获取数据,如果数据为空则返回默认值
288
+ getDataOrNull() {
289
+ return this.data;
290
+ }
291
+ // 获取数据,如果数据为空则返回默认值
292
+ getDataOrDefault(defaultValue) {
293
+ var _a2;
294
+ return (_a2 = this.data) != null ? _a2 : defaultValue;
295
+ }
296
+ };
297
+
298
+ // src/utils.ts
299
+ function generateUUID() {
300
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
301
+ const r = Math.random() * 16 | 0;
302
+ const v = c === "x" ? r : r & 3 | 8;
303
+ return v.toString(16);
304
+ });
305
+ }
306
+ function decodeBase64UTF8(base64) {
307
+ const binary = atob(base64);
308
+ const bytes = new Uint8Array(binary.length);
309
+ for (let i = 0; i < binary.length; i++) {
310
+ bytes[i] = binary.charCodeAt(i);
311
+ }
312
+ return new TextDecoder("utf-8").decode(bytes);
313
+ }
314
+
315
+ // src/app-info.ts
316
+ var AppInfo = class _AppInfo {
317
+ constructor(isSystem = false, minSdkVersion = 0, name = "", packageName = "", targetSdkVersion = 0, versionCode = 0, versionName = "") {
318
+ this.isSystem = isSystem;
319
+ this.minSdkVersion = minSdkVersion;
320
+ this.name = name;
321
+ this.packageName = packageName;
322
+ this.targetSdkVersion = targetSdkVersion;
323
+ this.versionCode = versionCode;
324
+ this.versionName = versionName;
325
+ }
326
+ /**
327
+ * 从JSON对象创建AppInfo实例
328
+ * @param data JSON对象
329
+ * @returns AppInfo实例
330
+ */
331
+ static fromJSON(data) {
332
+ var _a2, _b, _c, _d, _e, _f, _g;
333
+ return new _AppInfo(
334
+ (_a2 = data.isSystem) != null ? _a2 : false,
335
+ (_b = data.minSdkVersion) != null ? _b : 0,
336
+ (_c = data.name) != null ? _c : "",
337
+ (_d = data.packageName) != null ? _d : "",
338
+ (_e = data.targetSdkVersion) != null ? _e : 0,
339
+ (_f = data.versionCode) != null ? _f : 0,
340
+ (_g = data.versionName) != null ? _g : ""
341
+ );
342
+ }
343
+ /**
344
+ * 转换为JSON对象
345
+ * @returns JSON对象
346
+ */
347
+ toJSON() {
348
+ return {
349
+ isSystem: this.isSystem,
350
+ minSdkVersion: this.minSdkVersion,
351
+ name: this.name,
352
+ packageName: this.packageName,
353
+ targetSdkVersion: this.targetSdkVersion,
354
+ versionCode: this.versionCode,
355
+ versionName: this.versionName
356
+ };
357
+ }
358
+ };
359
+
360
+ // src/device-info.ts
361
+ var DeviceInfo = class _DeviceInfo {
362
+ constructor(uniqueDeviceId = "", androidID = "", macAddress = "", isDeviceRooted = false, manufacturer = "", model = "", sdkVersionCode = 0, sdkVersionName = "", abiList = [], isAdbEnabled = false, isDevelopmentSettingsEnabled = false, isEmulator = false, isTablet = false) {
363
+ this.uniqueDeviceId = uniqueDeviceId;
364
+ this.androidID = androidID;
365
+ this.macAddress = macAddress;
366
+ this.isDeviceRooted = isDeviceRooted;
367
+ this.manufacturer = manufacturer;
368
+ this.model = model;
369
+ this.sdkVersionCode = sdkVersionCode;
370
+ this.sdkVersionName = sdkVersionName;
371
+ this.abiList = abiList;
372
+ this.isAdbEnabled = isAdbEnabled;
373
+ this.isDevelopmentSettingsEnabled = isDevelopmentSettingsEnabled;
374
+ this.isEmulator = isEmulator;
375
+ this.isTablet = isTablet;
376
+ }
377
+ /**
378
+ * 从JSON对象创建DeviceInfo实例
379
+ * @param data JSON对象
380
+ * @returns DeviceInfo实例
381
+ */
382
+ static fromJSON(data) {
383
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m;
384
+ return new _DeviceInfo(
385
+ (_a2 = data.uniqueDeviceId) != null ? _a2 : "",
386
+ (_b = data.androidID) != null ? _b : "",
387
+ (_c = data.macAddress) != null ? _c : "",
388
+ (_d = data.isDeviceRooted) != null ? _d : false,
389
+ (_e = data.manufacturer) != null ? _e : "",
390
+ (_f = data.model) != null ? _f : "",
391
+ (_g = data.sdkVersionCode) != null ? _g : 0,
392
+ (_h = data.sdkVersionName) != null ? _h : "",
393
+ (_i = data.abiList) != null ? _i : [],
394
+ (_j = data.isAdbEnabled) != null ? _j : false,
395
+ (_k = data.isDevelopmentSettingsEnabled) != null ? _k : false,
396
+ (_l = data.isEmulator) != null ? _l : false,
397
+ (_m = data.isTablet) != null ? _m : false
398
+ );
399
+ }
400
+ /**
401
+ * 转换为JSON对象
402
+ * @returns JSON对象
403
+ */
404
+ toJSON() {
405
+ return {
406
+ uniqueDeviceId: this.uniqueDeviceId,
407
+ androidID: this.androidID,
408
+ macAddress: this.macAddress,
409
+ isDeviceRooted: this.isDeviceRooted,
410
+ manufacturer: this.manufacturer,
411
+ model: this.model,
412
+ sdkVersionCode: this.sdkVersionCode,
413
+ sdkVersionName: this.sdkVersionName,
414
+ abiList: this.abiList,
415
+ isAdbEnabled: this.isAdbEnabled,
416
+ isDevelopmentSettingsEnabled: this.isDevelopmentSettingsEnabled,
417
+ isEmulator: this.isEmulator,
418
+ isTablet: this.isTablet
419
+ };
420
+ }
421
+ };
422
+
423
+ // src/assistsx-async.ts
424
+ var AssistsXAsync = class {
425
+ /**
426
+ * 执行异步调用
427
+ * @param method 方法名
428
+ * @param args 参数对象
429
+ * @param timeout 超时时间(秒),默认30秒
430
+ * @returns Promise<调用响应>
431
+ */
432
+ static async asyncCall(method, {
433
+ args,
434
+ node,
435
+ nodes,
436
+ timeout = 30
437
+ } = {}) {
438
+ const uuid = generateUUID();
439
+ const params = {
440
+ method,
441
+ arguments: args ? args : void 0,
442
+ node: node ? node : void 0,
443
+ nodes: nodes ? nodes : void 0,
444
+ callbackId: uuid
445
+ };
446
+ const promise = new Promise((resolve) => {
447
+ callbacks.set(uuid, (data) => {
448
+ resolve(data);
449
+ });
450
+ setTimeout(() => {
451
+ callbacks.delete(uuid);
452
+ resolve(new CallResponse(0, null, uuid));
453
+ }, timeout * 1e3);
454
+ });
455
+ const result = window.assistsxAsync.call(JSON.stringify(params));
456
+ const promiseResult = await promise;
457
+ if (typeof promiseResult === "string") {
458
+ const responseData = JSON.parse(promiseResult);
459
+ const response = new CallResponse(
460
+ responseData.code,
461
+ responseData.data,
462
+ responseData.callbackId
463
+ );
464
+ return response;
465
+ }
466
+ throw new Error("Call failed");
467
+ }
468
+ /**
469
+ * 设置悬浮窗标志
470
+ * @param flags 标志
471
+ * @param timeout 超时时间(秒),默认30秒
472
+ * @returns 是否设置成功
473
+ */
474
+ static async setOverlayFlags(flags, timeout) {
475
+ const response = await this.asyncCall(CallMethod.setOverlayFlags, {
476
+ args: { flags },
477
+ timeout
478
+ });
479
+ return response.getDataOrDefault(false);
480
+ }
481
+ /**
482
+ * 设置悬浮窗标志
483
+ * @param flags 标志
484
+ * @param timeout 超时时间(秒),默认30秒
485
+ * @returns 是否设置成功
486
+ */
487
+ static async setOverlayFlagList(flags, timeout) {
488
+ const response = await this.asyncCall(CallMethod.setOverlayFlags, {
489
+ args: { flags },
490
+ timeout
491
+ });
492
+ return response.getDataOrDefault(false);
493
+ }
494
+ /**
495
+ * 获取所有符合条件的节点
496
+ * @param filterClass 类名过滤
497
+ * @param filterViewId 视图ID过滤
498
+ * @param filterDes 描述过滤
499
+ * @param filterText 文本过滤
500
+ * @param timeout 超时时间(秒),默认30秒
501
+ * @returns 节点数组
502
+ */
503
+ static async getAllNodes({
504
+ filterClass,
505
+ filterViewId,
506
+ filterDes,
507
+ filterText,
508
+ timeout,
509
+ scope
510
+ } = {}) {
511
+ const response = await this.asyncCall(CallMethod.getAllNodes, {
512
+ args: {
513
+ filterClass,
514
+ filterViewId,
515
+ filterDes,
516
+ filterText,
517
+ ...scope !== void 0 ? { scope } : {}
518
+ },
519
+ timeout
520
+ });
521
+ const data = response.getDataOrDefault([]);
522
+ if (!Array.isArray(data)) {
523
+ throw new Error(
524
+ `AssistsXAsync.getAllNodes: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
525
+ );
526
+ }
527
+ return Node.fromJSONArray(data);
528
+ }
529
+ /**
530
+ * 设置节点文本
531
+ * @param node 目标节点
532
+ * @param text 要设置的文本
533
+ * @param timeout 超时时间(秒),默认30秒
534
+ * @returns 是否设置成功
535
+ */
536
+ static async setNodeText(node, text, timeout) {
537
+ const response = await this.asyncCall(CallMethod.setNodeText, {
538
+ args: { text },
539
+ node,
540
+ timeout
541
+ });
542
+ return response.getDataOrDefault(false);
543
+ }
544
+ /**
545
+ * 对指定节点进行截图
546
+ * @param nodes 要截图的节点数组
547
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
548
+ * @param timeout 超时时间(秒),默认30秒
549
+ * @returns 截图路径数组
550
+ */
551
+ static async takeScreenshotNodes(nodes, overlayHiddenScreenshotDelayMillis = 250, timeout) {
552
+ const response = await this.asyncCall(CallMethod.takeScreenshot, {
553
+ nodes,
554
+ args: { overlayHiddenScreenshotDelayMillis },
555
+ timeout
556
+ });
557
+ const data = response.getDataOrDefault({ images: [] });
558
+ return data.images;
559
+ }
560
+ /**
561
+ * 保存全屏截图到文件
562
+ * @param options 截图保存选项
563
+ * @param options.filePath 文件路径(可选,不提供则自动生成)
564
+ * @param options.format 图片格式,支持 "PNG"、"JPEG"、"JPG"、"WEBP",默认为 "PNG"
565
+ * @param options.overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒),默认为 250
566
+ * @param options.timeout 超时时间(秒),默认30秒
567
+ * @returns 保存的文件路径
568
+ */
569
+ static async takeScreenshotSave(options = {}) {
570
+ const {
571
+ filePath,
572
+ format = "PNG",
573
+ overlayHiddenScreenshotDelayMillis = 250,
574
+ timeout
575
+ } = options;
576
+ const response = await this.asyncCall(CallMethod.takeScreenshotSave, {
577
+ args: {
578
+ filePath,
579
+ format,
580
+ overlayHiddenScreenshotDelayMillis
581
+ },
582
+ timeout
583
+ });
584
+ const data = response.getDataOrDefault({ file: "" });
585
+ return data.file;
586
+ }
587
+ /**
588
+ * 保存截图到文件(支持多个节点)
589
+ * @param options 截图保存选项
590
+ * @param options.nodes 要截图的节点数组(可选,不提供则保存全屏截图)
591
+ * @param options.filePath 文件路径(可选,不提供则自动生成。多个节点时会自动添加索引后缀)
592
+ * @param options.format 图片格式,支持 "PNG"、"JPEG"、"JPG"、"WEBP",默认为 "PNG"
593
+ * @param options.overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒),默认为 250
594
+ * @param options.timeout 超时时间(秒),默认30秒
595
+ * @returns 保存的文件路径数组
596
+ */
597
+ static async takeScreenshotToFile(options = {}) {
598
+ const {
599
+ nodes,
600
+ filePath,
601
+ format = "PNG",
602
+ overlayHiddenScreenshotDelayMillis = 250,
603
+ timeout
604
+ } = options;
605
+ const response = await this.asyncCall(CallMethod.takeScreenshotToFile, {
606
+ nodes,
607
+ args: {
608
+ filePath,
609
+ format,
610
+ overlayHiddenScreenshotDelayMillis
611
+ },
612
+ timeout
613
+ });
614
+ const data = response.getDataOrDefault({ files: [] });
615
+ if (!Array.isArray(data.files)) {
616
+ throw new Error(
617
+ `AssistsXAsync.takeScreenshotToFile: Expected files array, but got ${typeof data.files}. Value: ${JSON.stringify(data.files)}`
618
+ );
619
+ }
620
+ return data.files;
621
+ }
622
+ /**
623
+ * 截图识别文本
624
+ * @param param0 识别参数
625
+ * @returns 截图识别结果
626
+ */
627
+ static async recognizeTextInScreenshot(targetText, options = {}) {
628
+ const {
629
+ rotationDegrees = 0,
630
+ overlayHiddenScreenshotDelayMillis = 250,
631
+ restoreOverlay = true,
632
+ region,
633
+ timeout
634
+ } = options;
635
+ const response = await this.asyncCall(
636
+ CallMethod.recognizeTextInScreenshot,
637
+ {
638
+ args: {
639
+ targetText,
640
+ rotationDegrees,
641
+ overlayHiddenScreenshotDelayMillis,
642
+ restoreOverlay,
643
+ region
644
+ },
645
+ timeout
646
+ }
647
+ );
648
+ return response.getDataOrDefault({
649
+ fullText: "",
650
+ processingTimeMillis: 0,
651
+ positions: []
652
+ });
653
+ }
654
+ static async scanQR(timeout) {
655
+ const response = await this.asyncCall(CallMethod.scanQR, { timeout });
656
+ const data = response.getDataOrDefault({ value: "" });
657
+ return data.value;
658
+ }
659
+ static async loadWebViewOverlay(url, options = {}) {
660
+ const {
661
+ initialWidth,
662
+ initialHeight,
663
+ initialX,
664
+ initialY,
665
+ minWidth,
666
+ minHeight,
667
+ maxWidth,
668
+ maxHeight,
669
+ initialCenter,
670
+ showTopOperationArea,
671
+ showBottomOperationArea,
672
+ backgroundColor,
673
+ timeout
674
+ } = options;
675
+ const response = await this.asyncCall(CallMethod.loadWebViewOverlay, {
676
+ args: {
677
+ url,
678
+ initialWidth,
679
+ initialHeight,
680
+ initialX,
681
+ initialY,
682
+ minWidth,
683
+ minHeight,
684
+ maxWidth,
685
+ maxHeight,
686
+ initialCenter,
687
+ showTopOperationArea,
688
+ showBottomOperationArea,
689
+ backgroundColor
690
+ },
691
+ timeout
692
+ });
693
+ const data = response.getDataOrDefault({});
694
+ return data;
695
+ }
696
+ /**
697
+ * 关闭当前 WebView 悬浮窗
698
+ * @param timeout 超时时间(秒),默认30秒
699
+ * @returns 是否关闭成功(当前页面在悬浮窗内时返回 true,否则 false)
700
+ */
701
+ static async closeOverlay(timeout) {
702
+ const response = await this.asyncCall(CallMethod.closeOverlay, {
703
+ timeout
704
+ });
705
+ return response.getDataOrDefault(false);
706
+ }
707
+ /**
708
+ * 点击节点
709
+ * @param node 要点击的节点
710
+ * @param timeout 超时时间(秒),默认30秒
711
+ * @returns 是否点击成功
712
+ */
713
+ static async click(node, timeout) {
714
+ const response = await this.asyncCall(CallMethod.click, { node, timeout });
715
+ return response.getDataOrDefault(false);
716
+ }
717
+ /**
718
+ * 长按节点
719
+ * @param node 要长按的节点
720
+ * @param timeout 超时时间(秒),默认30秒
721
+ * @returns 是否长按成功
722
+ */
723
+ static async longClick(node, timeout) {
724
+ const response = await this.asyncCall(CallMethod.longClick, {
725
+ node,
726
+ timeout
727
+ });
728
+ return response.getDataOrDefault(false);
729
+ }
730
+ /**
731
+ * 启动应用
732
+ * @param packageName 应用包名
733
+ * @param timeout 超时时间(秒),默认30秒
734
+ * @returns 是否启动成功
735
+ */
736
+ static async launchApp(packageName, timeout) {
737
+ const response = await this.asyncCall(CallMethod.launchApp, {
738
+ args: { packageName },
739
+ timeout
740
+ });
741
+ return response.getDataOrDefault(false);
742
+ }
743
+ static async getPackageName(timeoutOrOptions) {
744
+ const normalized = typeof timeoutOrOptions === "number" ? { timeout: timeoutOrOptions } : timeoutOrOptions != null ? timeoutOrOptions : {};
745
+ const { timeout, scope } = normalized;
746
+ const response = await this.asyncCall(CallMethod.getPackageName, {
747
+ args: scope !== void 0 ? { scope } : void 0,
748
+ timeout
749
+ });
750
+ return response.getDataOrDefault("");
751
+ }
752
+ /**
753
+ * 显示悬浮提示
754
+ * @param text 提示文本
755
+ * @param delay 显示时长(毫秒)
756
+ * @param timeout 超时时间(秒),默认30秒
757
+ * @returns 是否显示成功
758
+ */
759
+ static async overlayToast(text, delay = 2e3, timeout) {
760
+ const response = await this.asyncCall(CallMethod.overlayToast, {
761
+ args: { text, delay },
762
+ timeout
763
+ });
764
+ return response.getDataOrDefault(false);
765
+ }
766
+ /**
767
+ * 通过ID查找节点
768
+ * @param id 节点ID
769
+ * @param filterClass 类名过滤
770
+ * @param filterText 文本过滤
771
+ * @param filterDes 描述过滤
772
+ * @param node 父节点范围
773
+ * @param timeout 超时时间(秒),默认30秒
774
+ * @returns 节点数组
775
+ */
776
+ static async findById(id, {
777
+ filterClass,
778
+ filterText,
779
+ filterDes,
780
+ node,
781
+ timeout,
782
+ scope
783
+ } = {}) {
784
+ const response = await this.asyncCall(CallMethod.findById, {
785
+ args: {
786
+ id,
787
+ filterClass,
788
+ filterText,
789
+ filterDes,
790
+ ...scope !== void 0 ? { scope } : {}
791
+ },
792
+ node,
793
+ timeout
794
+ });
795
+ const data = response.getDataOrDefault([]);
796
+ if (!Array.isArray(data)) {
797
+ throw new Error(
798
+ `AssistsXAsync.findById: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
799
+ );
800
+ }
801
+ return Node.fromJSONArray(data);
802
+ }
803
+ /**
804
+ * 通过文本查找节点
805
+ * @param text 要查找的文本
806
+ * @param filterClass 类名过滤
807
+ * @param filterViewId 视图ID过滤
808
+ * @param filterDes 描述过滤
809
+ * @param node 父节点范围
810
+ * @param timeout 超时时间(秒),默认30秒
811
+ * @returns 节点数组
812
+ */
813
+ static async findByText(text, {
814
+ filterClass,
815
+ filterViewId,
816
+ filterDes,
817
+ node,
818
+ timeout,
819
+ scope
820
+ } = {}) {
821
+ const response = await this.asyncCall(CallMethod.findByText, {
822
+ args: {
823
+ text,
824
+ filterClass,
825
+ filterViewId,
826
+ filterDes,
827
+ ...scope !== void 0 ? { scope } : {}
828
+ },
829
+ node,
830
+ timeout
831
+ });
832
+ const data = response.getDataOrDefault([]);
833
+ if (!Array.isArray(data)) {
834
+ throw new Error(
835
+ `AssistsXAsync.findByText: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
836
+ );
837
+ }
838
+ return Node.fromJSONArray(data);
839
+ }
840
+ /**
841
+ * 通过标签查找节点
842
+ * @param className 类名
843
+ * @param filterText 文本过滤
844
+ * @param filterViewId 视图ID过滤
845
+ * @param filterDes 描述过滤
846
+ * @param node 父节点范围
847
+ * @param timeout 超时时间(秒),默认30秒
848
+ * @returns 节点数组
849
+ */
850
+ static async findByTags(className, {
851
+ filterText,
852
+ filterViewId,
853
+ filterDes,
854
+ node,
855
+ timeout,
856
+ scope
857
+ } = {}) {
858
+ const response = await this.asyncCall(CallMethod.findByTags, {
859
+ args: {
860
+ className,
861
+ filterText,
862
+ filterViewId,
863
+ filterDes,
864
+ ...scope !== void 0 ? { scope } : {}
865
+ },
866
+ node,
867
+ timeout
868
+ });
869
+ const data = response.getDataOrDefault([]);
870
+ if (!Array.isArray(data)) {
871
+ throw new Error(
872
+ `AssistsXAsync.findByTags: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
873
+ );
874
+ }
875
+ return Node.fromJSONArray(data);
876
+ }
877
+ static async findByTextAllMatch(text, timeoutOrOptions) {
878
+ const normalized = typeof timeoutOrOptions === "number" ? { timeout: timeoutOrOptions } : timeoutOrOptions != null ? timeoutOrOptions : {};
879
+ const { timeout, scope } = normalized;
880
+ const response = await this.asyncCall(CallMethod.findByTextAllMatch, {
881
+ args: {
882
+ text,
883
+ ...scope !== void 0 ? { scope } : {}
884
+ },
885
+ timeout
886
+ });
887
+ const data = response.getDataOrDefault([]);
888
+ if (!Array.isArray(data)) {
889
+ throw new Error(
890
+ `AssistsXAsync.findByTextAllMatch: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
891
+ );
892
+ }
893
+ return Node.fromJSONArray(data);
894
+ }
895
+ /**
896
+ * 检查是否包含指定文本
897
+ * @param text 要检查的文本
898
+ * @param timeout 超时时间(秒),默认30秒
899
+ * @returns 是否包含
900
+ */
901
+ static async containsText(text, timeout) {
902
+ const response = await this.asyncCall(CallMethod.containsText, {
903
+ args: { text },
904
+ timeout
905
+ });
906
+ return response.getDataOrDefault(false);
907
+ }
908
+ /**
909
+ * 获取所有文本
910
+ * @param timeout 超时时间(秒),默认30秒
911
+ * @returns 文本数组
912
+ */
913
+ static async getAllText(timeout) {
914
+ const response = await this.asyncCall(CallMethod.getAllText, { timeout });
915
+ const data = response.getDataOrDefault([]);
916
+ if (!Array.isArray(data)) {
917
+ throw new Error(
918
+ `AssistsXAsync.getAllText: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
919
+ );
920
+ }
921
+ return data;
922
+ }
923
+ /**
924
+ * 查找第一个匹配标签的父节点
925
+ * @param className 类名
926
+ * @param timeout 超时时间(秒),默认30秒
927
+ * @returns 父节点
928
+ */
929
+ static async findFirstParentByTags(node, className, timeout) {
930
+ const response = await this.asyncCall(CallMethod.findFirstParentByTags, {
931
+ args: { className },
932
+ node,
933
+ timeout
934
+ });
935
+ return Node.create(response.getDataOrDefault({}));
936
+ }
937
+ /**
938
+ * 获取节点的所有子节点
939
+ * @param node 父节点
940
+ * @param timeout 超时时间(秒),默认30秒
941
+ * @returns 子节点数组
942
+ */
943
+ static async getNodes(node, timeout) {
944
+ const response = await this.asyncCall(CallMethod.getNodes, {
945
+ node,
946
+ timeout
947
+ });
948
+ const data = response.getDataOrDefault([]);
949
+ if (!Array.isArray(data)) {
950
+ throw new Error(
951
+ `AssistsXAsync.getNodes: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
952
+ );
953
+ }
954
+ return Node.fromJSONArray(data);
955
+ }
956
+ /**
957
+ * 获取节点的直接子节点
958
+ * @param node 父节点
959
+ * @param timeout 超时时间(秒),默认30秒
960
+ * @returns 子节点数组
961
+ */
962
+ static async getChildren(node, timeout) {
963
+ const response = await this.asyncCall(CallMethod.getChildren, {
964
+ node,
965
+ timeout
966
+ });
967
+ const data = response.getDataOrDefault([]);
968
+ if (!Array.isArray(data)) {
969
+ throw new Error(
970
+ `AssistsXAsync.getChildren: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
971
+ );
972
+ }
973
+ return Node.fromJSONArray(data);
974
+ }
975
+ /**
976
+ * 查找第一个可点击的父节点
977
+ * @param node 起始节点
978
+ * @param timeout 超时时间(秒),默认30秒
979
+ * @returns 可点击的父节点
980
+ */
981
+ static async findFirstParentClickable(node, timeout) {
982
+ const response = await this.asyncCall(CallMethod.findFirstParentClickable, {
983
+ node,
984
+ timeout
985
+ });
986
+ return Node.create(response.getDataOrDefault({}));
987
+ }
988
+ /**
989
+ * 获取节点在屏幕中的边界
990
+ * @param node 目标节点
991
+ * @param timeout 超时时间(秒),默认30秒
992
+ * @returns 边界对象
993
+ */
994
+ static async getBoundsInScreen(node, timeout) {
995
+ const response = await this.asyncCall(CallMethod.getBoundsInScreen, {
996
+ node,
997
+ timeout
998
+ });
999
+ return Bounds.fromData(response.getDataOrDefault({}));
1000
+ }
1001
+ /**
1002
+ * 检查节点是否可见
1003
+ * @param node 目标节点
1004
+ * @param compareNode 比较节点
1005
+ * @param isFullyByCompareNode 是否完全可见
1006
+ * @param timeout 超时时间(秒),默认30秒
1007
+ * @returns 是否可见
1008
+ */
1009
+ static async isVisible(node, {
1010
+ compareNode,
1011
+ isFullyByCompareNode,
1012
+ timeout
1013
+ } = {}) {
1014
+ const response = await this.asyncCall(CallMethod.isVisible, {
1015
+ node,
1016
+ args: { compareNode, isFullyByCompareNode },
1017
+ timeout
1018
+ });
1019
+ return response.getDataOrDefault(false);
1020
+ }
1021
+ /**
1022
+ * 执行点击手势
1023
+ * @param x 横坐标
1024
+ * @param y 纵坐标
1025
+ * @param duration 持续时间
1026
+ * @param timeout 超时时间(秒),默认30秒
1027
+ * @returns 是否成功
1028
+ */
1029
+ static async clickByGesture(x, y, duration, timeout) {
1030
+ const response = await this.asyncCall(CallMethod.clickByGesture, {
1031
+ args: { x, y, duration },
1032
+ timeout
1033
+ });
1034
+ return response.getDataOrDefault(false);
1035
+ }
1036
+ /**
1037
+ * 返回操作
1038
+ * @param timeout 超时时间(秒),默认30秒
1039
+ * @returns 是否成功
1040
+ */
1041
+ static async back(timeout) {
1042
+ const response = await this.asyncCall(CallMethod.back, { timeout });
1043
+ return response.getDataOrDefault(false);
1044
+ }
1045
+ /**
1046
+ * 回到主页
1047
+ * @param timeout 超时时间(秒),默认30秒
1048
+ * @returns 是否成功
1049
+ */
1050
+ static async home(timeout) {
1051
+ const response = await this.asyncCall(CallMethod.home, { timeout });
1052
+ return response.getDataOrDefault(false);
1053
+ }
1054
+ /**
1055
+ * 打开通知栏
1056
+ * @param timeout 超时时间(秒),默认30秒
1057
+ * @returns 是否成功
1058
+ */
1059
+ static async notifications(timeout) {
1060
+ const response = await this.asyncCall(CallMethod.notifications, {
1061
+ timeout
1062
+ });
1063
+ return response.getDataOrDefault(false);
1064
+ }
1065
+ /**
1066
+ * 显示最近应用
1067
+ * @param timeout 超时时间(秒),默认30秒
1068
+ * @returns 是否成功
1069
+ */
1070
+ static async recentApps(timeout) {
1071
+ const response = await this.asyncCall(CallMethod.recentApps, { timeout });
1072
+ return response.getDataOrDefault(false);
1073
+ }
1074
+ /**
1075
+ * 在节点中粘贴文本
1076
+ * @param node 目标节点
1077
+ * @param text 要粘贴的文本
1078
+ * @param timeout 超时时间(秒),默认30秒
1079
+ * @returns 是否成功
1080
+ */
1081
+ static async paste(node, text, timeout) {
1082
+ const response = await this.asyncCall(CallMethod.paste, {
1083
+ args: { text },
1084
+ node,
1085
+ timeout
1086
+ });
1087
+ return response.getDataOrDefault(false);
1088
+ }
1089
+ static async focus(node, timeout) {
1090
+ const response = await this.asyncCall(CallMethod.focus, { node, timeout });
1091
+ return response.getDataOrDefault(false);
1092
+ }
1093
+ /**
1094
+ * 选择文本
1095
+ * @param node 目标节点
1096
+ * @param selectionStart 选择起始位置
1097
+ * @param selectionEnd 选择结束位置
1098
+ * @param timeout 超时时间(秒),默认30秒
1099
+ * @returns 是否成功
1100
+ */
1101
+ static async selectionText(node, selectionStart, selectionEnd, timeout) {
1102
+ const response = await this.asyncCall(CallMethod.selectionText, {
1103
+ args: { selectionStart, selectionEnd },
1104
+ node,
1105
+ timeout
1106
+ });
1107
+ return response.getDataOrDefault(false);
1108
+ }
1109
+ /**
1110
+ * 向前滚动
1111
+ * @param node 可滚动节点
1112
+ * @param timeout 超时时间(秒),默认30秒
1113
+ * @returns 是否成功
1114
+ */
1115
+ static async scrollForward(node, timeout) {
1116
+ const response = await this.asyncCall(CallMethod.scrollForward, {
1117
+ node,
1118
+ timeout
1119
+ });
1120
+ return response.getDataOrDefault(false);
1121
+ }
1122
+ /**
1123
+ * 向后滚动
1124
+ * @param node 可滚动节点
1125
+ * @param timeout 超时时间(秒),默认30秒
1126
+ * @returns 是否成功
1127
+ */
1128
+ static async scrollBackward(node, timeout) {
1129
+ const response = await this.asyncCall(CallMethod.scrollBackward, {
1130
+ node,
1131
+ timeout
1132
+ });
1133
+ return response.getDataOrDefault(false);
1134
+ }
1135
+ /**
1136
+ * 对节点执行点击手势
1137
+ * @param node 目标节点
1138
+ * @param offsetX X轴偏移
1139
+ * @param offsetY Y轴偏移
1140
+ * @param switchWindowIntervalDelay 窗口切换延迟
1141
+ * @param clickDuration 点击持续时间
1142
+ * @param timeout 超时时间(秒),默认30秒
1143
+ * @returns 是否成功
1144
+ */
1145
+ static async clickNodeByGesture(node, {
1146
+ offsetX,
1147
+ offsetY,
1148
+ switchWindowIntervalDelay,
1149
+ clickDuration,
1150
+ timeout
1151
+ } = {}) {
1152
+ const response = await this.asyncCall(CallMethod.clickNodeByGesture, {
1153
+ node,
1154
+ args: { offsetX, offsetY, switchWindowIntervalDelay, clickDuration },
1155
+ timeout
1156
+ });
1157
+ return response.getDataOrDefault(false);
1158
+ }
1159
+ /**
1160
+ * 对节点执行双击手势
1161
+ * @param node 目标节点
1162
+ * @param offsetX X轴偏移
1163
+ * @param offsetY Y轴偏移
1164
+ * @param switchWindowIntervalDelay 窗口切换延迟
1165
+ * @param clickDuration 点击持续时间
1166
+ * @param clickInterval 点击间隔
1167
+ * @param timeout 超时时间(秒),默认30秒
1168
+ * @returns 是否成功
1169
+ */
1170
+ static async doubleClickNodeByGesture(node, {
1171
+ offsetX,
1172
+ offsetY,
1173
+ switchWindowIntervalDelay,
1174
+ clickDuration,
1175
+ clickInterval,
1176
+ timeout
1177
+ } = {}) {
1178
+ const response = await this.asyncCall(CallMethod.doubleClickNodeByGesture, {
1179
+ node,
1180
+ args: {
1181
+ offsetX,
1182
+ offsetY,
1183
+ switchWindowIntervalDelay,
1184
+ clickDuration,
1185
+ clickInterval
1186
+ },
1187
+ timeout
1188
+ });
1189
+ return response.getDataOrDefault(false);
1190
+ }
1191
+ /**
1192
+ * 执行线型手势
1193
+ * @param startPoint
1194
+ * @param endPoint
1195
+ * @param param2
1196
+ * @param timeout 超时时间(秒),默认30秒
1197
+ * @returns
1198
+ */
1199
+ static async performLinearGesture(startPoint, endPoint, { duration, timeout } = {}) {
1200
+ const response = await this.asyncCall(CallMethod.performLinearGesture, {
1201
+ args: { startPoint, endPoint, duration },
1202
+ timeout
1203
+ });
1204
+ return response.getDataOrDefault(false);
1205
+ }
1206
+ static async longPressNodeByGestureAutoPaste(node, text, {
1207
+ matchedPackageName,
1208
+ matchedText,
1209
+ timeoutMillis,
1210
+ longPressDuration,
1211
+ timeout
1212
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
1213
+ const response = await this.asyncCall(
1214
+ CallMethod.longPressGestureAutoPaste,
1215
+ {
1216
+ node,
1217
+ args: {
1218
+ text,
1219
+ matchedPackageName,
1220
+ matchedText,
1221
+ timeoutMillis,
1222
+ longPressDuration
1223
+ },
1224
+ timeout
1225
+ }
1226
+ );
1227
+ return response.getDataOrDefault(false);
1228
+ }
1229
+ static async longPressGestureAutoPaste(point, text, {
1230
+ matchedPackageName,
1231
+ matchedText,
1232
+ timeoutMillis,
1233
+ longPressDuration,
1234
+ timeout
1235
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
1236
+ const response = await this.asyncCall(
1237
+ CallMethod.longPressGestureAutoPaste,
1238
+ {
1239
+ args: {
1240
+ point,
1241
+ text,
1242
+ matchedPackageName,
1243
+ matchedText,
1244
+ timeoutMillis,
1245
+ longPressDuration
1246
+ },
1247
+ timeout
1248
+ }
1249
+ );
1250
+ return response.getDataOrDefault(false);
1251
+ }
1252
+ static async getAppInfo(packageName, timeout) {
1253
+ const response = await this.asyncCall(CallMethod.getAppInfo, {
1254
+ args: { packageName },
1255
+ timeout
1256
+ });
1257
+ return AppInfo.fromJSON(response.getDataOrDefault({}));
1258
+ }
1259
+ static async getUniqueDeviceId(timeout) {
1260
+ const response = await this.asyncCall(CallMethod.getUniqueDeviceId, {
1261
+ timeout
1262
+ });
1263
+ return response.getDataOrDefault("");
1264
+ }
1265
+ static async getAndroidID(timeout) {
1266
+ const response = await this.asyncCall(CallMethod.getAndroidID, { timeout });
1267
+ return response.getDataOrDefault("");
1268
+ }
1269
+ static async getMacAddress(timeout) {
1270
+ const response = await this.asyncCall(CallMethod.getMacAddress, {
1271
+ timeout
1272
+ });
1273
+ return response.getDataOrDefault({});
1274
+ }
1275
+ static async getDeviceInfo(timeout) {
1276
+ const response = await this.asyncCall(CallMethod.getDeviceInfo, {
1277
+ timeout
1278
+ });
1279
+ return DeviceInfo.fromJSON(response.getDataOrDefault({}));
1280
+ }
1281
+ /**
1282
+ * 获取屏幕尺寸
1283
+ * @param timeout 超时时间(秒),默认30秒
1284
+ * @returns 屏幕尺寸对象
1285
+ */
1286
+ static async getScreenSize(timeout) {
1287
+ const response = await this.asyncCall(CallMethod.getScreenSize, {
1288
+ timeout
1289
+ });
1290
+ return response.getDataOrDefault({});
1291
+ }
1292
+ /**
1293
+ * 获取应用窗口尺寸
1294
+ * @param timeout 超时时间(秒),默认30秒
1295
+ * @returns 应用窗口尺寸对象
1296
+ */
1297
+ static async getAppScreenSize(timeout) {
1298
+ const response = await this.asyncCall(CallMethod.getAppScreenSize, {
1299
+ timeout
1300
+ });
1301
+ return response.getDataOrDefault({});
1302
+ }
1303
+ /**
1304
+ * 在浏览器中打开URL
1305
+ * @param url 要打开的URL
1306
+ * @param timeout 超时时间(秒),默认30秒
1307
+ * @returns 是否成功打开
1308
+ */
1309
+ static async openUrlInBrowser(url, timeout) {
1310
+ const response = await this.asyncCall(CallMethod.openUrlInBrowser, {
1311
+ args: { url },
1312
+ timeout
1313
+ });
1314
+ return response.getDataOrDefault(false);
1315
+ }
1316
+ static async download(url, timeout) {
1317
+ const response = await this.asyncCall(CallMethod.download, {
1318
+ args: { url },
1319
+ timeout
1320
+ });
1321
+ return response.getDataOrDefault(null);
1322
+ }
1323
+ static async audioPlayFromFile(filePath, {
1324
+ volume = void 0,
1325
+ useAbsoluteVolume = false,
1326
+ timeout = 30
1327
+ }) {
1328
+ const response = await this.asyncCall(CallMethod.audioPlayFromFile, {
1329
+ args: { filePath, volume, useAbsoluteVolume },
1330
+ timeout
1331
+ });
1332
+ return response.getDataOrDefault(null);
1333
+ }
1334
+ static async audioStop({
1335
+ timeout = 30
1336
+ }) {
1337
+ const response = await this.asyncCall(CallMethod.audioStop, {
1338
+ timeout
1339
+ });
1340
+ return response.getDataOrDefault(false);
1341
+ }
1342
+ /**
1343
+ * 播放系统电话铃声
1344
+ * @param timeout 超时时间(秒),默认30秒
1345
+ * @returns 播放结果消息
1346
+ */
1347
+ static async audioPlayRingtone({
1348
+ timeout = 30
1349
+ }) {
1350
+ const response = await this.asyncCall(CallMethod.audioPlayRingtone, {
1351
+ timeout
1352
+ });
1353
+ return response.getDataOrDefault("");
1354
+ }
1355
+ /**
1356
+ * 停止播放系统电话铃声
1357
+ * @param timeout 超时时间(秒),默认30秒
1358
+ * @returns 停止结果消息
1359
+ */
1360
+ static async audioStopRingtone({
1361
+ timeout = 30
1362
+ }) {
1363
+ const response = await this.asyncCall(CallMethod.audioStopRingtone, {
1364
+ timeout
1365
+ });
1366
+ return response.getDataOrDefault("");
1367
+ }
1368
+ /**
1369
+ * 添加联系人
1370
+ * @param name 联系人姓名(必填)
1371
+ * @param phoneNumber 电话号码(必填)
1372
+ * @param timeout 超时时间(秒),默认30秒
1373
+ * @returns 是否添加成功
1374
+ */
1375
+ static async addContact(name, phoneNumber, timeout) {
1376
+ const response = await this.asyncCall(CallMethod.addContact, {
1377
+ args: { name, phoneNumber },
1378
+ timeout
1379
+ });
1380
+ return response.getDataOrDefault(false);
1381
+ }
1382
+ /**
1383
+ * 获取所有联系人
1384
+ * @param timeout 超时时间(秒),默认30秒
1385
+ * @returns 联系人列表
1386
+ */
1387
+ static async getAllContacts(timeout) {
1388
+ const response = await this.asyncCall(CallMethod.getAllContacts, {
1389
+ timeout
1390
+ });
1391
+ const data = response.getDataOrDefault([]);
1392
+ if (!Array.isArray(data)) {
1393
+ throw new Error(
1394
+ `AssistsXAsync.getAllContacts: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
1395
+ );
1396
+ }
1397
+ return data;
1398
+ }
1399
+ /**
1400
+ * 保存根节点树为JSON文件
1401
+ * @param options 保存选项
1402
+ * @param options.filePath 文件路径(可选,不提供则自动生成)
1403
+ * @param options.prettyPrint 是否格式化输出,默认为 true
1404
+ * @param options.timeout 超时时间(秒),默认30秒
1405
+ * @param options.scope 节点查找范围(可选)
1406
+ * @returns 保存的文件路径
1407
+ */
1408
+ static async saveRootNodeTreeJson(options = {}) {
1409
+ const {
1410
+ filePath,
1411
+ prettyPrint = true,
1412
+ timeout,
1413
+ scope
1414
+ } = options;
1415
+ const response = await this.asyncCall(CallMethod.saveRootNodeTreeJson, {
1416
+ args: {
1417
+ filePath,
1418
+ prettyPrint,
1419
+ ...scope !== void 0 ? { scope } : {}
1420
+ },
1421
+ timeout
1422
+ });
1423
+ const data = response.getDataOrDefault({ file: "" });
1424
+ return data.file;
1425
+ }
1426
+ /**
1427
+ * 获取剪贴板文本内容
1428
+ * @param timeout 超时时间(秒),默认30秒
1429
+ * @returns 剪贴板文本内容,如果获取失败则返回空字符串
1430
+ */
1431
+ static async getClipboardText(timeout) {
1432
+ const response = await this.asyncCall(CallMethod.getClipboardText, {
1433
+ timeout
1434
+ });
1435
+ const data = response.getDataOrDefault({ text: "" });
1436
+ return data.text || "";
1437
+ }
1438
+ /**
1439
+ * 发送HTTP请求
1440
+ * @param options 请求选项
1441
+ * @returns HTTP响应
1442
+ */
1443
+ // public static async httpRequest(
1444
+ // options: HttpRequestOptions
1445
+ // ): Promise<HttpResponse> {
1446
+ // const { url, method = "GET", headers, body, timeout = 30 } = options;
1447
+ // const response = await this.asyncCall(CallMethod.httpRequest, {
1448
+ // args: { url, method, headers, body, timeout },
1449
+ // });
1450
+ // return response.getDataOrDefault({
1451
+ // statusCode: -1,
1452
+ // statusMessage: "",
1453
+ // body: "",
1454
+ // headers: {},
1455
+ // });
1456
+ // }
1457
+ };
1458
+
1459
+ // src/node-async.ts
1460
+ var NodeAsync = class {
1461
+ /**
1462
+ * 构造函数
1463
+ * @param node Node实例
1464
+ */
1465
+ constructor(node) {
1466
+ this.node = node;
1467
+ }
1468
+ /**
1469
+ * 查找第一个匹配标签的父节点
1470
+ * @param className 类名
1471
+ * @returns 父节点
1472
+ */
1473
+ async findFirstParentByTags(className) {
1474
+ Step.assert(this.node.stepId);
1475
+ const node = await AssistsXAsync.findFirstParentByTags(
1476
+ this.node,
1477
+ className
1478
+ );
1479
+ Step.assert(this.node.stepId);
1480
+ return node;
1481
+ }
1482
+ /**
1483
+ * 对节点执行点击手势
1484
+ * @param offsetX X轴偏移
1485
+ * @param offsetY Y轴偏移
1486
+ * @param switchWindowIntervalDelay 窗口切换延迟
1487
+ * @param clickDuration 点击持续时间
1488
+ * @returns 是否点击成功
1489
+ */
1490
+ async clickNodeByGesture({
1491
+ offsetX,
1492
+ offsetY,
1493
+ switchWindowIntervalDelay,
1494
+ clickDuration
1495
+ } = {}) {
1496
+ Step.assert(this.node.stepId);
1497
+ const result = await AssistsXAsync.clickNodeByGesture(this.node, {
1498
+ offsetX,
1499
+ offsetY,
1500
+ switchWindowIntervalDelay,
1501
+ clickDuration
1502
+ });
1503
+ Step.assert(this.node.stepId);
1504
+ return result;
1505
+ }
1506
+ /**
1507
+ * 对节点执行双击手势
1508
+ * @param offsetX X轴偏移
1509
+ * @param offsetY Y轴偏移
1510
+ * @param switchWindowIntervalDelay 窗口切换延迟
1511
+ * @param clickDuration 点击持续时间
1512
+ * @param clickInterval 点击间隔
1513
+ * @returns 是否双击成功
1514
+ */
1515
+ async doubleClickNodeByGesture({
1516
+ offsetX,
1517
+ offsetY,
1518
+ switchWindowIntervalDelay,
1519
+ clickDuration,
1520
+ clickInterval
1521
+ } = {}) {
1522
+ Step.assert(this.node.stepId);
1523
+ const result = await AssistsXAsync.doubleClickNodeByGesture(this.node, {
1524
+ offsetX,
1525
+ offsetY,
1526
+ switchWindowIntervalDelay,
1527
+ clickDuration,
1528
+ clickInterval
1529
+ });
1530
+ Step.assert(this.node.stepId);
1531
+ return result;
1532
+ }
1533
+ async longPressNodeByGestureAutoPaste(text, {
1534
+ matchedPackageName,
1535
+ matchedText,
1536
+ timeoutMillis,
1537
+ longPressDuration
1538
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
1539
+ Step.assert(this.node.stepId);
1540
+ const result = await AssistsXAsync.longPressNodeByGestureAutoPaste(
1541
+ this.node,
1542
+ text,
1543
+ {
1544
+ matchedPackageName,
1545
+ matchedText,
1546
+ timeoutMillis,
1547
+ longPressDuration
1548
+ }
1549
+ );
1550
+ Step.assert(this.node.stepId);
1551
+ return result;
1552
+ }
1553
+ /**
1554
+ * 在当前节点范围内通过标签查找节点
1555
+ * @param className 类名
1556
+ * @param filterText 文本过滤
1557
+ * @param filterViewId 视图ID过滤
1558
+ * @param filterDes 描述过滤
1559
+ * @returns 节点数组
1560
+ */
1561
+ async findByTags(className, {
1562
+ filterText,
1563
+ filterViewId,
1564
+ filterDes
1565
+ } = {}) {
1566
+ Step.assert(this.node.stepId);
1567
+ const result = await AssistsXAsync.findByTags(className, {
1568
+ filterText,
1569
+ filterViewId,
1570
+ filterDes,
1571
+ node: this.node
1572
+ });
1573
+ Step.assignIdsToNodes(result, this.node.stepId);
1574
+ Step.assert(this.node.stepId);
1575
+ return result;
1576
+ }
1577
+ /**
1578
+ * 在当前节点范围内通过ID查找节点
1579
+ * @param id 节点ID
1580
+ * @param filterClass 类名过滤
1581
+ * @param filterText 文本过滤
1582
+ * @param filterDes 描述过滤
1583
+ * @returns 节点数组
1584
+ */
1585
+ async findById(id, {
1586
+ filterClass,
1587
+ filterText,
1588
+ filterDes
1589
+ } = {}) {
1590
+ Step.assert(this.node.stepId);
1591
+ const result = await AssistsXAsync.findById(id, {
1592
+ filterClass,
1593
+ filterText,
1594
+ filterDes,
1595
+ node: this.node
1596
+ });
1597
+ Step.assignIdsToNodes(result, this.node.stepId);
1598
+ Step.assert(this.node.stepId);
1599
+ return result;
1600
+ }
1601
+ /**
1602
+ * 在当前节点范围内通过文本查找节点
1603
+ * @param text 要查找的文本
1604
+ * @param filterClass 类名过滤
1605
+ * @param filterViewId 视图ID过滤
1606
+ * @param filterDes 描述过滤
1607
+ * @returns 节点数组
1608
+ */
1609
+ async findByText(text, {
1610
+ filterClass,
1611
+ filterViewId,
1612
+ filterDes
1613
+ } = {}) {
1614
+ Step.assert(this.node.stepId);
1615
+ const result = await AssistsXAsync.findByText(text, {
1616
+ filterClass,
1617
+ filterViewId,
1618
+ filterDes,
1619
+ node: this.node
1620
+ });
1621
+ Step.assignIdsToNodes(result, this.node.stepId);
1622
+ Step.assert(this.node.stepId);
1623
+ return result;
1624
+ }
1625
+ /**
1626
+ * 向前滚动节点
1627
+ * @returns 是否滚动成功
1628
+ */
1629
+ async scrollForward() {
1630
+ Step.assert(this.node.stepId);
1631
+ const response = await AssistsXAsync.scrollForward(this.node);
1632
+ Step.assert(this.node.stepId);
1633
+ return response;
1634
+ }
1635
+ /**
1636
+ * 向后滚动节点
1637
+ * @returns 是否滚动成功
1638
+ */
1639
+ async scrollBackward() {
1640
+ Step.assert(this.node.stepId);
1641
+ const response = await AssistsXAsync.scrollBackward(this.node);
1642
+ Step.assert(this.node.stepId);
1643
+ return response;
1644
+ }
1645
+ /**
1646
+ * 检查节点是否可见
1647
+ * @param compareNode 比较节点
1648
+ * @param isFullyByCompareNode 是否完全可见
1649
+ * @returns 是否可见
1650
+ */
1651
+ async isVisible({
1652
+ compareNode,
1653
+ isFullyByCompareNode
1654
+ } = {}) {
1655
+ Step.assert(this.node.stepId);
1656
+ const response = await AssistsXAsync.isVisible(this.node, {
1657
+ compareNode,
1658
+ isFullyByCompareNode
1659
+ });
1660
+ Step.assert(this.node.stepId);
1661
+ return response;
1662
+ }
1663
+ /**
1664
+ * 对节点进行截图
1665
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
1666
+ * @returns 截图路径
1667
+ */
1668
+ async takeScreenshot(overlayHiddenScreenshotDelayMillis = 250) {
1669
+ Step.assert(this.node.stepId);
1670
+ const result = await AssistsXAsync.takeScreenshotNodes(
1671
+ [this.node],
1672
+ overlayHiddenScreenshotDelayMillis
1673
+ );
1674
+ Step.assert(this.node.stepId);
1675
+ return result[0];
1676
+ }
1677
+ /**
1678
+ * 设置节点文本
1679
+ * @param text 要设置的文本
1680
+ * @returns 是否设置成功
1681
+ */
1682
+ async setNodeText(text) {
1683
+ Step.assert(this.node.stepId);
1684
+ const result = await AssistsXAsync.setNodeText(this.node, text);
1685
+ Step.assert(this.node.stepId);
1686
+ return result;
1687
+ }
1688
+ async paste(text) {
1689
+ Step.assert(this.node.stepId);
1690
+ const result = await AssistsXAsync.paste(this.node, text);
1691
+ Step.assert(this.node.stepId);
1692
+ return result;
1693
+ }
1694
+ async focus() {
1695
+ Step.assert(this.node.stepId);
1696
+ const result = await AssistsXAsync.focus(this.node);
1697
+ Step.assert(this.node.stepId);
1698
+ return result;
1699
+ }
1700
+ /**
1701
+ * 点击节点
1702
+ * @returns 是否点击成功
1703
+ */
1704
+ async click() {
1705
+ Step.assert(this.node.stepId);
1706
+ const result = await AssistsXAsync.click(this.node);
1707
+ Step.assert(this.node.stepId);
1708
+ return result;
1709
+ }
1710
+ /**
1711
+ * 长按节点
1712
+ * @returns 是否长按成功
1713
+ */
1714
+ async longClick() {
1715
+ Step.assert(this.node.stepId);
1716
+ const result = await AssistsXAsync.longClick(this.node);
1717
+ Step.assert(this.node.stepId);
1718
+ return result;
1719
+ }
1720
+ /**
1721
+ * 查找第一个可点击的父节点
1722
+ * @returns 可点击的父节点
1723
+ */
1724
+ async findFirstParentClickable() {
1725
+ Step.assert(this.node.stepId);
1726
+ const result = await AssistsXAsync.findFirstParentClickable(this.node);
1727
+ Step.assert(this.node.stepId);
1728
+ Step.assignIdsToNodes([result], this.node.stepId);
1729
+ return result;
1730
+ }
1731
+ /**
1732
+ * 获取节点在屏幕中的边界
1733
+ * @returns 边界对象
1734
+ */
1735
+ async getBoundsInScreen() {
1736
+ Step.assert(this.node.stepId);
1737
+ const result = await AssistsXAsync.getBoundsInScreen(this.node);
1738
+ Step.assert(this.node.stepId);
1739
+ return result;
1740
+ }
1741
+ /**
1742
+ * 获取节点的所有子节点
1743
+ * @returns 子节点数组
1744
+ */
1745
+ async getNodes() {
1746
+ Step.assert(this.node.stepId);
1747
+ const result = await AssistsXAsync.getNodes(this.node);
1748
+ Step.assert(this.node.stepId);
1749
+ Step.assignIdsToNodes(result, this.node.stepId);
1750
+ return result;
1751
+ }
1752
+ /**
1753
+ * 获取节点的直接子节点
1754
+ * @returns 子节点数组
1755
+ */
1756
+ async getChildren() {
1757
+ Step.assert(this.node.stepId);
1758
+ const result = await AssistsXAsync.getChildren(this.node);
1759
+ Step.assert(this.node.stepId);
1760
+ Step.assignIdsToNodes(result, this.node.stepId);
1761
+ return result;
1762
+ }
1763
+ /**
1764
+ * 从JSON字符串创建节点实例
1765
+ * @param json JSON字符串
1766
+ * @returns 节点实例
1767
+ */
1768
+ static fromJSON(json) {
1769
+ const data = JSON.parse(json);
1770
+ return new Node(data);
1771
+ }
1772
+ /**
1773
+ * 从普通对象创建节点实例
1774
+ * @param data 对象数据
1775
+ * @returns 节点实例
1776
+ */
1777
+ static from(data) {
1778
+ return new Node(data);
1779
+ }
1780
+ /**
1781
+ * JSON.parse的reviver函数,用于将解析的JSON对象转换为Node实例
1782
+ * @param key 属性键
1783
+ * @param value 属性值
1784
+ * @returns 转换后的值
1785
+ */
1786
+ static reviver(key, value) {
1787
+ return key === "" ? new Node(value) : value;
1788
+ }
1789
+ /**
1790
+ * 创建新的节点实例
1791
+ * @param params 节点参数对象
1792
+ * @returns 节点实例
1793
+ */
1794
+ static create(params) {
1795
+ return new Node(params);
1796
+ }
1797
+ /**
1798
+ * 从JSON数组创建节点数组
1799
+ * @param array JSON数组
1800
+ * @returns 节点数组
1801
+ */
1802
+ static fromJSONArray(array) {
1803
+ if (!Array.isArray(array)) {
1804
+ throw new Error(
1805
+ `NodeAsync.fromJSONArray: Expected array, but got ${typeof array}. Value: ${JSON.stringify(array)}`
1806
+ );
1807
+ }
1808
+ return array.map((data) => new Node(data));
1809
+ }
1810
+ };
1811
+
1812
+ // src/node.ts
1813
+ var Node = class _Node {
1814
+ /**
1815
+ * 节点在屏幕中的边界
1816
+ * @deprecated 请使用 bounds 字段替代
1817
+ */
1818
+ get boundsInScreen() {
1819
+ return this.bounds;
1820
+ }
1821
+ /**
1822
+ * 构造函数
1823
+ * @param params 节点参数对象
1824
+ */
1825
+ constructor(params) {
1826
+ var _a2;
1827
+ this.nodeId = params.nodeId;
1828
+ this.text = params.text;
1829
+ this.des = params.des;
1830
+ this.viewId = params.viewId;
1831
+ this.className = params.className;
1832
+ this.isScrollable = params.isScrollable;
1833
+ this.isClickable = params.isClickable;
1834
+ this.isEnabled = params.isEnabled;
1835
+ this.stepId = params.stepId;
1836
+ this.hintText = params.hintText;
1837
+ this.isCheckable = params.isCheckable;
1838
+ this.isChecked = params.isChecked;
1839
+ this.isFocusable = params.isFocusable;
1840
+ this.isFocused = params.isFocused;
1841
+ this.isLongClickable = params.isLongClickable;
1842
+ this.isPassword = params.isPassword;
1843
+ this.isSelected = params.isSelected;
1844
+ this.isVisibleToUser = params.isVisibleToUser;
1845
+ this.drawingOrder = params.drawingOrder;
1846
+ const rawBounds = (_a2 = params.bounds) != null ? _a2 : params.boundsInScreen;
1847
+ this.bounds = rawBounds instanceof Bounds ? rawBounds : Bounds.fromData(rawBounds);
1848
+ }
1849
+ get async() {
1850
+ return new NodeAsync(this);
1851
+ }
1852
+ /**
1853
+ * 查找第一个匹配标签的父节点
1854
+ * @param className 类名
1855
+ * @returns 父节点
1856
+ */
1857
+ findFirstParentByTags(className) {
1858
+ Step.assert(this.stepId);
1859
+ const node = AssistsX2.findFirstParentByTags(this, className);
1860
+ Step.assert(this.stepId);
1861
+ return node;
1862
+ }
1863
+ /**
1864
+ * 对节点执行点击手势
1865
+ * @param offsetX X轴偏移
1866
+ * @param offsetY Y轴偏移
1867
+ * @param switchWindowIntervalDelay 窗口切换延迟
1868
+ * @param clickDuration 点击持续时间
1869
+ * @returns 是否点击成功
1870
+ */
1871
+ async clickNodeByGesture({
1872
+ offsetX,
1873
+ offsetY,
1874
+ switchWindowIntervalDelay,
1875
+ clickDuration
1876
+ } = {}) {
1877
+ Step.assert(this.stepId);
1878
+ const result = await AssistsX2.clickNodeByGesture(this, {
1879
+ offsetX,
1880
+ offsetY,
1881
+ switchWindowIntervalDelay,
1882
+ clickDuration
1883
+ });
1884
+ Step.assert(this.stepId);
1885
+ return result;
1886
+ }
1887
+ /**
1888
+ * 对节点执行双击手势
1889
+ * @param offsetX X轴偏移
1890
+ * @param offsetY Y轴偏移
1891
+ * @param switchWindowIntervalDelay 窗口切换延迟
1892
+ * @param clickDuration 点击持续时间
1893
+ * @param clickInterval 点击间隔
1894
+ * @returns 是否双击成功
1895
+ */
1896
+ async doubleClickNodeByGesture({
1897
+ offsetX,
1898
+ offsetY,
1899
+ switchWindowIntervalDelay,
1900
+ clickDuration,
1901
+ clickInterval
1902
+ } = {}) {
1903
+ Step.assert(this.stepId);
1904
+ const result = await AssistsX2.doubleClickNodeByGesture(this, {
1905
+ offsetX,
1906
+ offsetY,
1907
+ switchWindowIntervalDelay,
1908
+ clickDuration,
1909
+ clickInterval
1910
+ });
1911
+ Step.assert(this.stepId);
1912
+ return result;
1913
+ }
1914
+ async longPressNodeByGestureAutoPaste(text, {
1915
+ matchedPackageName,
1916
+ matchedText,
1917
+ timeoutMillis,
1918
+ longPressDuration
1919
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
1920
+ Step.assert(this.stepId);
1921
+ const result = await AssistsX2.longPressNodeByGestureAutoPaste(this, text, {
1922
+ matchedPackageName,
1923
+ matchedText,
1924
+ timeoutMillis,
1925
+ longPressDuration
1926
+ });
1927
+ Step.assert(this.stepId);
1928
+ return result;
1929
+ }
1930
+ /**
1931
+ * 在当前节点范围内通过标签查找节点
1932
+ * @param className 类名
1933
+ * @param filterText 文本过滤
1934
+ * @param filterViewId 视图ID过滤
1935
+ * @param filterDes 描述过滤
1936
+ * @returns 节点数组
1937
+ */
1938
+ findByTags(className, {
1939
+ filterText,
1940
+ filterViewId,
1941
+ filterDes
1942
+ } = {}) {
1943
+ Step.assert(this.stepId);
1944
+ const result = AssistsX2.findByTags(className, {
1945
+ filterText,
1946
+ filterViewId,
1947
+ filterDes,
1948
+ node: this
1949
+ });
1950
+ Step.assignIdsToNodes(result, this.stepId);
1951
+ Step.assert(this.stepId);
1952
+ return result;
1953
+ }
1954
+ /**
1955
+ * 在当前节点范围内通过ID查找节点
1956
+ * @param id 节点ID
1957
+ * @param filterClass 类名过滤
1958
+ * @param filterText 文本过滤
1959
+ * @param filterDes 描述过滤
1960
+ * @returns 节点数组
1961
+ */
1962
+ findById(id, {
1963
+ filterClass,
1964
+ filterText,
1965
+ filterDes
1966
+ } = {}) {
1967
+ Step.assert(this.stepId);
1968
+ const result = AssistsX2.findById(id, {
1969
+ filterClass,
1970
+ filterText,
1971
+ filterDes,
1972
+ node: this
1973
+ });
1974
+ Step.assignIdsToNodes(result, this.stepId);
1975
+ Step.assert(this.stepId);
1976
+ return result;
1977
+ }
1978
+ /**
1979
+ * 在当前节点范围内通过文本查找节点
1980
+ * @param text 要查找的文本
1981
+ * @param filterClass 类名过滤
1982
+ * @param filterViewId 视图ID过滤
1983
+ * @param filterDes 描述过滤
1984
+ * @returns 节点数组
1985
+ */
1986
+ findByText(text, {
1987
+ filterClass,
1988
+ filterViewId,
1989
+ filterDes
1990
+ } = {}) {
1991
+ Step.assert(this.stepId);
1992
+ const result = AssistsX2.findByText(text, {
1993
+ filterClass,
1994
+ filterViewId,
1995
+ filterDes,
1996
+ node: this
1997
+ });
1998
+ Step.assignIdsToNodes(result, this.stepId);
1999
+ Step.assert(this.stepId);
2000
+ return result;
2001
+ }
2002
+ /**
2003
+ * 向前滚动节点
2004
+ * @returns 是否滚动成功
2005
+ */
2006
+ scrollForward() {
2007
+ Step.assert(this.stepId);
2008
+ const response = AssistsX2.scrollForward(this);
2009
+ Step.assert(this.stepId);
2010
+ return response;
2011
+ }
2012
+ /**
2013
+ * 向后滚动节点
2014
+ * @returns 是否滚动成功
2015
+ */
2016
+ scrollBackward() {
2017
+ Step.assert(this.stepId);
2018
+ const response = AssistsX2.scrollBackward(this);
2019
+ Step.assert(this.stepId);
2020
+ return response;
2021
+ }
2022
+ /**
2023
+ * 检查节点是否可见
2024
+ * @param compareNode 比较节点
2025
+ * @param isFullyByCompareNode 是否完全可见
2026
+ * @returns 是否可见
2027
+ */
2028
+ isVisible({
2029
+ compareNode,
2030
+ isFullyByCompareNode
2031
+ } = {}) {
2032
+ Step.assert(this.stepId);
2033
+ const response = AssistsX2.isVisible(this, {
2034
+ compareNode,
2035
+ isFullyByCompareNode
2036
+ });
2037
+ Step.assert(this.stepId);
2038
+ return response;
2039
+ }
2040
+ /**
2041
+ * 对节点进行截图
2042
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
2043
+ * @returns 截图路径
2044
+ */
2045
+ async takeScreenshot(overlayHiddenScreenshotDelayMillis = 250) {
2046
+ Step.assert(this.stepId);
2047
+ const result = await AssistsX2.takeScreenshotNodes(
2048
+ [this],
2049
+ overlayHiddenScreenshotDelayMillis
2050
+ );
2051
+ Step.assert(this.stepId);
2052
+ return result[0];
2053
+ }
2054
+ /**
2055
+ * 保存节点截图到文件
2056
+ * @param options 截图保存选项
2057
+ * @param options.filePath 文件路径(可选,不提供则自动生成)
2058
+ * @param options.format 图片格式,支持 "PNG"、"JPEG"、"JPG"、"WEBP",默认为 "PNG"
2059
+ * @param options.overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒),默认为 250
2060
+ * @returns 保存的文件路径
2061
+ */
2062
+ async takeScreenshotToFile(options = {}) {
2063
+ Step.assert(this.stepId);
2064
+ const result = await AssistsXAsync.takeScreenshotToFile({
2065
+ nodes: [this],
2066
+ ...options
2067
+ });
2068
+ Step.assert(this.stepId);
2069
+ return result[0];
2070
+ }
2071
+ /**
2072
+ * 设置节点文本
2073
+ * @param text 要设置的文本
2074
+ * @returns 是否设置成功
2075
+ */
2076
+ setNodeText(text) {
2077
+ Step.assert(this.stepId);
2078
+ const result = AssistsX2.setNodeText(this, text);
2079
+ Step.assert(this.stepId);
2080
+ return result;
2081
+ }
2082
+ paste(text) {
2083
+ Step.assert(this.stepId);
2084
+ const result = AssistsX2.paste(this, text);
2085
+ Step.assert(this.stepId);
2086
+ return result;
2087
+ }
2088
+ focus() {
2089
+ Step.assert(this.stepId);
2090
+ const result = AssistsX2.focus(this);
2091
+ Step.assert(this.stepId);
2092
+ return result;
2093
+ }
2094
+ /**
2095
+ * 点击节点
2096
+ * @returns 是否点击成功
2097
+ */
2098
+ click() {
2099
+ Step.assert(this.stepId);
2100
+ const result = AssistsX2.click(this);
2101
+ Step.assert(this.stepId);
2102
+ return result;
2103
+ }
2104
+ /**
2105
+ * 长按节点
2106
+ * @returns 是否长按成功
2107
+ */
2108
+ longClick() {
2109
+ Step.assert(this.stepId);
2110
+ const result = AssistsX2.longClick(this);
2111
+ Step.assert(this.stepId);
2112
+ return result;
2113
+ }
2114
+ /**
2115
+ * 查找第一个可点击的父节点
2116
+ * @returns 可点击的父节点
2117
+ */
2118
+ findFirstParentClickable() {
2119
+ Step.assert(this.stepId);
2120
+ const result = AssistsX2.findFirstParentClickable(this);
2121
+ Step.assert(this.stepId);
2122
+ Step.assignIdsToNodes([result], this.stepId);
2123
+ return result;
2124
+ }
2125
+ /**
2126
+ * 获取节点在屏幕中的边界
2127
+ * @returns 边界对象
2128
+ */
2129
+ getBoundsInScreen() {
2130
+ Step.assert(this.stepId);
2131
+ const result = AssistsX2.getBoundsInScreen(this);
2132
+ Step.assert(this.stepId);
2133
+ return result;
2134
+ }
2135
+ /**
2136
+ * 获取节点的所有子节点
2137
+ * @returns 子节点数组
2138
+ */
2139
+ getNodes() {
2140
+ Step.assert(this.stepId);
2141
+ const result = AssistsX2.getNodes(this);
2142
+ Step.assert(this.stepId);
2143
+ Step.assignIdsToNodes(result, this.stepId);
2144
+ return result;
2145
+ }
2146
+ /**
2147
+ * 获取节点的直接子节点
2148
+ * @returns 子节点数组
2149
+ */
2150
+ getChildren() {
2151
+ Step.assert(this.stepId);
2152
+ const result = AssistsX2.getChildren(this);
2153
+ Step.assert(this.stepId);
2154
+ Step.assignIdsToNodes(result, this.stepId);
2155
+ return result;
2156
+ }
2157
+ /**
2158
+ * 从JSON字符串创建节点实例
2159
+ * @param json JSON字符串
2160
+ * @returns 节点实例
2161
+ */
2162
+ static fromJSON(json) {
2163
+ const data = JSON.parse(json);
2164
+ return new _Node(data);
2165
+ }
2166
+ /**
2167
+ * 从普通对象创建节点实例
2168
+ * @param data 对象数据
2169
+ * @returns 节点实例
2170
+ */
2171
+ static from(data) {
2172
+ return new _Node(data);
2173
+ }
2174
+ /**
2175
+ * JSON.parse的reviver函数,用于将解析的JSON对象转换为Node实例
2176
+ * @param key 属性键
2177
+ * @param value 属性值
2178
+ * @returns 转换后的值
2179
+ */
2180
+ static reviver(key, value) {
2181
+ return key === "" ? new _Node(value) : value;
2182
+ }
2183
+ /**
2184
+ * 创建新的节点实例
2185
+ * @param params 节点参数对象
2186
+ * @returns 节点实例
2187
+ */
2188
+ static create(params) {
2189
+ return new _Node(params);
2190
+ }
2191
+ /**
2192
+ * 从JSON数组创建节点数组
2193
+ * @param array JSON数组
2194
+ * @returns 节点数组
2195
+ */
2196
+ static fromJSONArray(array) {
2197
+ if (!Array.isArray(array)) {
2198
+ throw new Error(
2199
+ `Node.fromJSONArray: Expected array, but got ${typeof array}. Value: ${JSON.stringify(array)}`
2200
+ );
2201
+ }
2202
+ return array.map((data) => new _Node(data));
2203
+ }
2204
+ };
2205
+
2206
+ // src/assistsx.ts
2207
+ var callbacks = /* @__PURE__ */ new Map();
2208
+ var accessibilityEventListeners = [];
2209
+ var screen;
2210
+ if (typeof window !== "undefined" && !window.assistsxCallback) {
2211
+ window.assistsxCallback = (data) => {
2212
+ let callbackId;
2213
+ try {
2214
+ const json = decodeBase64UTF8(data);
2215
+ const response = JSON.parse(json);
2216
+ callbackId = response.callbackId;
2217
+ if (callbackId) {
2218
+ const callback = callbacks.get(callbackId);
2219
+ if (callback) {
2220
+ callback(json);
2221
+ }
2222
+ }
2223
+ } catch (e) {
2224
+ console.log(e);
2225
+ } finally {
2226
+ if (callbackId) {
2227
+ callbacks.delete(callbackId);
2228
+ }
2229
+ }
2230
+ };
2231
+ }
2232
+ if (typeof window !== "undefined" && !window.onAccessibilityEvent) {
2233
+ window.onAccessibilityEvent = (event) => {
2234
+ accessibilityEventListeners.forEach((listener) => {
2235
+ try {
2236
+ const decodedEvent = decodeBase64UTF8(event);
2237
+ const parsedEvent = JSON.parse(decodedEvent);
2238
+ listener(parsedEvent);
2239
+ } catch (error) {
2240
+ console.error("Accessibility event listener error:", error);
2241
+ }
2242
+ });
2243
+ };
2244
+ }
2245
+ var AssistsX2 = class {
2246
+ /**
2247
+ * 屏幕尺寸(与全局变量 screen 同源)
2248
+ * @deprecated 已过时,请使用全局变量 {@link screen}
2249
+ */
2250
+ static get screenSize() {
2251
+ if (screen == null) return null;
2252
+ return {
2253
+ width: screen.width,
2254
+ height: screen.height,
2255
+ screenWidth: screen.width,
2256
+ screenHeight: screen.height
2257
+ };
2258
+ }
2259
+ /**
2260
+ * 执行同步调用
2261
+ * @param method 方法名
2262
+ * @param args 参数对象
2263
+ * @returns 调用响应
2264
+ */
2265
+ static call(method, { args, node } = {}) {
2266
+ const params = {
2267
+ method,
2268
+ arguments: args ? args : void 0,
2269
+ node: node ? node : void 0
2270
+ };
2271
+ const result = window.assistsx.call(JSON.stringify(params));
2272
+ if (typeof result === "string") {
2273
+ const responseData = JSON.parse(result);
2274
+ const response = new CallResponse(
2275
+ responseData.code,
2276
+ responseData.data,
2277
+ responseData.callbackId
2278
+ );
2279
+ return response;
2280
+ }
2281
+ throw new Error("Call failed");
2282
+ }
2283
+ /**
2284
+ * 执行异步调用
2285
+ * @param method 方法名
2286
+ * @param args 参数对象
2287
+ * @param timeout 超时时间(秒),默认30秒
2288
+ * @returns Promise<调用响应>
2289
+ */
2290
+ static async asyncCall(method, {
2291
+ args,
2292
+ node,
2293
+ nodes,
2294
+ timeout = 30
2295
+ } = {}) {
2296
+ const uuid = generateUUID();
2297
+ const params = {
2298
+ method,
2299
+ arguments: args ? args : void 0,
2300
+ node: node ? node : void 0,
2301
+ nodes: nodes ? nodes : void 0,
2302
+ callbackId: uuid
2303
+ };
2304
+ const promise = new Promise((resolve) => {
2305
+ callbacks.set(uuid, (data) => {
2306
+ resolve(data);
2307
+ });
2308
+ setTimeout(() => {
2309
+ callbacks.delete(uuid);
2310
+ resolve(new CallResponse(0, null, uuid));
2311
+ }, timeout * 1e3);
2312
+ });
2313
+ const result = window.assistsx.call(JSON.stringify(params));
2314
+ const promiseResult = await promise;
2315
+ if (typeof promiseResult === "string") {
2316
+ const responseData = JSON.parse(promiseResult);
2317
+ const response = new CallResponse(
2318
+ responseData.code,
2319
+ responseData.data,
2320
+ responseData.callbackId
2321
+ );
2322
+ return response;
2323
+ }
2324
+ throw new Error("Call failed");
2325
+ }
2326
+ /**
2327
+ * 设置悬浮窗标志
2328
+ * @param flags 标志
2329
+ * @returns 是否设置成功
2330
+ */
2331
+ static setOverlayFlags(flags) {
2332
+ const response = this.call(CallMethod.setOverlayFlags, {
2333
+ args: { flags }
2334
+ });
2335
+ return response.getDataOrDefault(false);
2336
+ }
2337
+ /**
2338
+ * 设置悬浮窗标志
2339
+ * @param flags 标志
2340
+ * @returns 是否设置成功
2341
+ */
2342
+ static setOverlayFlagList(flags) {
2343
+ const response = this.call(CallMethod.setOverlayFlags, {
2344
+ args: { flags }
2345
+ });
2346
+ return response.getDataOrDefault(false);
2347
+ }
2348
+ /**
2349
+ * 获取所有符合条件的节点
2350
+ * @param filterClass 类名过滤
2351
+ * @param filterViewId 视图ID过滤
2352
+ * @param filterDes 描述过滤
2353
+ * @param filterText 文本过滤
2354
+ * @returns 节点数组
2355
+ */
2356
+ static getAllNodes({
2357
+ filterClass,
2358
+ filterViewId,
2359
+ filterDes,
2360
+ filterText,
2361
+ scope
2362
+ } = {}) {
2363
+ const response = this.call(CallMethod.getAllNodes, {
2364
+ args: {
2365
+ filterClass,
2366
+ filterViewId,
2367
+ filterDes,
2368
+ filterText,
2369
+ ...scope !== void 0 ? { scope } : {}
2370
+ }
2371
+ });
2372
+ const data = response.getDataOrDefault([]);
2373
+ if (!Array.isArray(data)) {
2374
+ throw new Error(
2375
+ `AssistsX.getAllNodes: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2376
+ );
2377
+ }
2378
+ return Node.fromJSONArray(data);
2379
+ }
2380
+ /**
2381
+ * 设置节点文本
2382
+ * @param node 目标节点
2383
+ * @param text 要设置的文本
2384
+ * @returns 是否设置成功
2385
+ */
2386
+ static setNodeText(node, text) {
2387
+ const response = this.call(CallMethod.setNodeText, {
2388
+ args: { text },
2389
+ node
2390
+ });
2391
+ return response.getDataOrDefault(false);
2392
+ }
2393
+ /**
2394
+ * 获取剪贴板最新文本
2395
+ * @returns 剪贴板最新文本
2396
+ */
2397
+ static getClipboardLatestText() {
2398
+ const response = this.call(CallMethod.getClipboardLatestText);
2399
+ return response.getDataOrDefault({});
2400
+ }
2401
+ /**
2402
+ * 获取剪贴板文本内容(异步)
2403
+ * @param timeout 超时时间(秒),默认30秒
2404
+ * @returns 剪贴板文本内容,如果获取失败则返回空字符串
2405
+ */
2406
+ static async getClipboardText(timeout) {
2407
+ const response = await this.asyncCall(CallMethod.getClipboardText, {
2408
+ timeout
2409
+ });
2410
+ const data = response.getDataOrDefault({ text: "" });
2411
+ return data.text || "";
2412
+ }
2413
+ /**
2414
+ * 在浏览器中打开URL
2415
+ * @param url 要打开的URL
2416
+ * @returns 是否成功打开
2417
+ */
2418
+ static openUrlInBrowser(url) {
2419
+ const response = this.call(CallMethod.openUrlInBrowser, {
2420
+ args: { url }
2421
+ });
2422
+ return response.getDataOrDefault(false);
2423
+ }
2424
+ /**
2425
+ * 保持屏幕常亮
2426
+ * @param tip 提示文本
2427
+ * @returns 是否保持屏幕常亮成功
2428
+ */
2429
+ static keepScreenOn(tip) {
2430
+ const response = this.call(CallMethod.keepScreenOn, {
2431
+ args: { tip }
2432
+ });
2433
+ return response.getDataOrDefault(false);
2434
+ }
2435
+ static clearKeepScreenOn() {
2436
+ const response = this.call(CallMethod.clearKeepScreenOn, {});
2437
+ return response.getDataOrDefault(false);
2438
+ }
2439
+ static isAppInstalled(packageName) {
2440
+ const response = this.call(CallMethod.isAppInstalled, {
2441
+ args: { packageName }
2442
+ });
2443
+ return response.getDataOrDefault(false);
2444
+ }
2445
+ /**
2446
+ * 对指定节点进行截图
2447
+ * @param nodes 要截图的节点数组
2448
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
2449
+ * @param timeout 超时时间(秒),默认30秒
2450
+ * @returns 截图路径数组
2451
+ */
2452
+ static async takeScreenshotNodes(nodes, overlayHiddenScreenshotDelayMillis = 250, timeout) {
2453
+ const response = await this.asyncCall(CallMethod.takeScreenshot, {
2454
+ nodes,
2455
+ args: { overlayHiddenScreenshotDelayMillis },
2456
+ timeout
2457
+ });
2458
+ const data = response.getDataOrDefault({ images: [] });
2459
+ return data.images;
2460
+ }
2461
+ static async scanQR(timeout) {
2462
+ const response = await this.asyncCall(CallMethod.scanQR, { timeout });
2463
+ const data = response.getDataOrDefault({ value: "" });
2464
+ return data.value;
2465
+ }
2466
+ static async loadWebViewOverlay(url, options = {}) {
2467
+ const {
2468
+ initialWidth,
2469
+ initialHeight,
2470
+ initialX,
2471
+ initialY,
2472
+ minWidth,
2473
+ minHeight,
2474
+ maxWidth,
2475
+ maxHeight,
2476
+ initialCenter,
2477
+ showTopOperationArea,
2478
+ showBottomOperationArea,
2479
+ backgroundColor,
2480
+ timeout
2481
+ } = options;
2482
+ const response = await this.asyncCall(CallMethod.loadWebViewOverlay, {
2483
+ args: {
2484
+ url,
2485
+ initialWidth,
2486
+ initialHeight,
2487
+ initialX,
2488
+ initialY,
2489
+ minWidth,
2490
+ minHeight,
2491
+ maxWidth,
2492
+ maxHeight,
2493
+ initialCenter,
2494
+ showTopOperationArea,
2495
+ showBottomOperationArea,
2496
+ backgroundColor
2497
+ },
2498
+ timeout
2499
+ });
2500
+ const data = response.getDataOrDefault({});
2501
+ return data;
2502
+ }
2503
+ /**
2504
+ * 点击节点
2505
+ * @param node 要点击的节点
2506
+ * @returns 是否点击成功
2507
+ */
2508
+ static click(node) {
2509
+ const response = this.call(CallMethod.click, { node });
2510
+ return response.getDataOrDefault(false);
2511
+ }
2512
+ /**
2513
+ * 长按节点
2514
+ * @param node 要长按的节点
2515
+ * @returns 是否长按成功
2516
+ */
2517
+ static longClick(node) {
2518
+ const response = this.call(CallMethod.longClick, { node });
2519
+ return response.getDataOrDefault(false);
2520
+ }
2521
+ /**
2522
+ * 启动应用
2523
+ * @param packageName 应用包名
2524
+ * @returns 是否启动成功
2525
+ */
2526
+ static launchApp(packageName) {
2527
+ const response = this.call(CallMethod.launchApp, { args: { packageName } });
2528
+ return response.getDataOrDefault(false);
2529
+ }
2530
+ /**
2531
+ * 获取当前应用包名
2532
+ * @returns 包名
2533
+ */
2534
+ static getPackageName(options = {}) {
2535
+ const { scope } = options;
2536
+ const response = this.call(
2537
+ CallMethod.getPackageName,
2538
+ scope !== void 0 ? { args: { scope } } : {}
2539
+ );
2540
+ return response.getDataOrDefault("");
2541
+ }
2542
+ /**
2543
+ * 显示悬浮提示
2544
+ * @param text 提示文本
2545
+ * @param delay 显示时长(毫秒)
2546
+ * @returns 是否显示成功
2547
+ */
2548
+ static overlayToast(text, delay = 2e3) {
2549
+ const response = this.call(CallMethod.overlayToast, {
2550
+ args: { text, delay }
2551
+ });
2552
+ return response.getDataOrDefault(false);
2553
+ }
2554
+ /**
2555
+ * 通过ID查找节点
2556
+ * @param id 节点ID
2557
+ * @param filterClass 类名过滤
2558
+ * @param filterText 文本过滤
2559
+ * @param filterDes 描述过滤
2560
+ * @param node 父节点范围
2561
+ * @returns 节点数组
2562
+ */
2563
+ static findById(id, {
2564
+ filterClass,
2565
+ filterText,
2566
+ filterDes,
2567
+ node,
2568
+ scope
2569
+ } = {}) {
2570
+ const response = this.call(CallMethod.findById, {
2571
+ args: {
2572
+ id,
2573
+ filterClass,
2574
+ filterText,
2575
+ filterDes,
2576
+ ...scope !== void 0 ? { scope } : {}
2577
+ },
2578
+ node
2579
+ });
2580
+ const data = response.getDataOrDefault([]);
2581
+ if (!Array.isArray(data)) {
2582
+ throw new Error(
2583
+ `AssistsX.findById: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2584
+ );
2585
+ }
2586
+ return Node.fromJSONArray(data);
2587
+ }
2588
+ /**
2589
+ * 通过文本查找节点
2590
+ * @param text 要查找的文本
2591
+ * @param filterClass 类名过滤
2592
+ * @param filterViewId 视图ID过滤
2593
+ * @param filterDes 描述过滤
2594
+ * @param node 父节点范围
2595
+ * @returns 节点数组
2596
+ */
2597
+ static findByText(text, {
2598
+ filterClass,
2599
+ filterViewId,
2600
+ filterDes,
2601
+ node,
2602
+ scope
2603
+ } = {}) {
2604
+ const response = this.call(CallMethod.findByText, {
2605
+ args: {
2606
+ text,
2607
+ filterClass,
2608
+ filterViewId,
2609
+ filterDes,
2610
+ ...scope !== void 0 ? { scope } : {}
2611
+ },
2612
+ node
2613
+ });
2614
+ const data = response.getDataOrDefault([]);
2615
+ if (!Array.isArray(data)) {
2616
+ throw new Error(
2617
+ `AssistsX.findByText: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2618
+ );
2619
+ }
2620
+ return Node.fromJSONArray(data);
2621
+ }
2622
+ /**
2623
+ * 通过标签查找节点
2624
+ * @param className 类名
2625
+ * @param filterText 文本过滤
2626
+ * @param filterViewId 视图ID过滤
2627
+ * @param filterDes 描述过滤
2628
+ * @param node 父节点范围
2629
+ * @returns 节点数组
2630
+ */
2631
+ static findByTags(className, {
2632
+ filterText,
2633
+ filterViewId,
2634
+ filterDes,
2635
+ node,
2636
+ scope
2637
+ } = {}) {
2638
+ const response = this.call(CallMethod.findByTags, {
2639
+ args: {
2640
+ className,
2641
+ filterText,
2642
+ filterViewId,
2643
+ filterDes,
2644
+ ...scope !== void 0 ? { scope } : {}
2645
+ },
2646
+ node
2647
+ });
2648
+ const data = response.getDataOrDefault([]);
2649
+ if (!Array.isArray(data)) {
2650
+ throw new Error(
2651
+ `AssistsX.findByTags: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2652
+ );
2653
+ }
2654
+ return Node.fromJSONArray(data);
2655
+ }
2656
+ /**
2657
+ * 查找所有匹配文本的节点
2658
+ * @param text 要查找的文本
2659
+ * @param options.scope 节点查找范围(可选)
2660
+ */
2661
+ static findByTextAllMatch(text, { scope } = {}) {
2662
+ const response = this.call(CallMethod.findByTextAllMatch, {
2663
+ args: {
2664
+ text,
2665
+ ...scope !== void 0 ? { scope } : {}
2666
+ }
2667
+ });
2668
+ const data = response.getDataOrDefault([]);
2669
+ if (!Array.isArray(data)) {
2670
+ throw new Error(
2671
+ `AssistsX.findByTextAllMatch: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2672
+ );
2673
+ }
2674
+ return Node.fromJSONArray(data);
2675
+ }
2676
+ /**
2677
+ * 检查是否包含指定文本
2678
+ * @param text 要检查的文本
2679
+ * @returns 是否包含
2680
+ */
2681
+ static containsText(text) {
2682
+ const response = this.call(CallMethod.containsText, { args: { text } });
2683
+ return response.getDataOrDefault(false);
2684
+ }
2685
+ /**
2686
+ * 获取所有文本
2687
+ * @returns 文本数组
2688
+ */
2689
+ static getAllText() {
2690
+ const response = this.call(CallMethod.getAllText);
2691
+ const data = response.getDataOrDefault([]);
2692
+ if (!Array.isArray(data)) {
2693
+ throw new Error(
2694
+ `AssistsX.getAllText: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2695
+ );
2696
+ }
2697
+ return data;
2698
+ }
2699
+ /**
2700
+ * 查找第一个匹配标签的父节点
2701
+ * @param className 类名
2702
+ * @returns 父节点
2703
+ */
2704
+ static findFirstParentByTags(node, className) {
2705
+ const response = this.call(CallMethod.findFirstParentByTags, {
2706
+ args: { className },
2707
+ node
2708
+ });
2709
+ return Node.create(response.getDataOrDefault({}));
2710
+ }
2711
+ /**
2712
+ * 获取节点的所有子节点
2713
+ * @param node 父节点
2714
+ * @returns 子节点数组
2715
+ */
2716
+ static getNodes(node) {
2717
+ const response = this.call(CallMethod.getNodes, { node });
2718
+ const data = response.getDataOrDefault([]);
2719
+ if (!Array.isArray(data)) {
2720
+ throw new Error(
2721
+ `AssistsX.getNodes: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2722
+ );
2723
+ }
2724
+ return Node.fromJSONArray(data);
2725
+ }
2726
+ /**
2727
+ * 获取节点的直接子节点
2728
+ * @param node 父节点
2729
+ * @returns 子节点数组
2730
+ */
2731
+ static getChildren(node) {
2732
+ const response = this.call(CallMethod.getChildren, { node });
2733
+ const data = response.getDataOrDefault([]);
2734
+ if (!Array.isArray(data)) {
2735
+ throw new Error(
2736
+ `AssistsX.getChildren: Expected array, but got ${typeof data}. Value: ${JSON.stringify(data)}`
2737
+ );
2738
+ }
2739
+ return Node.fromJSONArray(data);
2740
+ }
2741
+ /**
2742
+ * 查找第一个可点击的父节点
2743
+ * @param node 起始节点
2744
+ * @returns 可点击的父节点
2745
+ */
2746
+ static findFirstParentClickable(node) {
2747
+ const response = this.call(CallMethod.findFirstParentClickable, { node });
2748
+ return Node.create(response.getDataOrDefault({}));
2749
+ }
2750
+ /**
2751
+ * 获取节点在屏幕中的边界
2752
+ * @param node 目标节点
2753
+ * @returns 边界对象
2754
+ */
2755
+ static getBoundsInScreen(node) {
2756
+ const response = this.call(CallMethod.getBoundsInScreen, { node });
2757
+ return Bounds.fromData(response.getDataOrDefault({}));
2758
+ }
2759
+ /**
2760
+ * 检查节点是否可见
2761
+ * @param node 目标节点
2762
+ * @param compareNode 比较节点
2763
+ * @param isFullyByCompareNode 是否完全可见
2764
+ * @returns 是否可见
2765
+ */
2766
+ static isVisible(node, {
2767
+ compareNode,
2768
+ isFullyByCompareNode
2769
+ } = {}) {
2770
+ const response = this.call(CallMethod.isVisible, {
2771
+ node,
2772
+ args: { compareNode, isFullyByCompareNode }
2773
+ });
2774
+ return response.getDataOrDefault(false);
2775
+ }
2776
+ /**
2777
+ * 执行点击手势
2778
+ * @param x 横坐标
2779
+ * @param y 纵坐标
2780
+ * @param duration 持续时间
2781
+ * @param timeout 超时时间(秒),默认30秒
2782
+ * @returns 是否成功
2783
+ */
2784
+ static async clickByGesture(x, y, duration, timeout) {
2785
+ const response = await this.asyncCall(CallMethod.clickByGesture, {
2786
+ args: { x, y, duration },
2787
+ timeout
2788
+ });
2789
+ return response.getDataOrDefault(false);
2790
+ }
2791
+ /**
2792
+ * 返回操作
2793
+ * @returns 是否成功
2794
+ */
2795
+ static back() {
2796
+ const response = this.call(CallMethod.back);
2797
+ return response.getDataOrDefault(false);
2798
+ }
2799
+ /**
2800
+ * 回到主页
2801
+ * @returns 是否成功
2802
+ */
2803
+ static home() {
2804
+ const response = this.call(CallMethod.home);
2805
+ return response.getDataOrDefault(false);
2806
+ }
2807
+ /**
2808
+ * 打开通知栏
2809
+ * @returns 是否成功
2810
+ */
2811
+ static notifications() {
2812
+ const response = this.call(CallMethod.notifications);
2813
+ return response.getDataOrDefault(false);
2814
+ }
2815
+ /**
2816
+ * 显示最近应用
2817
+ * @returns 是否成功
2818
+ */
2819
+ static recentApps() {
2820
+ const response = this.call(CallMethod.recentApps);
2821
+ return response.getDataOrDefault(false);
2822
+ }
2823
+ /**
2824
+ * 在节点中粘贴文本
2825
+ * @param node 目标节点
2826
+ * @param text 要粘贴的文本
2827
+ * @returns 是否成功
2828
+ */
2829
+ static paste(node, text) {
2830
+ const response = this.call(CallMethod.paste, { args: { text }, node });
2831
+ return response.getDataOrDefault(false);
2832
+ }
2833
+ static focus(node) {
2834
+ const response = this.call(CallMethod.focus, { node });
2835
+ return response.getDataOrDefault(false);
2836
+ }
2837
+ /**
2838
+ * 选择文本
2839
+ * @param node 目标节点
2840
+ * @param selectionStart 选择起始位置
2841
+ * @param selectionEnd 选择结束位置
2842
+ * @returns 是否成功
2843
+ */
2844
+ static selectionText(node, selectionStart, selectionEnd) {
2845
+ const response = this.call(CallMethod.selectionText, {
2846
+ args: { selectionStart, selectionEnd },
2847
+ node
2848
+ });
2849
+ return response.getDataOrDefault(false);
2850
+ }
2851
+ /**
2852
+ * 向前滚动
2853
+ * @param node 可滚动节点
2854
+ * @returns 是否成功
2855
+ */
2856
+ static scrollForward(node) {
2857
+ const response = this.call(CallMethod.scrollForward, { node });
2858
+ return response.getDataOrDefault(false);
2859
+ }
2860
+ /**
2861
+ * 向后滚动
2862
+ * @param node 可滚动节点
2863
+ * @returns 是否成功
2864
+ */
2865
+ static scrollBackward(node) {
2866
+ const response = this.call(CallMethod.scrollBackward, { node });
2867
+ return response.getDataOrDefault(false);
2868
+ }
2869
+ /**
2870
+ * 对节点执行点击手势
2871
+ * @param node 目标节点
2872
+ * @param offsetX X轴偏移
2873
+ * @param offsetY Y轴偏移
2874
+ * @param switchWindowIntervalDelay 窗口切换延迟
2875
+ * @param clickDuration 点击持续时间
2876
+ * @param timeout 超时时间(秒),默认30秒
2877
+ * @returns 是否成功
2878
+ */
2879
+ static async clickNodeByGesture(node, {
2880
+ offsetX,
2881
+ offsetY,
2882
+ switchWindowIntervalDelay,
2883
+ clickDuration,
2884
+ timeout
2885
+ } = {}) {
2886
+ const response = await this.asyncCall(CallMethod.clickNodeByGesture, {
2887
+ node,
2888
+ args: { offsetX, offsetY, switchWindowIntervalDelay, clickDuration },
2889
+ timeout
2890
+ });
2891
+ return response.getDataOrDefault(false);
2892
+ }
2893
+ /**
2894
+ * 对节点执行双击手势
2895
+ * @param node 目标节点
2896
+ * @param offsetX X轴偏移
2897
+ * @param offsetY Y轴偏移
2898
+ * @param switchWindowIntervalDelay 窗口切换延迟
2899
+ * @param clickDuration 点击持续时间
2900
+ * @param clickInterval 点击间隔
2901
+ * @param timeout 超时时间(秒),默认30秒
2902
+ * @returns 是否成功
2903
+ */
2904
+ static async doubleClickNodeByGesture(node, {
2905
+ offsetX,
2906
+ offsetY,
2907
+ switchWindowIntervalDelay,
2908
+ clickDuration,
2909
+ clickInterval,
2910
+ timeout
2911
+ } = {}) {
2912
+ const response = await this.asyncCall(CallMethod.doubleClickNodeByGesture, {
2913
+ node,
2914
+ args: {
2915
+ offsetX,
2916
+ offsetY,
2917
+ switchWindowIntervalDelay,
2918
+ clickDuration,
2919
+ clickInterval
2920
+ },
2921
+ timeout
2922
+ });
2923
+ return response.getDataOrDefault(false);
2924
+ }
2925
+ /**
2926
+ * 执行线型手势
2927
+ * @param startPoint
2928
+ * @param endPoint
2929
+ * @param param2
2930
+ * @param timeout 超时时间(秒),默认30秒
2931
+ * @returns
2932
+ */
2933
+ static async performLinearGesture(startPoint, endPoint, { duration, timeout } = {}) {
2934
+ const response = await this.asyncCall(CallMethod.performLinearGesture, {
2935
+ args: { startPoint, endPoint, duration },
2936
+ timeout
2937
+ });
2938
+ return response.getDataOrDefault(false);
2939
+ }
2940
+ static async longPressNodeByGestureAutoPaste(node, text, {
2941
+ matchedPackageName,
2942
+ matchedText,
2943
+ timeoutMillis,
2944
+ longPressDuration,
2945
+ timeout
2946
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
2947
+ const response = await this.asyncCall(
2948
+ CallMethod.longPressGestureAutoPaste,
2949
+ {
2950
+ node,
2951
+ args: {
2952
+ text,
2953
+ matchedPackageName,
2954
+ matchedText,
2955
+ timeoutMillis,
2956
+ longPressDuration
2957
+ },
2958
+ timeout
2959
+ }
2960
+ );
2961
+ return response.getDataOrDefault(false);
2962
+ }
2963
+ static async longPressGestureAutoPaste(point, text, {
2964
+ matchedPackageName,
2965
+ matchedText,
2966
+ timeoutMillis,
2967
+ longPressDuration,
2968
+ timeout
2969
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
2970
+ const response = await this.asyncCall(
2971
+ CallMethod.longPressGestureAutoPaste,
2972
+ {
2973
+ args: {
2974
+ point,
2975
+ text,
2976
+ matchedPackageName,
2977
+ matchedText,
2978
+ timeoutMillis,
2979
+ longPressDuration
2980
+ },
2981
+ timeout
2982
+ }
2983
+ );
2984
+ return response.getDataOrDefault(false);
2985
+ }
2986
+ static async getAppInfo(packageName, timeout) {
2987
+ const response = await this.asyncCall(CallMethod.getAppInfo, {
2988
+ args: { packageName },
2989
+ timeout
2990
+ });
2991
+ return AppInfo.fromJSON(response.getDataOrDefault({}));
2992
+ }
2993
+ static getUniqueDeviceId() {
2994
+ const response = this.call(CallMethod.getUniqueDeviceId);
2995
+ return response.getDataOrDefault("");
2996
+ }
2997
+ static getAndroidID() {
2998
+ const response = this.call(CallMethod.getAndroidID);
2999
+ return response.getDataOrDefault("");
3000
+ }
3001
+ static async getMacAddress(timeout) {
3002
+ const response = await this.asyncCall(CallMethod.getMacAddress, {
3003
+ timeout
3004
+ });
3005
+ return response.getDataOrDefault({});
3006
+ }
3007
+ static async getDeviceInfo(timeout) {
3008
+ const response = await this.asyncCall(CallMethod.getDeviceInfo, {
3009
+ timeout
3010
+ });
3011
+ return DeviceInfo.fromJSON(response.getDataOrDefault({}));
3012
+ }
3013
+ static async getNetworkType(timeout) {
3014
+ const response = await this.asyncCall(CallMethod.getNetworkType, {
3015
+ timeout
3016
+ });
3017
+ return response.getDataOrDefault({});
3018
+ }
3019
+ /**
3020
+ * 播放系统电话铃声
3021
+ * @param timeout 超时时间(秒),默认30秒
3022
+ * @returns 播放结果消息
3023
+ */
3024
+ static async audioPlayRingtone(timeout) {
3025
+ const response = await this.asyncCall(CallMethod.audioPlayRingtone, {
3026
+ timeout
3027
+ });
3028
+ return response.getDataOrDefault("");
3029
+ }
3030
+ /**
3031
+ * 停止播放系统电话铃声
3032
+ * @param timeout 超时时间(秒),默认30秒
3033
+ * @returns 停止结果消息
3034
+ */
3035
+ static async audioStopRingtone(timeout) {
3036
+ const response = await this.asyncCall(CallMethod.audioStopRingtone, {
3037
+ timeout
3038
+ });
3039
+ return response.getDataOrDefault("");
3040
+ }
3041
+ static async setAccessibilityEventFilters(value) {
3042
+ const response = this.call(CallMethod.setAccessibilityEventFilters, {
3043
+ args: { value }
3044
+ });
3045
+ return response.getDataOrDefault({});
3046
+ }
3047
+ static async addAccessibilityEventFilter(value) {
3048
+ const response = this.call(CallMethod.addAccessibilityEventFilter, {
3049
+ args: { value }
3050
+ });
3051
+ return response.getDataOrDefault({});
3052
+ }
3053
+ /**
3054
+ * 获取屏幕尺寸
3055
+ * @returns 屏幕尺寸对象(width, height)
3056
+ */
3057
+ static getScreenSize() {
3058
+ const response = this.call(CallMethod.getScreenSize);
3059
+ const data = response.getDataOrDefault({});
3060
+ return normalizeScreen(data);
3061
+ }
3062
+ /**
3063
+ * 获取应用窗口尺寸
3064
+ * @returns 应用窗口尺寸对象
3065
+ */
3066
+ static getAppScreenSize() {
3067
+ const response = this.call(CallMethod.getAppScreenSize);
3068
+ return response.getDataOrDefault({});
3069
+ }
3070
+ /**
3071
+ * 添加无障碍事件监听器
3072
+ * @param listener 监听器函数
3073
+ */
3074
+ static addAccessibilityEventListener(listener) {
3075
+ accessibilityEventListeners.push(listener);
3076
+ }
3077
+ /**
3078
+ * 判断是否包含无障碍事件监听器
3079
+ * @param listener 监听器函数
3080
+ * @returns 是否包含
3081
+ */
3082
+ static containsAccessibilityEventListener(listener) {
3083
+ return accessibilityEventListeners.indexOf(listener) > -1;
3084
+ }
3085
+ /**
3086
+ * 移除无障碍事件监听器
3087
+ * @param listener 要移除的监听器函数
3088
+ * @returns 是否移除成功
3089
+ */
3090
+ static removeAccessibilityEventListener(listener) {
3091
+ const index = accessibilityEventListeners.indexOf(listener);
3092
+ if (index > -1) {
3093
+ accessibilityEventListeners.splice(index, 1);
3094
+ return true;
3095
+ }
3096
+ return false;
3097
+ }
3098
+ /**
3099
+ * 移除所有无障碍事件监听器
3100
+ */
3101
+ static removeAllAccessibilityEventListeners() {
3102
+ accessibilityEventListeners.length = 0;
3103
+ }
3104
+ /**
3105
+ * 获取当前注册的无障碍事件监听器数量
3106
+ * @returns 监听器数量
3107
+ */
3108
+ static getAccessibilityEventListenerCount() {
3109
+ return accessibilityEventListeners.length;
3110
+ }
3111
+ };
3112
+ function normalizeScreen(data) {
3113
+ if (data == null) return null;
3114
+ const w = typeof data.width === "number" ? data.width : data.screenWidth;
3115
+ const h = typeof data.height === "number" ? data.height : data.screenHeight;
3116
+ if (typeof w !== "number" || typeof h !== "number") return null;
3117
+ return { width: Math.floor(w), height: Math.floor(h) };
3118
+ }
3119
+ var _a;
3120
+ if (typeof window !== "undefined") {
3121
+ try {
3122
+ if (window.assistsx && typeof window.assistsx.call === "function") {
3123
+ screen = (_a = AssistsX2.getScreenSize()) != null ? _a : { width: 0, height: 0 };
3124
+ }
3125
+ } catch (e) {
3126
+ console.log("Failed to initialize screen size:", e);
3127
+ }
3128
+ }
3129
+
3130
+ // src/step-state-store.ts
3131
+ var import_pinia = require("pinia");
3132
+ var useStepStore = (0, import_pinia.defineStore)("step", {
3133
+ state: () => ({
3134
+ status: "idle",
3135
+ stepId: void 0,
3136
+ tag: void 0,
3137
+ data: void 0,
3138
+ error: void 0
3139
+ }),
3140
+ actions: {
3141
+ // 开始执行步骤
3142
+ startStep(stepId, tag, data) {
3143
+ this.status = "running";
3144
+ this.stepId = stepId;
3145
+ this.tag = tag;
3146
+ this.data = data;
3147
+ this.error = void 0;
3148
+ },
3149
+ // 完成步骤
3150
+ completeStep() {
3151
+ this.status = "completed";
3152
+ },
3153
+ // 步骤出错
3154
+ setError(error) {
3155
+ this.status = "error";
3156
+ this.error = error;
3157
+ },
3158
+ // 重置状态
3159
+ reset() {
3160
+ this.status = "idle";
3161
+ this.stepId = void 0;
3162
+ this.tag = void 0;
3163
+ this.data = void 0;
3164
+ this.error = void 0;
3165
+ }
3166
+ }
3167
+ });
3168
+
3169
+ // src/pinia-ensure.ts
3170
+ var import_pinia2 = require("pinia");
3171
+ var fallbackPinia = null;
3172
+ function ensureAssistsXPinia() {
3173
+ if ((0, import_pinia2.getActivePinia)() !== void 0) return;
3174
+ if (fallbackPinia === null) {
3175
+ fallbackPinia = (0, import_pinia2.createPinia)();
3176
+ }
3177
+ (0, import_pinia2.setActivePinia)(fallbackPinia);
3178
+ }
3179
+
3180
+ // src/step-error.ts
3181
+ var StepError = class extends Error {
3182
+ constructor(message, data, impl, tag, originalError, currentStep) {
3183
+ super(message);
3184
+ this.name = "StepError";
3185
+ this.data = data;
3186
+ this.impl = impl;
3187
+ this.tag = tag;
3188
+ this.originalError = originalError;
3189
+ this.currentStep = currentStep;
3190
+ }
3191
+ };
3192
+ var StepStopError = class extends StepError {
3193
+ constructor(message, data) {
3194
+ super(message || "\u4E3B\u52A8\u4E2D\u65AD\u6B65\u9AA4", data);
3195
+ this.name = "StepStopError";
3196
+ }
3197
+ };
3198
+
3199
+ // src/step-async.ts
3200
+ var StepAsync = class {
3201
+ /**
3202
+ * 构造函数
3203
+ * @param step Step实例
3204
+ */
3205
+ constructor(step) {
3206
+ this.step = step;
3207
+ }
3208
+ /**
3209
+ * 对单个节点进行截图
3210
+ * @param node 目标节点
3211
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
3212
+ * @returns 截图路径
3213
+ */
3214
+ async takeScreenshotByNode(node, overlayHiddenScreenshotDelayMillis = 250) {
3215
+ Step.assert(this.step.stepId);
3216
+ const result = await AssistsXAsync.takeScreenshotNodes(
3217
+ [node],
3218
+ overlayHiddenScreenshotDelayMillis
3219
+ );
3220
+ Step.assert(this.step.stepId);
3221
+ return result[0];
3222
+ }
3223
+ /**
3224
+ * 对多个节点进行截图
3225
+ * @param nodes 目标节点数组
3226
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
3227
+ * @returns 截图路径数组
3228
+ */
3229
+ async takeScreenshotNodes(nodes, overlayHiddenScreenshotDelayMillis = 250) {
3230
+ Step.assert(this.step.stepId);
3231
+ const result = await AssistsXAsync.takeScreenshotNodes(
3232
+ nodes,
3233
+ overlayHiddenScreenshotDelayMillis
3234
+ );
3235
+ Step.assert(this.step.stepId);
3236
+ return result;
3237
+ }
3238
+ /**
3239
+ * 获取所有符合条件的节点
3240
+ * @param filterClass 类名过滤
3241
+ * @param filterViewId 视图ID过滤
3242
+ * @param filterDes 描述过滤
3243
+ * @param filterText 文本过滤
3244
+ * @returns 节点数组
3245
+ */
3246
+ async getAllNodes({
3247
+ filterClass,
3248
+ filterViewId,
3249
+ filterDes,
3250
+ filterText,
3251
+ scope
3252
+ } = {}) {
3253
+ Step.assert(this.step.stepId);
3254
+ const nodes = await AssistsXAsync.getAllNodes({
3255
+ filterClass,
3256
+ filterViewId,
3257
+ filterDes,
3258
+ filterText,
3259
+ scope
3260
+ });
3261
+ Step.assert(this.step.stepId);
3262
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3263
+ return nodes;
3264
+ }
3265
+ /**
3266
+ * 启动应用
3267
+ * @param packageName 应用包名
3268
+ * @returns 是否启动成功
3269
+ */
3270
+ async launchApp(packageName) {
3271
+ Step.assert(this.step.stepId);
3272
+ const result = await AssistsXAsync.launchApp(packageName);
3273
+ Step.assert(this.step.stepId);
3274
+ return result;
3275
+ }
3276
+ async getPackageName(timeoutOrOptions) {
3277
+ Step.assert(this.step.stepId);
3278
+ const result = typeof timeoutOrOptions === "number" ? await AssistsXAsync.getPackageName(timeoutOrOptions) : await AssistsXAsync.getPackageName(timeoutOrOptions != null ? timeoutOrOptions : {});
3279
+ Step.assert(this.step.stepId);
3280
+ return result;
3281
+ }
3282
+ /**
3283
+ * 通过ID查找节点
3284
+ * @param id 节点ID
3285
+ * @param filterClass 类名过滤
3286
+ * @param filterText 文本过滤
3287
+ * @param filterDes 描述过滤
3288
+ * @returns 节点数组
3289
+ */
3290
+ async findById(id, {
3291
+ filterClass,
3292
+ filterText,
3293
+ filterDes,
3294
+ scope
3295
+ } = {}) {
3296
+ Step.assert(this.step.stepId);
3297
+ const nodes = await AssistsXAsync.findById(id, {
3298
+ filterClass,
3299
+ filterText,
3300
+ filterDes,
3301
+ scope
3302
+ });
3303
+ Step.assert(this.step.stepId);
3304
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3305
+ return nodes;
3306
+ }
3307
+ /**
3308
+ * 通过文本查找节点
3309
+ * @param text 要查找的文本
3310
+ * @param filterClass 类名过滤
3311
+ * @param filterViewId 视图ID过滤
3312
+ * @param filterDes 描述过滤
3313
+ * @returns 节点数组
3314
+ */
3315
+ async findByText(text, {
3316
+ filterClass,
3317
+ filterViewId,
3318
+ filterDes,
3319
+ scope
3320
+ } = {}) {
3321
+ Step.assert(this.step.stepId);
3322
+ const nodes = await AssistsXAsync.findByText(text, {
3323
+ filterClass,
3324
+ filterViewId,
3325
+ filterDes,
3326
+ scope
3327
+ });
3328
+ Step.assert(this.step.stepId);
3329
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3330
+ return nodes;
3331
+ }
3332
+ /**
3333
+ * 通过标签查找节点
3334
+ * @param className 类名
3335
+ * @param filterText 文本过滤
3336
+ * @param filterViewId 视图ID过滤
3337
+ * @param filterDes 描述过滤
3338
+ * @returns 节点数组
3339
+ */
3340
+ async findByTags(className, {
3341
+ filterText,
3342
+ filterViewId,
3343
+ filterDes,
3344
+ scope
3345
+ } = {}) {
3346
+ Step.assert(this.step.stepId);
3347
+ const nodes = await AssistsXAsync.findByTags(className, {
3348
+ filterText,
3349
+ filterViewId,
3350
+ filterDes,
3351
+ scope
3352
+ });
3353
+ Step.assert(this.step.stepId);
3354
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3355
+ return nodes;
3356
+ }
3357
+ async findByTextAllMatch(text, timeoutOrOptions) {
3358
+ Step.assert(this.step.stepId);
3359
+ const nodes = typeof timeoutOrOptions === "number" ? await AssistsXAsync.findByTextAllMatch(text, timeoutOrOptions) : timeoutOrOptions !== void 0 ? await AssistsXAsync.findByTextAllMatch(text, timeoutOrOptions) : await AssistsXAsync.findByTextAllMatch(text);
3360
+ Step.assert(this.step.stepId);
3361
+ Step.assignIdsToNodes(nodes, this.step.stepId);
3362
+ return nodes;
3363
+ }
3364
+ /**
3365
+ * 检查是否包含指定文本
3366
+ * @param text 要检查的文本
3367
+ * @returns 是否包含
3368
+ */
3369
+ async containsText(text) {
3370
+ Step.assert(this.step.stepId);
3371
+ const result = await AssistsXAsync.containsText(text);
3372
+ Step.assert(this.step.stepId);
3373
+ return result;
3374
+ }
3375
+ /**
3376
+ * 获取所有文本
3377
+ * @returns 文本数组
3378
+ */
3379
+ async getAllText() {
3380
+ Step.assert(this.step.stepId);
3381
+ const texts = await AssistsXAsync.getAllText();
3382
+ Step.assert(this.step.stepId);
3383
+ return texts;
3384
+ }
3385
+ /**
3386
+ * 执行点击手势
3387
+ * @param x 横坐标
3388
+ * @param y 纵坐标
3389
+ * @param duration 持续时间(毫秒)
3390
+ * @returns 是否成功
3391
+ */
3392
+ async clickByGesture(x, y, duration) {
3393
+ Step.assert(this.step.stepId);
3394
+ const result = await AssistsXAsync.clickByGesture(x, y, duration);
3395
+ Step.assert(this.step.stepId);
3396
+ return result;
3397
+ }
3398
+ async longPressGestureAutoPaste(point, text, {
3399
+ matchedPackageName,
3400
+ matchedText,
3401
+ timeoutMillis,
3402
+ longPressDuration
3403
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
3404
+ Step.assert(this.step.stepId);
3405
+ const result = await AssistsXAsync.longPressGestureAutoPaste(point, text, {
3406
+ matchedPackageName,
3407
+ matchedText,
3408
+ timeoutMillis,
3409
+ longPressDuration
3410
+ });
3411
+ Step.assert(this.step.stepId);
3412
+ return result;
3413
+ }
3414
+ async getAppInfo(packageName) {
3415
+ Step.assert(this.step.stepId);
3416
+ const result = await AssistsXAsync.getAppInfo(packageName);
3417
+ Step.assert(this.step.stepId);
3418
+ return result;
3419
+ }
3420
+ async performLinearGesture(startPoint, endPoint, { duration } = {}) {
3421
+ Step.assert(this.step.stepId);
3422
+ const result = await AssistsXAsync.performLinearGesture(
3423
+ startPoint,
3424
+ endPoint,
3425
+ {
3426
+ duration
3427
+ }
3428
+ );
3429
+ Step.assert(this.step.stepId);
3430
+ return result;
3431
+ }
3432
+ /**
3433
+ * 返回操作
3434
+ * @returns 是否成功
3435
+ */
3436
+ async back() {
3437
+ Step.assert(this.step.stepId);
3438
+ const result = await AssistsXAsync.back();
3439
+ Step.assert(this.step.stepId);
3440
+ return result;
3441
+ }
3442
+ /**
3443
+ * 回到主页
3444
+ * @returns 是否成功
3445
+ */
3446
+ async home() {
3447
+ Step.assert(this.step.stepId);
3448
+ const result = await AssistsXAsync.home();
3449
+ Step.assert(this.step.stepId);
3450
+ return result;
3451
+ }
3452
+ /**
3453
+ * 打开通知栏
3454
+ * @returns 是否成功
3455
+ */
3456
+ async notifications() {
3457
+ Step.assert(this.step.stepId);
3458
+ const result = await AssistsXAsync.notifications();
3459
+ Step.assert(this.step.stepId);
3460
+ return result;
3461
+ }
3462
+ /**
3463
+ * 显示最近应用
3464
+ * @returns 是否成功
3465
+ */
3466
+ async recentApps() {
3467
+ Step.assert(this.step.stepId);
3468
+ const result = await AssistsXAsync.recentApps();
3469
+ Step.assert(this.step.stepId);
3470
+ return result;
3471
+ }
3472
+ /**
3473
+ * 获取屏幕尺寸
3474
+ * @returns 屏幕尺寸对象
3475
+ */
3476
+ async getScreenSize() {
3477
+ Step.assert(this.step.stepId);
3478
+ const data = await AssistsXAsync.getScreenSize();
3479
+ Step.assert(this.step.stepId);
3480
+ return data;
3481
+ }
3482
+ /**
3483
+ * 获取应用窗口尺寸
3484
+ * @returns 应用窗口尺寸对象
3485
+ */
3486
+ async getAppScreenSize() {
3487
+ Step.assert(this.step.stepId);
3488
+ const data = await AssistsXAsync.getAppScreenSize();
3489
+ Step.assert(this.step.stepId);
3490
+ return data;
3491
+ }
3492
+ };
3493
+
3494
+ // src/step.ts
3495
+ var _Step = class _Step {
3496
+ /**
3497
+ * 构造函数
3498
+ * @param stepId 步骤ID
3499
+ * @param impl 步骤实现函数
3500
+ * @param tag 步骤标签
3501
+ * @param data 步骤数据
3502
+ * @param delayMs 步骤延迟时间(毫秒)
3503
+ */
3504
+ constructor({
3505
+ stepId,
3506
+ impl,
3507
+ tag,
3508
+ data,
3509
+ delayMs = _Step.delayMsDefault,
3510
+ repeatCountMax = _Step.repeatCountMaxDefault,
3511
+ exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault,
3512
+ isEnd = false
3513
+ }) {
3514
+ /**
3515
+ * 步骤ID
3516
+ */
3517
+ this.stepId = "";
3518
+ /**
3519
+ * 步骤重复执行次数
3520
+ */
3521
+ this.repeatCount = 0;
3522
+ /**
3523
+ * 步骤重复执行最大次数,默认15次
3524
+ */
3525
+ this.repeatCountMax = _Step.repeatCountMaxDefault;
3526
+ /**
3527
+ * 异常重试次数
3528
+ */
3529
+ this.exceptionRetryCount = 0;
3530
+ /**
3531
+ * 异常重试最大次数,默认3次
3532
+ */
3533
+ this.exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault;
3534
+ this.isEnd = false;
3535
+ /**
3536
+ * 步骤延迟时间(毫秒)
3537
+ */
3538
+ this.delayMs = _Step.delayMsDefault;
3539
+ this.tag = tag;
3540
+ this.stepId = stepId;
3541
+ this.data = _Step.resolveStepData(data);
3542
+ this.impl = impl;
3543
+ this.delayMs = delayMs;
3544
+ this.repeatCountMax = repeatCountMax;
3545
+ this.exceptionRetryCountMax = exceptionRetryCountMax;
3546
+ this.isEnd = isEnd;
3547
+ }
3548
+ /**
3549
+ * 判断步骤数据是否有效(非空且为普通对象)
3550
+ */
3551
+ static isValidStepData(data) {
3552
+ return data !== null && data !== void 0 && typeof data === "object" && !Array.isArray(data);
3553
+ }
3554
+ /**
3555
+ * 解析步骤数据:优先使用传入值,否则使用当前值,均无效时返回空对象
3556
+ */
3557
+ static resolveStepData(provided, fallback) {
3558
+ if (provided !== void 0 && _Step.isValidStepData(provided)) {
3559
+ return provided;
3560
+ }
3561
+ if (fallback !== void 0 && _Step.isValidStepData(fallback)) {
3562
+ return fallback;
3563
+ }
3564
+ return {};
3565
+ }
3566
+ /**
3567
+ * 运行步骤实现
3568
+ * @param impl 步骤实现函数
3569
+ * @param tag 步骤标签
3570
+ * @param data 步骤数据
3571
+ * @param delayMs 步骤延迟时间(毫秒)
3572
+ */
3573
+ static async run(impl, {
3574
+ stepId,
3575
+ tag,
3576
+ data,
3577
+ delayMs = _Step.delayMsDefault,
3578
+ exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault
3579
+ } = {}) {
3580
+ var _a2, _b, _c, _d, _e, _f;
3581
+ this.exception = void 0;
3582
+ ensureAssistsXPinia();
3583
+ const stepStore = useStepStore();
3584
+ const resolvedData = _Step.resolveStepData(data);
3585
+ let implnName = impl.name;
3586
+ let currentStep;
3587
+ let nextStep;
3588
+ try {
3589
+ if (stepId) {
3590
+ this._stepId = stepId;
3591
+ if (_Step.showLog) {
3592
+ console.log(`\u4F7F\u7528\u4F20\u5165\u6B65\u9AA4ID: ${this._stepId}`);
3593
+ }
3594
+ } else {
3595
+ this._stepId = generateUUID();
3596
+ if (_Step.showLog) {
3597
+ console.log(`\u751F\u6210\u6B65\u9AA4ID: ${this._stepId}`);
3598
+ }
3599
+ }
3600
+ stepStore.startStep(this._stepId, tag, resolvedData);
3601
+ currentStep = new _Step({
3602
+ stepId: this._stepId,
3603
+ impl,
3604
+ tag,
3605
+ data: resolvedData,
3606
+ delayMs,
3607
+ exceptionRetryCountMax
3608
+ });
3609
+ while (true) {
3610
+ let interceptedStep = void 0;
3611
+ let stepForRetry = currentStep;
3612
+ try {
3613
+ if (currentStep.delayMs) {
3614
+ if (_Step.showLog) {
3615
+ console.log(`\u5EF6\u8FDF${currentStep.delayMs}\u6BEB\u79D2`);
3616
+ }
3617
+ await currentStep.delay(currentStep.delayMs);
3618
+ _Step.assert(currentStep.stepId);
3619
+ }
3620
+ implnName = (_b = (_a2 = currentStep.impl) == null ? void 0 : _a2.name) != null ? _b : "undefined";
3621
+ if (_Step.showLog) {
3622
+ console.log(
3623
+ `\u6267\u884C\u6B65\u9AA4${implnName}\uFF0C\u91CD\u590D\u6B21\u6570${currentStep.repeatCount}`
3624
+ );
3625
+ }
3626
+ for (const interceptor of this._interceptors) {
3627
+ try {
3628
+ const result = await interceptor(currentStep);
3629
+ if (result) {
3630
+ interceptedStep = result;
3631
+ if (_Step.showLog) {
3632
+ console.log(`\u6B65\u9AA4${implnName}\u88AB\u62E6\u622A\u5668\u62E6\u622A\uFF0C\u6267\u884C\u62E6\u622A\u540E\u7684\u6B65\u9AA4`);
3633
+ }
3634
+ break;
3635
+ }
3636
+ } catch (e) {
3637
+ if (_Step.showLog) {
3638
+ console.error(`\u62E6\u622A\u5668\u6267\u884C\u51FA\u9519`, e);
3639
+ }
3640
+ }
3641
+ }
3642
+ stepForRetry = currentStep;
3643
+ if (interceptedStep !== void 0) {
3644
+ const stepToExecute = interceptedStep;
3645
+ stepForRetry = stepToExecute;
3646
+ if (stepToExecute.delayMs) {
3647
+ if (_Step.showLog) {
3648
+ console.log(`\u62E6\u622A\u6B65\u9AA4\u5EF6\u8FDF${stepToExecute.delayMs}\u6BEB\u79D2`);
3649
+ }
3650
+ await stepToExecute.delay(stepToExecute.delayMs);
3651
+ _Step.assert(stepToExecute.stepId);
3652
+ }
3653
+ const interceptedImplName = (_c = stepToExecute.impl) == null ? void 0 : _c.name;
3654
+ if (_Step.showLog) {
3655
+ console.log(
3656
+ `\u6267\u884C\u62E6\u622A\u6B65\u9AA4${interceptedImplName}\uFF0C\u91CD\u590D\u6B21\u6570${stepToExecute.repeatCount}`
3657
+ );
3658
+ }
3659
+ nextStep = await ((_d = stepToExecute.impl) == null ? void 0 : _d.call(stepToExecute, stepToExecute));
3660
+ } else {
3661
+ nextStep = await ((_e = currentStep.impl) == null ? void 0 : _e.call(currentStep, currentStep));
3662
+ }
3663
+ if (currentStep.repeatCountMax > _Step.repeatCountInfinite && currentStep.repeatCount >= currentStep.repeatCountMax) {
3664
+ if (_Step.showLog) {
3665
+ console.log(
3666
+ `\u91CD\u590D\u6B21\u6570${currentStep.repeatCount}\u8D85\u8FC7\u6700\u5927\u6B21\u6570${currentStep.repeatCountMax}\uFF0C\u505C\u6B62\u6267\u884C`
3667
+ );
3668
+ }
3669
+ throw new StepError("\u6B65\u9AA4\u91CD\u590D\u6B21\u6570\u8FBE\u5230\u6700\u5927\u6B21\u6570", { stepId: currentStep.stepId, repeatCount: currentStep.repeatCount, repeatCountMax: currentStep.repeatCountMax });
3670
+ }
3671
+ _Step.assert(currentStep.stepId);
3672
+ stepForRetry.exceptionRetryCount = 0;
3673
+ if (nextStep) {
3674
+ currentStep = nextStep;
3675
+ if (currentStep.isEnd) {
3676
+ if (_Step.showLog) {
3677
+ console.log(`\u6B65\u9AA4${implnName}\u7ED3\u675F`);
3678
+ }
3679
+ break;
3680
+ }
3681
+ } else {
3682
+ break;
3683
+ }
3684
+ } catch (e) {
3685
+ if ((e == null ? void 0 : e.message) === "\u6B65\u9AA4\u91CD\u590D\u6B21\u6570\u8FBE\u5230\u6700\u5927\u6B21\u6570") {
3686
+ throw e;
3687
+ }
3688
+ stepForRetry.exceptionRetryCount++;
3689
+ if (stepForRetry.exceptionRetryCount < stepForRetry.exceptionRetryCountMax) {
3690
+ if (_Step.showLog) {
3691
+ console.warn(
3692
+ `\u6B65\u9AA4${implnName}\u6267\u884C\u5F02\u5E38\uFF0C\u91CD\u8BD5\u7B2C${stepForRetry.exceptionRetryCount}\u6B21\uFF0C\u6700\u5927\u91CD\u8BD5\u6B21\u6570${stepForRetry.exceptionRetryCountMax}`,
3693
+ e
3694
+ );
3695
+ }
3696
+ continue;
3697
+ } else {
3698
+ if (_Step.showLog) {
3699
+ console.error(
3700
+ `\u6B65\u9AA4${implnName}\u6267\u884C\u5F02\u5E38\uFF0C\u5DF2\u8FBE\u5230\u6700\u5927\u91CD\u8BD5\u6B21\u6570${stepForRetry.exceptionRetryCountMax}\uFF0C\u505C\u6B62\u91CD\u8BD5`,
3701
+ e
3702
+ );
3703
+ }
3704
+ throw e;
3705
+ }
3706
+ }
3707
+ }
3708
+ stepStore.completeStep();
3709
+ } catch (e) {
3710
+ console.error(`\u6B65\u9AA4${implnName}\u6267\u884C\u51FA\u9519`, e);
3711
+ const errorMsg = JSON.stringify({
3712
+ impl: implnName,
3713
+ tag,
3714
+ data: resolvedData,
3715
+ error: (_f = e == null ? void 0 : e.message) != null ? _f : String(e)
3716
+ });
3717
+ stepStore.setError(errorMsg);
3718
+ throw e;
3719
+ }
3720
+ return currentStep;
3721
+ }
3722
+ /**
3723
+ * 获取当前步骤ID
3724
+ */
3725
+ static get stepId() {
3726
+ return this._stepId;
3727
+ }
3728
+ /**
3729
+ * 验证步骤ID是否匹配,如果不匹配则表示停止
3730
+ * @param stepId 要验证的步骤ID
3731
+ */
3732
+ static assert(stepId) {
3733
+ if (_Step.exception) {
3734
+ throw _Step.exception;
3735
+ }
3736
+ if (stepId && _Step.stepId != stepId) {
3737
+ throw new StepError("StepId mismatch", { stepId, currentStepId: _Step.stepId });
3738
+ }
3739
+ }
3740
+ /**
3741
+ * 为节点数组分配步骤ID
3742
+ * @param nodes 节点数组
3743
+ * @param stepId 步骤ID
3744
+ */
3745
+ static assignIdsToNodes(nodes, stepId) {
3746
+ if (stepId) {
3747
+ nodes.forEach((node) => {
3748
+ node.stepId = stepId;
3749
+ });
3750
+ }
3751
+ }
3752
+ /**
3753
+ * 停止当前步骤执行
3754
+ * @param exception 可选的异常对象,如果传入则使用该异常,否则使用默认的StepStopError
3755
+ */
3756
+ static stop(exception) {
3757
+ this._stepId = "STEP_STOP";
3758
+ if (exception) {
3759
+ this.exception = exception;
3760
+ } else {
3761
+ this.exception = new StepStopError("\u4E3B\u52A8\u4E2D\u65AD\u6B65\u9AA4", { stepId: this._stepId });
3762
+ }
3763
+ }
3764
+ /**
3765
+ * 添加步骤拦截器
3766
+ * @param interceptor 拦截器函数
3767
+ */
3768
+ static addInterceptor(interceptor) {
3769
+ this._interceptors.push(interceptor);
3770
+ }
3771
+ /**
3772
+ * 移除步骤拦截器
3773
+ * @param interceptor 要移除的拦截器函数
3774
+ * @returns 是否成功删除
3775
+ */
3776
+ static removeInterceptor(interceptor) {
3777
+ const index = this._interceptors.indexOf(interceptor);
3778
+ if (index > -1) {
3779
+ this._interceptors.splice(index, 1);
3780
+ return true;
3781
+ }
3782
+ return false;
3783
+ }
3784
+ /**
3785
+ * 按索引移除步骤拦截器
3786
+ * @param index 要移除的拦截器索引
3787
+ * @returns 是否成功删除
3788
+ */
3789
+ static removeInterceptorByIndex(index) {
3790
+ if (index >= 0 && index < this._interceptors.length) {
3791
+ this._interceptors.splice(index, 1);
3792
+ return true;
3793
+ }
3794
+ return false;
3795
+ }
3796
+ /**
3797
+ * 移除所有匹配的步骤拦截器
3798
+ * @param interceptor 要移除的拦截器函数
3799
+ * @returns 删除的拦截器数量
3800
+ */
3801
+ static removeAllInterceptors(interceptor) {
3802
+ let removedCount = 0;
3803
+ for (let i = this._interceptors.length - 1; i >= 0; i--) {
3804
+ if (this._interceptors[i] === interceptor) {
3805
+ this._interceptors.splice(i, 1);
3806
+ removedCount++;
3807
+ }
3808
+ }
3809
+ return removedCount;
3810
+ }
3811
+ /**
3812
+ * 按条件移除步骤拦截器
3813
+ * @param predicate 判断是否删除的条件函数
3814
+ * @returns 删除的拦截器数量
3815
+ */
3816
+ static removeInterceptorByPredicate(predicate) {
3817
+ let removedCount = 0;
3818
+ for (let i = this._interceptors.length - 1; i >= 0; i--) {
3819
+ if (predicate(this._interceptors[i], i)) {
3820
+ this._interceptors.splice(i, 1);
3821
+ removedCount++;
3822
+ }
3823
+ }
3824
+ return removedCount;
3825
+ }
3826
+ /**
3827
+ * 清空所有拦截器
3828
+ */
3829
+ static clearInterceptors() {
3830
+ this._interceptors = [];
3831
+ }
3832
+ /**
3833
+ * 获取所有拦截器
3834
+ * @returns 拦截器数组
3835
+ */
3836
+ static getInterceptors() {
3837
+ return [...this._interceptors];
3838
+ }
3839
+ get async() {
3840
+ return new StepAsync(this);
3841
+ }
3842
+ /**
3843
+ * 创建下一个步骤
3844
+ * @param impl 下一步骤实现函数
3845
+ * @param tag 步骤标签
3846
+ * @param data 步骤数据
3847
+ * @param delayMs 步骤延迟时间(毫秒)
3848
+ * @returns 新的步骤实例
3849
+ */
3850
+ next(impl, {
3851
+ tag,
3852
+ data,
3853
+ delayMs = _Step.delayMsDefault,
3854
+ repeatCountMax = _Step.repeatCountMaxDefault,
3855
+ exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault
3856
+ } = {}) {
3857
+ _Step.assert(this.stepId);
3858
+ return new _Step({
3859
+ stepId: this.stepId,
3860
+ impl,
3861
+ tag,
3862
+ data: _Step.resolveStepData(data, this.data),
3863
+ delayMs,
3864
+ repeatCountMax,
3865
+ exceptionRetryCountMax
3866
+ });
3867
+ }
3868
+ end({
3869
+ tag,
3870
+ data,
3871
+ delayMs = _Step.delayMsDefault,
3872
+ repeatCountMax = _Step.repeatCountMaxDefault,
3873
+ exceptionRetryCountMax = _Step.exceptionRetryCountMaxDefault
3874
+ } = {}) {
3875
+ _Step.assert(this.stepId);
3876
+ return new _Step({
3877
+ stepId: this.stepId,
3878
+ impl: void 0,
3879
+ tag,
3880
+ data: _Step.resolveStepData(data, this.data),
3881
+ delayMs,
3882
+ repeatCountMax,
3883
+ exceptionRetryCountMax,
3884
+ isEnd: true
3885
+ });
3886
+ }
3887
+ /**
3888
+ * 重复当前步骤
3889
+ * @param stepId 步骤ID
3890
+ * @param tag 步骤标签
3891
+ * @param data 步骤数据
3892
+ * @param delayMs 步骤延迟时间(毫秒)
3893
+ * @returns 当前步骤实例
3894
+ */
3895
+ repeat({
3896
+ stepId = this.stepId,
3897
+ tag = this.tag,
3898
+ data,
3899
+ delayMs = this.delayMs,
3900
+ repeatCountMax = this.repeatCountMax,
3901
+ exceptionRetryCountMax = this.exceptionRetryCountMax
3902
+ } = {}) {
3903
+ _Step.assert(this.stepId);
3904
+ this.repeatCount++;
3905
+ this.stepId = stepId;
3906
+ this.tag = tag;
3907
+ this.data = _Step.resolveStepData(data, this.data);
3908
+ this.delayMs = delayMs;
3909
+ this.repeatCountMax = repeatCountMax;
3910
+ this.exceptionRetryCountMax = exceptionRetryCountMax;
3911
+ this.exceptionRetryCount = 0;
3912
+ return this;
3913
+ }
3914
+ /**
3915
+ * 延迟执行
3916
+ * @param ms 延迟时间(毫秒)
3917
+ * @returns Promise
3918
+ */
3919
+ async delay(ms) {
3920
+ while (true) {
3921
+ ms -= 100;
3922
+ if (ms <= 0) {
3923
+ break;
3924
+ }
3925
+ await new Promise((resolve) => setTimeout(resolve, 100));
3926
+ _Step.assert(this.stepId);
3927
+ }
3928
+ }
3929
+ /**
3930
+ * 等待异步方法执行完成
3931
+ * @param method 异步方法
3932
+ * @returns Promise<T>
3933
+ */
3934
+ async await(method) {
3935
+ _Step.assert(this.stepId);
3936
+ const result = await method();
3937
+ _Step.assert(this.stepId);
3938
+ return result;
3939
+ }
3940
+ /**
3941
+ * 对单个节点进行截图
3942
+ * @param node 目标节点
3943
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
3944
+ * @returns 截图路径
3945
+ */
3946
+ async takeScreenshotByNode(node, overlayHiddenScreenshotDelayMillis = 250) {
3947
+ _Step.assert(this.stepId);
3948
+ const result = await AssistsX2.takeScreenshotNodes(
3949
+ [node],
3950
+ overlayHiddenScreenshotDelayMillis
3951
+ );
3952
+ _Step.assert(this.stepId);
3953
+ return result[0];
3954
+ }
3955
+ /**
3956
+ * 对多个节点进行截图
3957
+ * @param nodes 目标节点数组
3958
+ * @param overlayHiddenScreenshotDelayMillis 截图延迟时间(毫秒)
3959
+ * @returns 截图路径数组
3960
+ */
3961
+ async takeScreenshotNodes(nodes, overlayHiddenScreenshotDelayMillis = 250) {
3962
+ _Step.assert(this.stepId);
3963
+ const result = await AssistsX2.takeScreenshotNodes(
3964
+ nodes,
3965
+ overlayHiddenScreenshotDelayMillis
3966
+ );
3967
+ _Step.assert(this.stepId);
3968
+ return result;
3969
+ }
3970
+ /**
3971
+ * 获取所有符合条件的节点
3972
+ * @param filterClass 类名过滤
3973
+ * @param filterViewId 视图ID过滤
3974
+ * @param filterDes 描述过滤
3975
+ * @param filterText 文本过滤
3976
+ * @returns 节点数组
3977
+ */
3978
+ getAllNodes({
3979
+ filterClass,
3980
+ filterViewId,
3981
+ filterDes,
3982
+ filterText,
3983
+ scope
3984
+ } = {}) {
3985
+ _Step.assert(this.stepId);
3986
+ const nodes = AssistsX2.getAllNodes({
3987
+ filterClass,
3988
+ filterViewId,
3989
+ filterDes,
3990
+ filterText,
3991
+ scope
3992
+ });
3993
+ _Step.assert(this.stepId);
3994
+ _Step.assignIdsToNodes(nodes, this.stepId);
3995
+ return nodes;
3996
+ }
3997
+ /**
3998
+ * 启动应用
3999
+ * @param packageName 应用包名
4000
+ * @returns 是否启动成功
4001
+ */
4002
+ launchApp(packageName) {
4003
+ _Step.assert(this.stepId);
4004
+ const result = AssistsX2.launchApp(packageName);
4005
+ _Step.assert(this.stepId);
4006
+ return result;
4007
+ }
4008
+ /**
4009
+ * 获取当前应用包名
4010
+ * @param options.scope 节点查找范围(可选)
4011
+ */
4012
+ getPackageName(options = {}) {
4013
+ _Step.assert(this.stepId);
4014
+ const result = AssistsX2.getPackageName(options);
4015
+ _Step.assert(this.stepId);
4016
+ return result;
4017
+ }
4018
+ /**
4019
+ * 通过ID查找节点
4020
+ * @param id 节点ID
4021
+ * @param filterClass 类名过滤
4022
+ * @param filterText 文本过滤
4023
+ * @param filterDes 描述过滤
4024
+ * @returns 节点数组
4025
+ */
4026
+ findById(id, {
4027
+ filterClass,
4028
+ filterText,
4029
+ filterDes,
4030
+ scope
4031
+ } = {}) {
4032
+ _Step.assert(this.stepId);
4033
+ const nodes = AssistsX2.findById(id, {
4034
+ filterClass,
4035
+ filterText,
4036
+ filterDes,
4037
+ scope
4038
+ });
4039
+ _Step.assert(this.stepId);
4040
+ _Step.assignIdsToNodes(nodes, this.stepId);
4041
+ return nodes;
4042
+ }
4043
+ /**
4044
+ * 通过文本查找节点
4045
+ * @param text 要查找的文本
4046
+ * @param filterClass 类名过滤
4047
+ * @param filterViewId 视图ID过滤
4048
+ * @param filterDes 描述过滤
4049
+ * @returns 节点数组
4050
+ */
4051
+ findByText(text, {
4052
+ filterClass,
4053
+ filterViewId,
4054
+ filterDes,
4055
+ scope
4056
+ } = {}) {
4057
+ _Step.assert(this.stepId);
4058
+ const nodes = AssistsX2.findByText(text, {
4059
+ filterClass,
4060
+ filterViewId,
4061
+ filterDes,
4062
+ scope
4063
+ });
4064
+ _Step.assert(this.stepId);
4065
+ _Step.assignIdsToNodes(nodes, this.stepId);
4066
+ return nodes;
4067
+ }
4068
+ /**
4069
+ * 通过标签查找节点
4070
+ * @param className 类名
4071
+ * @param filterText 文本过滤
4072
+ * @param filterViewId 视图ID过滤
4073
+ * @param filterDes 描述过滤
4074
+ * @returns 节点数组
4075
+ */
4076
+ findByTags(className, {
4077
+ filterText,
4078
+ filterViewId,
4079
+ filterDes,
4080
+ scope
4081
+ } = {}) {
4082
+ _Step.assert(this.stepId);
4083
+ const nodes = AssistsX2.findByTags(className, {
4084
+ filterText,
4085
+ filterViewId,
4086
+ filterDes,
4087
+ scope
4088
+ });
4089
+ _Step.assert(this.stepId);
4090
+ _Step.assignIdsToNodes(nodes, this.stepId);
4091
+ return nodes;
4092
+ }
4093
+ /**
4094
+ * 查找所有匹配文本的节点
4095
+ * @param text 要查找的文本
4096
+ * @param options.scope 节点查找范围(可选)
4097
+ */
4098
+ findByTextAllMatch(text, { scope } = {}) {
4099
+ _Step.assert(this.stepId);
4100
+ const nodes = AssistsX2.findByTextAllMatch(text, { scope });
4101
+ _Step.assert(this.stepId);
4102
+ _Step.assignIdsToNodes(nodes, this.stepId);
4103
+ return nodes;
4104
+ }
4105
+ /**
4106
+ * 检查是否包含指定文本
4107
+ * @param text 要检查的文本
4108
+ * @returns 是否包含
4109
+ */
4110
+ containsText(text) {
4111
+ _Step.assert(this.stepId);
4112
+ const result = AssistsX2.containsText(text);
4113
+ _Step.assert(this.stepId);
4114
+ return result;
4115
+ }
4116
+ /**
4117
+ * 获取所有文本
4118
+ * @returns 文本数组
4119
+ */
4120
+ getAllText() {
4121
+ _Step.assert(this.stepId);
4122
+ const texts = AssistsX2.getAllText();
4123
+ _Step.assert(this.stepId);
4124
+ return texts;
4125
+ }
4126
+ /**
4127
+ * 执行点击手势
4128
+ * @param x 横坐标
4129
+ * @param y 纵坐标
4130
+ * @param duration 持续时间(毫秒)
4131
+ * @returns 是否成功
4132
+ */
4133
+ async clickByGesture(x, y, duration) {
4134
+ _Step.assert(this.stepId);
4135
+ const result = await AssistsX2.clickByGesture(x, y, duration);
4136
+ _Step.assert(this.stepId);
4137
+ return result;
4138
+ }
4139
+ async longPressGestureAutoPaste(point, text, {
4140
+ matchedPackageName,
4141
+ matchedText,
4142
+ timeoutMillis,
4143
+ longPressDuration
4144
+ } = { matchedText: "\u7C98\u8D34", timeoutMillis: 1500, longPressDuration: 600 }) {
4145
+ _Step.assert(this.stepId);
4146
+ const result = await AssistsX2.longPressGestureAutoPaste(point, text, {
4147
+ matchedPackageName,
4148
+ matchedText,
4149
+ timeoutMillis,
4150
+ longPressDuration
4151
+ });
4152
+ _Step.assert(this.stepId);
4153
+ return result;
4154
+ }
4155
+ async getAppInfo(packageName) {
4156
+ _Step.assert(this.stepId);
4157
+ const result = await AssistsX2.getAppInfo(packageName);
4158
+ _Step.assert(this.stepId);
4159
+ return result;
4160
+ }
4161
+ async performLinearGesture(startPoint, endPoint, { duration } = {}) {
4162
+ _Step.assert(this.stepId);
4163
+ const result = await AssistsX2.performLinearGesture(startPoint, endPoint, {
4164
+ duration
4165
+ });
4166
+ _Step.assert(this.stepId);
4167
+ return result;
4168
+ }
4169
+ /**
4170
+ * 返回操作
4171
+ * @returns 是否成功
4172
+ */
4173
+ back() {
4174
+ _Step.assert(this.stepId);
4175
+ const result = AssistsX2.back();
4176
+ _Step.assert(this.stepId);
4177
+ return result;
4178
+ }
4179
+ /**
4180
+ * 回到主页
4181
+ * @returns 是否成功
4182
+ */
4183
+ home() {
4184
+ _Step.assert(this.stepId);
4185
+ const result = AssistsX2.home();
4186
+ _Step.assert(this.stepId);
4187
+ return result;
4188
+ }
4189
+ /**
4190
+ * 打开通知栏
4191
+ * @returns 是否成功
4192
+ */
4193
+ notifications() {
4194
+ _Step.assert(this.stepId);
4195
+ const result = AssistsX2.notifications();
4196
+ _Step.assert(this.stepId);
4197
+ return result;
4198
+ }
4199
+ /**
4200
+ * 显示最近应用
4201
+ * @returns 是否成功
4202
+ */
4203
+ recentApps() {
4204
+ _Step.assert(this.stepId);
4205
+ const result = AssistsX2.recentApps();
4206
+ _Step.assert(this.stepId);
4207
+ return result;
4208
+ }
4209
+ /**
4210
+ * 获取屏幕尺寸
4211
+ * @returns 屏幕尺寸对象
4212
+ */
4213
+ getScreenSize() {
4214
+ _Step.assert(this.stepId);
4215
+ const data = AssistsX2.getScreenSize();
4216
+ _Step.assert(this.stepId);
4217
+ return data;
4218
+ }
4219
+ /**
4220
+ * 获取应用窗口尺寸
4221
+ * @returns 应用窗口尺寸对象
4222
+ */
4223
+ getAppScreenSize() {
4224
+ _Step.assert(this.stepId);
4225
+ const data = AssistsX2.getAppScreenSize();
4226
+ _Step.assert(this.stepId);
4227
+ return data;
4228
+ }
4229
+ };
4230
+ _Step.delayMsDefault = 1e3;
4231
+ _Step.repeatCountInfinite = -1;
4232
+ _Step.repeatCountMaxDefault = 15;
4233
+ _Step.showLog = false;
4234
+ _Step.exceptionRetryCountMaxDefault = 3;
4235
+ /**
4236
+ * 当前执行步骤的ID
4237
+ */
4238
+ _Step._stepId = void 0;
4239
+ /**
4240
+ * 步骤拦截器列表
4241
+ */
4242
+ _Step._interceptors = [];
4243
+ /**
4244
+ * 步骤异常变量,默认为空
4245
+ */
4246
+ _Step.exception = void 0;
4247
+ var Step = _Step;
4248
+
4249
+ // src/step-flow/runner.ts
4250
+ function ensureFlowMeta(step, config) {
4251
+ const data = step.data;
4252
+ if (!data.__flow) {
4253
+ data.__flow = { id: config.id, state: config.initial };
4254
+ }
4255
+ }
4256
+ function setFlowState(step, state, config) {
4257
+ const data = step.data;
4258
+ if (!data.__flow) {
4259
+ data.__flow = { id: config.id, state };
4260
+ } else {
4261
+ data.__flow.state = state;
4262
+ }
4263
+ }
4264
+ function resolveOutcome(config, currentState, outcome) {
4265
+ if (outcome.type === "end") {
4266
+ return void 0;
4267
+ }
4268
+ if (outcome.type === "repeat") {
4269
+ return null;
4270
+ }
4271
+ if (outcome.type === "legacy") {
4272
+ return "legacy";
4273
+ }
4274
+ const stateDef = config.states[currentState];
4275
+ if (!stateDef) {
4276
+ throw new StepError(`StepFlow: unknown state "${currentState}"`, {
4277
+ flowId: config.id,
4278
+ state: currentState
4279
+ });
4280
+ }
4281
+ const nextState = stateDef.on[outcome.name];
4282
+ if (!nextState) {
4283
+ throw new StepError(
4284
+ `StepFlow: no transition for event "${outcome.name}" in state "${currentState}"`,
4285
+ { flowId: config.id, state: currentState, event: outcome.name }
4286
+ );
4287
+ }
4288
+ return nextState;
4289
+ }
4290
+ function createDispatcher(config) {
4291
+ const dispatcher = async (step) => {
4292
+ ensureFlowMeta(step, config);
4293
+ const data = step.data;
4294
+ const currentState = data.__flow.state;
4295
+ const stateDef = config.states[currentState];
4296
+ if (!stateDef) {
4297
+ throw new StepError(`StepFlow: unknown state "${currentState}"`, {
4298
+ flowId: config.id,
4299
+ state: currentState
4300
+ });
4301
+ }
4302
+ const outcome = await stateDef.run(step);
4303
+ const resolved = resolveOutcome(config, currentState, outcome);
4304
+ if (resolved === void 0) {
4305
+ return void 0;
4306
+ }
4307
+ if (resolved === null) {
4308
+ return step.repeat();
4309
+ }
4310
+ if (resolved === "legacy") {
4311
+ if (outcome.type !== "legacy") {
4312
+ throw new StepError("StepFlow: internal legacy outcome mismatch");
4313
+ }
4314
+ return step.next(outcome.impl);
4315
+ }
4316
+ setFlowState(step, resolved, config);
4317
+ return step.next(dispatcher);
4318
+ };
4319
+ return dispatcher;
4320
+ }
4321
+ function createFlowDispatcher(config) {
4322
+ return createDispatcher(config);
4323
+ }
4324
+ function buildFlowInitialData(config) {
4325
+ var _a2;
4326
+ return {
4327
+ payload: (_a2 = config.data) != null ? _a2 : {},
4328
+ __flow: {
4329
+ id: config.id,
4330
+ state: config.initial
4331
+ }
4332
+ };
4333
+ }
4334
+ var StepFlow = class {
4335
+ /**
4336
+ * 按状态机配置运行流程,内部复用 Step.run 与现有步骤循环。
4337
+ */
4338
+ static async run(config, options) {
4339
+ var _a2;
4340
+ if (!config.states[config.initial]) {
4341
+ throw new StepError(
4342
+ `StepFlow: initial state "${config.initial}" is not defined`,
4343
+ { flowId: config.id }
4344
+ );
4345
+ }
4346
+ const dispatcher = createDispatcher(config);
4347
+ return Step.run(dispatcher, {
4348
+ ...options,
4349
+ tag: (_a2 = options == null ? void 0 : options.tag) != null ? _a2 : config.id,
4350
+ data: buildFlowInitialData(config)
4351
+ });
4352
+ }
4353
+ };
4354
+ // Annotate the CommonJS export names for ESM import in node:
4355
+ 0 && (module.exports = {
4356
+ StepFlow,
4357
+ assignFlowPayload,
4358
+ buildFlowInitialData,
4359
+ createFinishHandoff,
4360
+ createFlowDispatcher,
4361
+ createLaunchState,
4362
+ flowEnd,
4363
+ flowEvent,
4364
+ flowRepeat,
4365
+ getFlowPayload
4366
+ });
4367
+ //# sourceMappingURL=index.cjs.map