@midscene/android 0.13.2-beta-20250403020006.0 → 0.14.0

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.
@@ -1,21 +1,21 @@
1
- import { AbstractPage } from '@midscene/web';
2
- export { PageAgent as AndroidAgent } from '@midscene/web';
3
1
  import { Size, Point } from '@midscene/core';
4
2
  import { ElementInfo } from '@midscene/shared/extractor';
5
- import { ADB } from 'appium-adb';
3
+ import { AndroidDevicePage } from '@midscene/web';
4
+ import { ADB, Device } from 'appium-adb';
5
+ import { PageAgent, PageAgentOpt } from '@midscene/web/agent';
6
6
 
7
- declare class AndroidDevice implements AbstractPage {
7
+ declare class AndroidDevice implements AndroidDevicePage {
8
8
  private deviceId;
9
9
  private screenSize;
10
10
  private yadbPushed;
11
11
  private deviceRatio;
12
- private adbInitPromise;
12
+ private adb;
13
+ private connectingAdb;
13
14
  pageType: string;
14
- constructor({ deviceId }: {
15
- deviceId: string;
16
- });
17
- private initAdb;
15
+ constructor(deviceId: string);
16
+ connect(): Promise<ADB>;
18
17
  getAdb(): Promise<ADB>;
18
+ launch(uri: string): Promise<AndroidDevice>;
19
19
  private execYadb;
20
20
  getElementsInfo(): Promise<ElementInfo[]>;
21
21
  getElementsNodeTree(): Promise<any>;
@@ -79,4 +79,11 @@ declare class AndroidDevice implements AbstractPage {
79
79
  destroy(): Promise<void>;
80
80
  }
81
81
 
82
- export { AndroidDevice };
82
+ declare class AndroidAgent extends PageAgent<AndroidDevice> {
83
+ launch(uri: string): Promise<void>;
84
+ }
85
+ declare function agentFromAdbDevice(deviceId?: string, opts?: PageAgentOpt): Promise<AndroidAgent>;
86
+
87
+ declare function getConnectedDevices(): Promise<Device[]>;
88
+
89
+ export { AndroidAgent, AndroidDevice, agentFromAdbDevice, getConnectedDevices };
package/dist/es/index.js CHANGED
@@ -1,35 +1,79 @@
1
- // src/index.ts
2
- import { PageAgent } from "@midscene/web";
3
-
4
1
  // src/page/index.ts
2
+ import assert from "assert";
5
3
  import fs from "fs";
6
4
  import path from "path";
7
5
  import { getTmpFile } from "@midscene/core/utils";
8
6
  import { resizeImg } from "@midscene/shared/img";
9
7
  import { getDebug } from "@midscene/shared/logger";
10
8
  import { ADB } from "appium-adb";
11
- var debugPage = getDebug("android:adb");
12
9
  var androidScreenshotPath = "/data/local/tmp/midscene_screenshot.png";
10
+ var debugPage = getDebug("android");
13
11
  var AndroidDevice = class {
14
- constructor({ deviceId }) {
12
+ constructor(deviceId) {
15
13
  this.screenSize = null;
16
14
  this.yadbPushed = false;
17
15
  this.deviceRatio = 1;
16
+ this.adb = null;
17
+ this.connectingAdb = null;
18
18
  this.pageType = "android";
19
+ assert(deviceId, "deviceId is required for AndroidDevice");
19
20
  this.deviceId = deviceId;
20
- this.adbInitPromise = this.initAdb();
21
21
  }
22
- async initAdb() {
23
- debugPage(`Initializing ADB with device ID: ${this.deviceId}`);
24
- const adb = await ADB.createADB({
25
- udid: this.deviceId,
26
- adbExecTimeout: 6e4
27
- });
28
- debugPage("ADB initialized successfully");
29
- return adb;
22
+ async connect() {
23
+ return this.getAdb();
30
24
  }
31
25
  async getAdb() {
32
- return this.adbInitPromise;
26
+ if (this.adb) {
27
+ return this.adb;
28
+ }
29
+ if (this.connectingAdb) {
30
+ return this.connectingAdb;
31
+ }
32
+ this.connectingAdb = (async () => {
33
+ let error = null;
34
+ debugPage(`Initializing ADB with device ID: ${this.deviceId}`);
35
+ try {
36
+ this.adb = await ADB.createADB({
37
+ udid: this.deviceId,
38
+ adbExecTimeout: 6e4
39
+ });
40
+ debugPage("ADB initialized successfully");
41
+ return this.adb;
42
+ } catch (e) {
43
+ debugPage(`Failed to initialize ADB: ${e}`);
44
+ error = new Error(`Unable to connect to device ${this.deviceId}: ${e}`);
45
+ } finally {
46
+ this.connectingAdb = null;
47
+ }
48
+ if (error) {
49
+ throw error;
50
+ }
51
+ throw new Error("ADB initialization failed unexpectedly");
52
+ })();
53
+ return this.connectingAdb;
54
+ }
55
+ async launch(uri) {
56
+ const adb = await this.getAdb();
57
+ try {
58
+ if (uri.startsWith("http://") || uri.startsWith("https://") || uri.includes("://")) {
59
+ await adb.startUri(uri);
60
+ } else if (uri.includes("/")) {
61
+ const [appPackage, appActivity] = uri.split("/");
62
+ await adb.startApp({
63
+ pkg: appPackage,
64
+ activity: appActivity
65
+ });
66
+ } else {
67
+ await adb.startApp({
68
+ pkg: uri
69
+ });
70
+ }
71
+ debugPage(`Successfully launched: ${uri}`);
72
+ } catch (error) {
73
+ debugPage(`Error launching ${uri}: ${error}`);
74
+ throw new Error(`Failed to launch ${uri}: ${error}`, { cause: error });
75
+ }
76
+ return this;
33
77
  }
34
78
  async execYadb(keyboardContent) {
35
79
  await this.ensureYadb();
@@ -158,9 +202,11 @@ var AndroidDevice = class {
158
202
  }
159
203
  await this.ensureYadb();
160
204
  const adb = await this.getAdb();
205
+ await this.mouse.click(element.center[0], element.center[1]);
161
206
  await adb.shell(
162
207
  'app_process -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "~CLEAR~"'
163
208
  );
209
+ await this.mouse.click(element.center[0], element.center[1]);
164
210
  }
165
211
  async forceScreenshot(path2) {
166
212
  await this.ensureYadb();
@@ -363,7 +409,45 @@ var AndroidDevice = class {
363
409
  }
364
410
  }
365
411
  };
412
+
413
+ // src/agent/index.ts
414
+ import { PageAgent } from "@midscene/web/agent";
415
+
416
+ // src/utils/index.ts
417
+ import { ADB as ADB2 } from "appium-adb";
418
+ async function getConnectedDevices() {
419
+ try {
420
+ const adb = await ADB2.createADB({
421
+ adbExecTimeout: 6e4
422
+ });
423
+ const devices = await adb.getConnectedDevices();
424
+ debugPage(`Found ${devices.length} connected devices: `, devices);
425
+ return devices;
426
+ } catch (error) {
427
+ console.error("Failed to get device list:", error);
428
+ throw new Error("Unable to get connected Android device list");
429
+ }
430
+ }
431
+
432
+ // src/agent/index.ts
433
+ var AndroidAgent = class extends PageAgent {
434
+ async launch(uri) {
435
+ const device = this.page;
436
+ await device.launch(uri);
437
+ }
438
+ };
439
+ async function agentFromAdbDevice(deviceId, opts) {
440
+ if (!deviceId) {
441
+ const devices = await getConnectedDevices();
442
+ deviceId = devices[0].udid;
443
+ }
444
+ const page = new AndroidDevice(deviceId);
445
+ await page.connect();
446
+ return new AndroidAgent(page, opts);
447
+ }
366
448
  export {
367
- PageAgent as AndroidAgent,
368
- AndroidDevice
449
+ AndroidAgent,
450
+ AndroidDevice,
451
+ agentFromAdbDevice,
452
+ getConnectedDevices
369
453
  };
@@ -1,21 +1,21 @@
1
- import { AbstractPage } from '@midscene/web';
2
- export { PageAgent as AndroidAgent } from '@midscene/web';
3
1
  import { Size, Point } from '@midscene/core';
4
2
  import { ElementInfo } from '@midscene/shared/extractor';
5
- import { ADB } from 'appium-adb';
3
+ import { AndroidDevicePage } from '@midscene/web';
4
+ import { ADB, Device } from 'appium-adb';
5
+ import { PageAgent, PageAgentOpt } from '@midscene/web/agent';
6
6
 
7
- declare class AndroidDevice implements AbstractPage {
7
+ declare class AndroidDevice implements AndroidDevicePage {
8
8
  private deviceId;
9
9
  private screenSize;
10
10
  private yadbPushed;
11
11
  private deviceRatio;
12
- private adbInitPromise;
12
+ private adb;
13
+ private connectingAdb;
13
14
  pageType: string;
14
- constructor({ deviceId }: {
15
- deviceId: string;
16
- });
17
- private initAdb;
15
+ constructor(deviceId: string);
16
+ connect(): Promise<ADB>;
18
17
  getAdb(): Promise<ADB>;
18
+ launch(uri: string): Promise<AndroidDevice>;
19
19
  private execYadb;
20
20
  getElementsInfo(): Promise<ElementInfo[]>;
21
21
  getElementsNodeTree(): Promise<any>;
@@ -79,4 +79,11 @@ declare class AndroidDevice implements AbstractPage {
79
79
  destroy(): Promise<void>;
80
80
  }
81
81
 
82
- export { AndroidDevice };
82
+ declare class AndroidAgent extends PageAgent<AndroidDevice> {
83
+ launch(uri: string): Promise<void>;
84
+ }
85
+ declare function agentFromAdbDevice(deviceId?: string, opts?: PageAgentOpt): Promise<AndroidAgent>;
86
+
87
+ declare function getConnectedDevices(): Promise<Device[]>;
88
+
89
+ export { AndroidAgent, AndroidDevice, agentFromAdbDevice, getConnectedDevices };
package/dist/lib/index.js CHANGED
@@ -30,41 +30,89 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/index.ts
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
- AndroidAgent: () => import_web.PageAgent,
34
- AndroidDevice: () => AndroidDevice
33
+ AndroidAgent: () => AndroidAgent,
34
+ AndroidDevice: () => AndroidDevice,
35
+ agentFromAdbDevice: () => agentFromAdbDevice,
36
+ getConnectedDevices: () => getConnectedDevices
35
37
  });
36
38
  module.exports = __toCommonJS(src_exports);
37
- var import_web = require("@midscene/web");
38
39
 
39
40
  // src/page/index.ts
41
+ var import_node_assert = __toESM(require("assert"));
40
42
  var import_node_fs = __toESM(require("fs"));
41
43
  var import_node_path = __toESM(require("path"));
42
44
  var import_utils = require("@midscene/core/utils");
43
45
  var import_img = require("@midscene/shared/img");
44
46
  var import_logger = require("@midscene/shared/logger");
45
47
  var import_appium_adb = require("appium-adb");
46
- var debugPage = (0, import_logger.getDebug)("android:adb");
47
48
  var androidScreenshotPath = "/data/local/tmp/midscene_screenshot.png";
49
+ var debugPage = (0, import_logger.getDebug)("android");
48
50
  var AndroidDevice = class {
49
- constructor({ deviceId }) {
51
+ constructor(deviceId) {
50
52
  this.screenSize = null;
51
53
  this.yadbPushed = false;
52
54
  this.deviceRatio = 1;
55
+ this.adb = null;
56
+ this.connectingAdb = null;
53
57
  this.pageType = "android";
58
+ (0, import_node_assert.default)(deviceId, "deviceId is required for AndroidDevice");
54
59
  this.deviceId = deviceId;
55
- this.adbInitPromise = this.initAdb();
56
60
  }
57
- async initAdb() {
58
- debugPage(`Initializing ADB with device ID: ${this.deviceId}`);
59
- const adb = await import_appium_adb.ADB.createADB({
60
- udid: this.deviceId,
61
- adbExecTimeout: 6e4
62
- });
63
- debugPage("ADB initialized successfully");
64
- return adb;
61
+ async connect() {
62
+ return this.getAdb();
65
63
  }
66
64
  async getAdb() {
67
- return this.adbInitPromise;
65
+ if (this.adb) {
66
+ return this.adb;
67
+ }
68
+ if (this.connectingAdb) {
69
+ return this.connectingAdb;
70
+ }
71
+ this.connectingAdb = (async () => {
72
+ let error = null;
73
+ debugPage(`Initializing ADB with device ID: ${this.deviceId}`);
74
+ try {
75
+ this.adb = await import_appium_adb.ADB.createADB({
76
+ udid: this.deviceId,
77
+ adbExecTimeout: 6e4
78
+ });
79
+ debugPage("ADB initialized successfully");
80
+ return this.adb;
81
+ } catch (e) {
82
+ debugPage(`Failed to initialize ADB: ${e}`);
83
+ error = new Error(`Unable to connect to device ${this.deviceId}: ${e}`);
84
+ } finally {
85
+ this.connectingAdb = null;
86
+ }
87
+ if (error) {
88
+ throw error;
89
+ }
90
+ throw new Error("ADB initialization failed unexpectedly");
91
+ })();
92
+ return this.connectingAdb;
93
+ }
94
+ async launch(uri) {
95
+ const adb = await this.getAdb();
96
+ try {
97
+ if (uri.startsWith("http://") || uri.startsWith("https://") || uri.includes("://")) {
98
+ await adb.startUri(uri);
99
+ } else if (uri.includes("/")) {
100
+ const [appPackage, appActivity] = uri.split("/");
101
+ await adb.startApp({
102
+ pkg: appPackage,
103
+ activity: appActivity
104
+ });
105
+ } else {
106
+ await adb.startApp({
107
+ pkg: uri
108
+ });
109
+ }
110
+ debugPage(`Successfully launched: ${uri}`);
111
+ } catch (error) {
112
+ debugPage(`Error launching ${uri}: ${error}`);
113
+ throw new Error(`Failed to launch ${uri}: ${error}`, { cause: error });
114
+ }
115
+ return this;
68
116
  }
69
117
  async execYadb(keyboardContent) {
70
118
  await this.ensureYadb();
@@ -193,9 +241,11 @@ var AndroidDevice = class {
193
241
  }
194
242
  await this.ensureYadb();
195
243
  const adb = await this.getAdb();
244
+ await this.mouse.click(element.center[0], element.center[1]);
196
245
  await adb.shell(
197
246
  'app_process -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "~CLEAR~"'
198
247
  );
248
+ await this.mouse.click(element.center[0], element.center[1]);
199
249
  }
200
250
  async forceScreenshot(path2) {
201
251
  await this.ensureYadb();
@@ -398,8 +448,46 @@ var AndroidDevice = class {
398
448
  }
399
449
  }
400
450
  };
451
+
452
+ // src/agent/index.ts
453
+ var import_agent = require("@midscene/web/agent");
454
+
455
+ // src/utils/index.ts
456
+ var import_appium_adb2 = require("appium-adb");
457
+ async function getConnectedDevices() {
458
+ try {
459
+ const adb = await import_appium_adb2.ADB.createADB({
460
+ adbExecTimeout: 6e4
461
+ });
462
+ const devices = await adb.getConnectedDevices();
463
+ debugPage(`Found ${devices.length} connected devices: `, devices);
464
+ return devices;
465
+ } catch (error) {
466
+ console.error("Failed to get device list:", error);
467
+ throw new Error("Unable to get connected Android device list");
468
+ }
469
+ }
470
+
471
+ // src/agent/index.ts
472
+ var AndroidAgent = class extends import_agent.PageAgent {
473
+ async launch(uri) {
474
+ const device = this.page;
475
+ await device.launch(uri);
476
+ }
477
+ };
478
+ async function agentFromAdbDevice(deviceId, opts) {
479
+ if (!deviceId) {
480
+ const devices = await getConnectedDevices();
481
+ deviceId = devices[0].udid;
482
+ }
483
+ const page = new AndroidDevice(deviceId);
484
+ await page.connect();
485
+ return new AndroidAgent(page, opts);
486
+ }
401
487
  // Annotate the CommonJS export names for ESM import in node:
402
488
  0 && (module.exports = {
403
489
  AndroidAgent,
404
- AndroidDevice
490
+ AndroidDevice,
491
+ agentFromAdbDevice,
492
+ getConnectedDevices
405
493
  });
@@ -1,21 +1,21 @@
1
- import { AbstractPage } from '@midscene/web';
2
- export { PageAgent as AndroidAgent } from '@midscene/web';
3
1
  import { Size, Point } from '@midscene/core';
4
2
  import { ElementInfo } from '@midscene/shared/extractor';
5
- import { ADB } from 'appium-adb';
3
+ import { AndroidDevicePage } from '@midscene/web';
4
+ import { ADB, Device } from 'appium-adb';
5
+ import { PageAgent, PageAgentOpt } from '@midscene/web/agent';
6
6
 
7
- declare class AndroidDevice implements AbstractPage {
7
+ declare class AndroidDevice implements AndroidDevicePage {
8
8
  private deviceId;
9
9
  private screenSize;
10
10
  private yadbPushed;
11
11
  private deviceRatio;
12
- private adbInitPromise;
12
+ private adb;
13
+ private connectingAdb;
13
14
  pageType: string;
14
- constructor({ deviceId }: {
15
- deviceId: string;
16
- });
17
- private initAdb;
15
+ constructor(deviceId: string);
16
+ connect(): Promise<ADB>;
18
17
  getAdb(): Promise<ADB>;
18
+ launch(uri: string): Promise<AndroidDevice>;
19
19
  private execYadb;
20
20
  getElementsInfo(): Promise<ElementInfo[]>;
21
21
  getElementsNodeTree(): Promise<any>;
@@ -79,4 +79,11 @@ declare class AndroidDevice implements AbstractPage {
79
79
  destroy(): Promise<void>;
80
80
  }
81
81
 
82
- export { AndroidDevice };
82
+ declare class AndroidAgent extends PageAgent<AndroidDevice> {
83
+ launch(uri: string): Promise<void>;
84
+ }
85
+ declare function agentFromAdbDevice(deviceId?: string, opts?: PageAgentOpt): Promise<AndroidAgent>;
86
+
87
+ declare function getConnectedDevices(): Promise<Device[]>;
88
+
89
+ export { AndroidAgent, AndroidDevice, agentFromAdbDevice, getConnectedDevices };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/android",
3
- "version": "0.13.2-beta-20250403020006.0",
3
+ "version": "0.14.0",
4
4
  "description": "Android automation library for Midscene",
5
5
  "main": "./dist/lib/index.js",
6
6
  "types": "./dist/types/index.d.ts",
@@ -17,9 +17,9 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "appium-adb": "12.12.1",
20
- "@midscene/web": "0.13.2-beta-20250403020006.0",
21
- "@midscene/core": "0.13.2-beta-20250403020006.0",
22
- "@midscene/shared": "0.13.2-beta-20250403020006.0"
20
+ "@midscene/web": "0.14.0",
21
+ "@midscene/core": "0.14.0",
22
+ "@midscene/shared": "0.14.0"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@modern-js/module-tools": "2.60.6",