@testdroid-ai/cli 0.1.2

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.
Files changed (229) hide show
  1. package/dist/adb/adb-path-resolver.d.ts +6 -0
  2. package/dist/adb/adb-path-resolver.d.ts.map +1 -0
  3. package/dist/adb/adb-path-resolver.js +93 -0
  4. package/dist/adb/adb-path-resolver.js.map +1 -0
  5. package/dist/adb/adb-shell.d.ts +29 -0
  6. package/dist/adb/adb-shell.d.ts.map +1 -0
  7. package/dist/adb/adb-shell.js +128 -0
  8. package/dist/adb/adb-shell.js.map +1 -0
  9. package/dist/adb/detector.d.ts +12 -0
  10. package/dist/adb/detector.d.ts.map +1 -0
  11. package/dist/adb/detector.js +44 -0
  12. package/dist/adb/detector.js.map +1 -0
  13. package/dist/adb/device-tracker.d.ts +23 -0
  14. package/dist/adb/device-tracker.d.ts.map +1 -0
  15. package/dist/adb/device-tracker.js +134 -0
  16. package/dist/adb/device-tracker.js.map +1 -0
  17. package/dist/adb/emulator-detector.d.ts +11 -0
  18. package/dist/adb/emulator-detector.d.ts.map +1 -0
  19. package/dist/adb/emulator-detector.js +54 -0
  20. package/dist/adb/emulator-detector.js.map +1 -0
  21. package/dist/appium/health-check.d.ts +6 -0
  22. package/dist/appium/health-check.d.ts.map +1 -0
  23. package/dist/appium/health-check.js +61 -0
  24. package/dist/appium/health-check.js.map +1 -0
  25. package/dist/appium/session-manager.d.ts +15 -0
  26. package/dist/appium/session-manager.d.ts.map +1 -0
  27. package/dist/appium/session-manager.js +82 -0
  28. package/dist/appium/session-manager.js.map +1 -0
  29. package/dist/auth/credential-store.d.ts +31 -0
  30. package/dist/auth/credential-store.d.ts.map +1 -0
  31. package/dist/auth/credential-store.js +154 -0
  32. package/dist/auth/credential-store.js.map +1 -0
  33. package/dist/auth/pairing-auth.d.ts +26 -0
  34. package/dist/auth/pairing-auth.d.ts.map +1 -0
  35. package/dist/auth/pairing-auth.js +177 -0
  36. package/dist/auth/pairing-auth.js.map +1 -0
  37. package/dist/auth/token-manager.d.ts +20 -0
  38. package/dist/auth/token-manager.d.ts.map +1 -0
  39. package/dist/auth/token-manager.js +101 -0
  40. package/dist/auth/token-manager.js.map +1 -0
  41. package/dist/commands/connect.d.ts +9 -0
  42. package/dist/commands/connect.d.ts.map +1 -0
  43. package/dist/commands/connect.js +270 -0
  44. package/dist/commands/connect.js.map +1 -0
  45. package/dist/commands/devices.d.ts +2 -0
  46. package/dist/commands/devices.d.ts.map +1 -0
  47. package/dist/commands/devices.js +52 -0
  48. package/dist/commands/devices.js.map +1 -0
  49. package/dist/commands/doctor.d.ts +2 -0
  50. package/dist/commands/doctor.d.ts.map +1 -0
  51. package/dist/commands/doctor.js +214 -0
  52. package/dist/commands/doctor.js.map +1 -0
  53. package/dist/commands/mirror.d.ts +2 -0
  54. package/dist/commands/mirror.d.ts.map +1 -0
  55. package/dist/commands/mirror.js +77 -0
  56. package/dist/commands/mirror.js.map +1 -0
  57. package/dist/commands/prompt.d.ts +12 -0
  58. package/dist/commands/prompt.d.ts.map +1 -0
  59. package/dist/commands/prompt.js +174 -0
  60. package/dist/commands/prompt.js.map +1 -0
  61. package/dist/commands/record.d.ts +7 -0
  62. package/dist/commands/record.d.ts.map +1 -0
  63. package/dist/commands/record.js +129 -0
  64. package/dist/commands/record.js.map +1 -0
  65. package/dist/commands/run.d.ts +16 -0
  66. package/dist/commands/run.d.ts.map +1 -0
  67. package/dist/commands/run.js +271 -0
  68. package/dist/commands/run.js.map +1 -0
  69. package/dist/commands/setup.d.ts +6 -0
  70. package/dist/commands/setup.d.ts.map +1 -0
  71. package/dist/commands/setup.js +50 -0
  72. package/dist/commands/setup.js.map +1 -0
  73. package/dist/commands/status.d.ts +2 -0
  74. package/dist/commands/status.d.ts.map +1 -0
  75. package/dist/commands/status.js +32 -0
  76. package/dist/commands/status.js.map +1 -0
  77. package/dist/healing/ai-adapter.d.ts +44 -0
  78. package/dist/healing/ai-adapter.d.ts.map +1 -0
  79. package/dist/healing/ai-adapter.js +87 -0
  80. package/dist/healing/ai-adapter.js.map +1 -0
  81. package/dist/healing/healer.d.ts +109 -0
  82. package/dist/healing/healer.d.ts.map +1 -0
  83. package/dist/healing/healer.js +475 -0
  84. package/dist/healing/healer.js.map +1 -0
  85. package/dist/healing/similarity.d.ts +63 -0
  86. package/dist/healing/similarity.d.ts.map +1 -0
  87. package/dist/healing/similarity.js +172 -0
  88. package/dist/healing/similarity.js.map +1 -0
  89. package/dist/index.d.ts +3 -0
  90. package/dist/index.d.ts.map +1 -0
  91. package/dist/index.js +107 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/recording/capture-strategies/capture-strategy.interface.d.ts +6 -0
  94. package/dist/recording/capture-strategies/capture-strategy.interface.d.ts.map +1 -0
  95. package/dist/recording/capture-strategies/capture-strategy.interface.js +3 -0
  96. package/dist/recording/capture-strategies/capture-strategy.interface.js.map +1 -0
  97. package/dist/recording/capture-strategies/getevent.strategy.d.ts +27 -0
  98. package/dist/recording/capture-strategies/getevent.strategy.d.ts.map +1 -0
  99. package/dist/recording/capture-strategies/getevent.strategy.js +163 -0
  100. package/dist/recording/capture-strategies/getevent.strategy.js.map +1 -0
  101. package/dist/recording/capture-strategies/key-capture.strategy.d.ts +16 -0
  102. package/dist/recording/capture-strategies/key-capture.strategy.d.ts.map +1 -0
  103. package/dist/recording/capture-strategies/key-capture.strategy.js +67 -0
  104. package/dist/recording/capture-strategies/key-capture.strategy.js.map +1 -0
  105. package/dist/recording/capture-strategies/logcat-capture.strategy.d.ts +32 -0
  106. package/dist/recording/capture-strategies/logcat-capture.strategy.d.ts.map +1 -0
  107. package/dist/recording/capture-strategies/logcat-capture.strategy.js +176 -0
  108. package/dist/recording/capture-strategies/logcat-capture.strategy.js.map +1 -0
  109. package/dist/recording/confidence-scorer.d.ts +13 -0
  110. package/dist/recording/confidence-scorer.d.ts.map +1 -0
  111. package/dist/recording/confidence-scorer.js +34 -0
  112. package/dist/recording/confidence-scorer.js.map +1 -0
  113. package/dist/recording/event-capture.d.ts +40 -0
  114. package/dist/recording/event-capture.d.ts.map +1 -0
  115. package/dist/recording/event-capture.js +168 -0
  116. package/dist/recording/event-capture.js.map +1 -0
  117. package/dist/recording/recorder.d.ts +32 -0
  118. package/dist/recording/recorder.d.ts.map +1 -0
  119. package/dist/recording/recorder.js +107 -0
  120. package/dist/recording/recorder.js.map +1 -0
  121. package/dist/runner/adb-executor.d.ts +116 -0
  122. package/dist/runner/adb-executor.d.ts.map +1 -0
  123. package/dist/runner/adb-executor.js +323 -0
  124. package/dist/runner/adb-executor.js.map +1 -0
  125. package/dist/runner/appium-executor.d.ts +35 -0
  126. package/dist/runner/appium-executor.d.ts.map +1 -0
  127. package/dist/runner/appium-executor.js +191 -0
  128. package/dist/runner/appium-executor.js.map +1 -0
  129. package/dist/runner/parse-strategies/appium-default.strategy.d.ts +12 -0
  130. package/dist/runner/parse-strategies/appium-default.strategy.d.ts.map +1 -0
  131. package/dist/runner/parse-strategies/appium-default.strategy.js +342 -0
  132. package/dist/runner/parse-strategies/appium-default.strategy.js.map +1 -0
  133. package/dist/runner/parse-strategies/index.d.ts +7 -0
  134. package/dist/runner/parse-strategies/index.d.ts.map +1 -0
  135. package/dist/runner/parse-strategies/index.js +14 -0
  136. package/dist/runner/parse-strategies/index.js.map +1 -0
  137. package/dist/runner/parse-strategies/java.strategy.d.ts +8 -0
  138. package/dist/runner/parse-strategies/java.strategy.d.ts.map +1 -0
  139. package/dist/runner/parse-strategies/java.strategy.js +170 -0
  140. package/dist/runner/parse-strategies/java.strategy.js.map +1 -0
  141. package/dist/runner/parse-strategies/maestro.strategy.d.ts +8 -0
  142. package/dist/runner/parse-strategies/maestro.strategy.d.ts.map +1 -0
  143. package/dist/runner/parse-strategies/maestro.strategy.js +105 -0
  144. package/dist/runner/parse-strategies/maestro.strategy.js.map +1 -0
  145. package/dist/runner/parse-strategies/python.strategy.d.ts +8 -0
  146. package/dist/runner/parse-strategies/python.strategy.d.ts.map +1 -0
  147. package/dist/runner/parse-strategies/python.strategy.js +140 -0
  148. package/dist/runner/parse-strategies/python.strategy.js.map +1 -0
  149. package/dist/runner/parse-strategies/robot.strategy.d.ts +8 -0
  150. package/dist/runner/parse-strategies/robot.strategy.d.ts.map +1 -0
  151. package/dist/runner/parse-strategies/robot.strategy.js +81 -0
  152. package/dist/runner/parse-strategies/robot.strategy.js.map +1 -0
  153. package/dist/runner/parse-strategies/types.d.ts +17 -0
  154. package/dist/runner/parse-strategies/types.d.ts.map +1 -0
  155. package/dist/runner/parse-strategies/types.js +3 -0
  156. package/dist/runner/parse-strategies/types.js.map +1 -0
  157. package/dist/runner/parse-strategies/utils.d.ts +39 -0
  158. package/dist/runner/parse-strategies/utils.d.ts.map +1 -0
  159. package/dist/runner/parse-strategies/utils.js +217 -0
  160. package/dist/runner/parse-strategies/utils.js.map +1 -0
  161. package/dist/runner/script-parser.d.ts +43 -0
  162. package/dist/runner/script-parser.d.ts.map +1 -0
  163. package/dist/runner/script-parser.js +68 -0
  164. package/dist/runner/script-parser.js.map +1 -0
  165. package/dist/runner/selector-resolver.d.ts +87 -0
  166. package/dist/runner/selector-resolver.d.ts.map +1 -0
  167. package/dist/runner/selector-resolver.js +206 -0
  168. package/dist/runner/selector-resolver.js.map +1 -0
  169. package/dist/runner/step-executor.d.ts +112 -0
  170. package/dist/runner/step-executor.d.ts.map +1 -0
  171. package/dist/runner/step-executor.js +518 -0
  172. package/dist/runner/step-executor.js.map +1 -0
  173. package/dist/runner/test-runner.d.ts +89 -0
  174. package/dist/runner/test-runner.d.ts.map +1 -0
  175. package/dist/runner/test-runner.js +320 -0
  176. package/dist/runner/test-runner.js.map +1 -0
  177. package/dist/scrcpy/launcher.d.ts +16 -0
  178. package/dist/scrcpy/launcher.d.ts.map +1 -0
  179. package/dist/scrcpy/launcher.js +87 -0
  180. package/dist/scrcpy/launcher.js.map +1 -0
  181. package/dist/services/device-poller.d.ts +10 -0
  182. package/dist/services/device-poller.d.ts.map +1 -0
  183. package/dist/services/device-poller.js +44 -0
  184. package/dist/services/device-poller.js.map +1 -0
  185. package/dist/services/execution-manager.d.ts +18 -0
  186. package/dist/services/execution-manager.d.ts.map +1 -0
  187. package/dist/services/execution-manager.js +185 -0
  188. package/dist/services/execution-manager.js.map +1 -0
  189. package/dist/services/recording-manager.d.ts +13 -0
  190. package/dist/services/recording-manager.d.ts.map +1 -0
  191. package/dist/services/recording-manager.js +234 -0
  192. package/dist/services/recording-manager.js.map +1 -0
  193. package/dist/setup/adb-installer.d.ts +8 -0
  194. package/dist/setup/adb-installer.d.ts.map +1 -0
  195. package/dist/setup/adb-installer.js +115 -0
  196. package/dist/setup/adb-installer.js.map +1 -0
  197. package/dist/setup/appium-installer.d.ts +8 -0
  198. package/dist/setup/appium-installer.d.ts.map +1 -0
  199. package/dist/setup/appium-installer.js +113 -0
  200. package/dist/setup/appium-installer.js.map +1 -0
  201. package/dist/setup/base-installer.d.ts +33 -0
  202. package/dist/setup/base-installer.d.ts.map +1 -0
  203. package/dist/setup/base-installer.js +170 -0
  204. package/dist/setup/base-installer.js.map +1 -0
  205. package/dist/setup/build-tools-installer.d.ts +8 -0
  206. package/dist/setup/build-tools-installer.d.ts.map +1 -0
  207. package/dist/setup/build-tools-installer.js +109 -0
  208. package/dist/setup/build-tools-installer.js.map +1 -0
  209. package/dist/setup/java-installer.d.ts +8 -0
  210. package/dist/setup/java-installer.d.ts.map +1 -0
  211. package/dist/setup/java-installer.js +132 -0
  212. package/dist/setup/java-installer.js.map +1 -0
  213. package/dist/setup/paths.d.ts +12 -0
  214. package/dist/setup/paths.d.ts.map +1 -0
  215. package/dist/setup/paths.js +90 -0
  216. package/dist/setup/paths.js.map +1 -0
  217. package/dist/setup/scrcpy-installer.d.ts +8 -0
  218. package/dist/setup/scrcpy-installer.d.ts.map +1 -0
  219. package/dist/setup/scrcpy-installer.js +143 -0
  220. package/dist/setup/scrcpy-installer.js.map +1 -0
  221. package/dist/setup/setup-manager.d.ts +18 -0
  222. package/dist/setup/setup-manager.d.ts.map +1 -0
  223. package/dist/setup/setup-manager.js +113 -0
  224. package/dist/setup/setup-manager.js.map +1 -0
  225. package/dist/ws/socket.d.ts +38 -0
  226. package/dist/ws/socket.d.ts.map +1 -0
  227. package/dist/ws/socket.js +91 -0
  228. package/dist/ws/socket.js.map +1 -0
  229. package/package.json +53 -0
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Resolves the ADB binary path across platforms.
3
+ * Priority: ~/.testdroid/ → PATH → ANDROID_HOME → ANDROID_SDK_ROOT → platform defaults
4
+ */
5
+ export declare function resolveAdbPath(): string;
6
+ //# sourceMappingURL=adb-path-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adb-path-resolver.d.ts","sourceRoot":"","sources":["../../src/adb/adb-path-resolver.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAkDvC"}
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.resolveAdbPath = resolveAdbPath;
37
+ const child_process_1 = require("child_process");
38
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ const fs = __importStar(require("fs"));
41
+ const paths_1 = require("../setup/paths");
42
+ /**
43
+ * Resolves the ADB binary path across platforms.
44
+ * Priority: ~/.testdroid/ → PATH → ANDROID_HOME → ANDROID_SDK_ROOT → platform defaults
45
+ */
46
+ function resolveAdbPath() {
47
+ // 1. Check ~/.testdroid/platform-tools/adb (testdroid setup install)
48
+ const testdroidAdb = (0, paths_1.getAdbPath)();
49
+ if (fs.existsSync(testdroidAdb)) {
50
+ try {
51
+ (0, child_process_1.execFileSync)(testdroidAdb, ['version'], { stdio: 'pipe' });
52
+ return testdroidAdb;
53
+ }
54
+ catch { }
55
+ }
56
+ // 2. Check if adb is in PATH
57
+ try {
58
+ (0, child_process_1.execFileSync)('adb', ['version'], { stdio: 'pipe' });
59
+ return 'adb';
60
+ }
61
+ catch { }
62
+ // 3. Check ANDROID_HOME / ANDROID_SDK_ROOT
63
+ const sdkPaths = [
64
+ process.env.ANDROID_HOME,
65
+ process.env.ANDROID_SDK_ROOT,
66
+ ].filter(Boolean);
67
+ // 4. Check default installation paths per platform
68
+ if (process.platform === 'darwin') {
69
+ sdkPaths.push(path.join(os.homedir(), 'Library', 'Android', 'sdk'));
70
+ }
71
+ else if (process.platform === 'linux') {
72
+ sdkPaths.push(path.join(os.homedir(), 'Android', 'Sdk'));
73
+ }
74
+ else if (process.platform === 'win32') {
75
+ const localAppData = process.env.LOCALAPPDATA || '';
76
+ if (localAppData) {
77
+ sdkPaths.push(path.join(localAppData, 'Android', 'Sdk'));
78
+ }
79
+ }
80
+ for (const sdkPath of sdkPaths) {
81
+ const adbBinary = process.platform === 'win32' ? 'adb.exe' : 'adb';
82
+ const adbPath = path.join(sdkPath, 'platform-tools', adbBinary);
83
+ if (fs.existsSync(adbPath)) {
84
+ try {
85
+ (0, child_process_1.execFileSync)(adbPath, ['version'], { stdio: 'pipe' });
86
+ return adbPath;
87
+ }
88
+ catch { }
89
+ }
90
+ }
91
+ throw new Error('ADB not found. Run `testdroid setup` to install automatically.');
92
+ }
93
+ //# sourceMappingURL=adb-path-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adb-path-resolver.js","sourceRoot":"","sources":["../../src/adb/adb-path-resolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUA,wCAkDC;AA5DD,iDAA6C;AAC7C,2CAA6B;AAC7B,uCAAyB;AACzB,uCAAyB;AACzB,0CAA4C;AAE5C;;;GAGG;AACH,SAAgB,cAAc;IAC5B,qEAAqE;IACrE,MAAM,YAAY,GAAG,IAAA,kBAAU,GAAE,CAAC;IAClC,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,IAAA,4BAAY,EAAC,YAAY,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC3D,OAAO,YAAY,CAAC;QACtB,CAAC;QAAC,MAAM,CAAC,CAAA,CAAC;IACZ,CAAC;IAED,6BAA6B;IAC7B,IAAI,CAAC;QACH,IAAA,4BAAY,EAAC,KAAK,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACpD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,2CAA2C;IAC3C,MAAM,QAAQ,GAAG;QACf,OAAO,CAAC,GAAG,CAAC,YAAY;QACxB,OAAO,CAAC,GAAG,CAAC,gBAAgB;KAC7B,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;IAE9B,mDAAmD;IACnD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IACtE,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IAC3D,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACxC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;QACpD,IAAI,YAAY,EAAE,CAAC;YACjB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAED,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,MAAM,SAAS,GACb,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,SAAS,CAAC,CAAC;QAEhE,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,IAAA,4BAAY,EAAC,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBACtD,OAAO,OAAO,CAAC;YACjB,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;QACZ,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CACb,gEAAgE,CACjE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ export interface AdbDevice {
2
+ serial: string;
3
+ state: string;
4
+ product?: string;
5
+ model?: string;
6
+ device?: string;
7
+ transportId?: string;
8
+ }
9
+ export declare class AdbShell {
10
+ private adbPath;
11
+ constructor(adbPath?: string);
12
+ hasAdb(): boolean;
13
+ listDevices(): AdbDevice[];
14
+ getDeviceProperty(serial: string, prop: string): string;
15
+ getDeviceInfo(serial: string): {
16
+ model: string;
17
+ brand: string;
18
+ osVersion: string;
19
+ sdkVersion: string;
20
+ };
21
+ isEmulator(serial: string): boolean;
22
+ getScreenSize(serial: string): {
23
+ width: number;
24
+ height: number;
25
+ };
26
+ startServer(): void;
27
+ private parseDeviceLine;
28
+ }
29
+ //# sourceMappingURL=adb-shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adb-shell.d.ts","sourceRoot":"","sources":["../../src/adb/adb-shell.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAaD,qBAAa,QAAQ;IACP,OAAO,CAAC,OAAO;gBAAP,OAAO,GAAE,MAAc;IAE3C,MAAM,IAAI,OAAO;IASjB,WAAW,IAAI,SAAS,EAAE;IAwB1B,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IAgBvD,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;QAC7B,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACpB;IAYD,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAInC,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAehE,WAAW,IAAI,IAAI;IAMnB,OAAO,CAAC,eAAe;CAyCxB"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AdbShell = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const ALLOWED_PROPS = [
6
+ 'ro.product.model',
7
+ 'ro.product.brand',
8
+ 'ro.build.version.release',
9
+ 'ro.build.version.sdk',
10
+ 'ro.kernel.qemu',
11
+ 'ro.hardware',
12
+ 'ro.build.fingerprint',
13
+ 'ro.build.characteristics',
14
+ ];
15
+ class AdbShell {
16
+ adbPath;
17
+ constructor(adbPath = 'adb') {
18
+ this.adbPath = adbPath;
19
+ }
20
+ hasAdb() {
21
+ try {
22
+ (0, child_process_1.execFileSync)(this.adbPath, ['version'], { stdio: 'pipe' });
23
+ return true;
24
+ }
25
+ catch {
26
+ return false;
27
+ }
28
+ }
29
+ listDevices() {
30
+ try {
31
+ const output = (0, child_process_1.execFileSync)(this.adbPath, ['devices', '-l'], {
32
+ encoding: 'utf-8',
33
+ stdio: 'pipe',
34
+ });
35
+ const lines = output.trim().split('\n').slice(1);
36
+ return lines
37
+ .filter((line) => line.trim().length > 0)
38
+ .map((line) => this.parseDeviceLine(line))
39
+ .filter((device) => device !== null);
40
+ }
41
+ catch (err) {
42
+ if (err.code === 'ENOENT') {
43
+ console.error('Erro: adb nao encontrado. Instale o Android SDK e adicione ao PATH.');
44
+ }
45
+ else {
46
+ console.error(`Erro ao listar dispositivos: ${err.message}`);
47
+ }
48
+ return [];
49
+ }
50
+ }
51
+ getDeviceProperty(serial, prop) {
52
+ if (!ALLOWED_PROPS.includes(prop)) {
53
+ return '';
54
+ }
55
+ try {
56
+ const output = (0, child_process_1.execFileSync)(this.adbPath, ['-s', serial, 'shell', 'getprop', prop], { encoding: 'utf-8', stdio: 'pipe', timeout: 5000 });
57
+ return output.trim();
58
+ }
59
+ catch {
60
+ return '';
61
+ }
62
+ }
63
+ getDeviceInfo(serial) {
64
+ return {
65
+ model: this.getDeviceProperty(serial, 'ro.product.model'),
66
+ brand: this.getDeviceProperty(serial, 'ro.product.brand'),
67
+ osVersion: this.getDeviceProperty(serial, 'ro.build.version.release'),
68
+ sdkVersion: this.getDeviceProperty(serial, 'ro.build.version.sdk'),
69
+ };
70
+ }
71
+ isEmulator(serial) {
72
+ return serial.startsWith('emulator-');
73
+ }
74
+ getScreenSize(serial) {
75
+ try {
76
+ const output = (0, child_process_1.execFileSync)(this.adbPath, ['-s', serial, 'shell', 'wm', 'size'], { encoding: 'utf-8', stdio: 'pipe', timeout: 5000 });
77
+ const match = output.match(/(\d+)x(\d+)/);
78
+ if (match) {
79
+ return { width: parseInt(match[1], 10), height: parseInt(match[2], 10) };
80
+ }
81
+ }
82
+ catch { }
83
+ return { width: 1080, height: 2400 };
84
+ }
85
+ startServer() {
86
+ try {
87
+ (0, child_process_1.execFileSync)(this.adbPath, ['start-server'], { stdio: 'pipe' });
88
+ }
89
+ catch { }
90
+ }
91
+ parseDeviceLine(line) {
92
+ const parts = line.trim().split(/\s+/);
93
+ if (parts.length < 2)
94
+ return null;
95
+ const serial = parts[0];
96
+ const state = parts[1];
97
+ if (state !== 'device' &&
98
+ state !== 'offline' &&
99
+ state !== 'unauthorized' &&
100
+ state !== 'authorizing' &&
101
+ state !== 'no permissions') {
102
+ return null;
103
+ }
104
+ const device = { serial, state };
105
+ for (let i = 2; i < parts.length; i++) {
106
+ const [key, value] = parts[i].split(':');
107
+ if (key && value) {
108
+ switch (key) {
109
+ case 'product':
110
+ device.product = value;
111
+ break;
112
+ case 'model':
113
+ device.model = value;
114
+ break;
115
+ case 'device':
116
+ device.device = value;
117
+ break;
118
+ case 'transport_id':
119
+ device.transportId = value;
120
+ break;
121
+ }
122
+ }
123
+ }
124
+ return device;
125
+ }
126
+ }
127
+ exports.AdbShell = AdbShell;
128
+ //# sourceMappingURL=adb-shell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adb-shell.js","sourceRoot":"","sources":["../../src/adb/adb-shell.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { Device } from '@testdroid-ai/shared';
2
+ import { AdbShell } from './adb-shell';
3
+ export declare class DeviceDetector {
4
+ private adbClient;
5
+ constructor(adbClient?: AdbShell);
6
+ /**
7
+ * Detecta todos os dispositivos conectados via ADB
8
+ * e converte para o tipo Device compartilhado.
9
+ */
10
+ detect(): Device[];
11
+ }
12
+ //# sourceMappingURL=detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.d.ts","sourceRoot":"","sources":["../../src/adb/detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAOvC,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAW;gBAEhB,SAAS,CAAC,EAAE,QAAQ;IAIhC;;;OAGG;IACH,MAAM,IAAI,MAAM,EAAE;CA4BnB"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DeviceDetector = void 0;
4
+ const adb_shell_1 = require("./adb-shell");
5
+ const generateId = () => {
6
+ // Simple unique ID without extra dependency
7
+ return `dev_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
8
+ };
9
+ class DeviceDetector {
10
+ adbClient;
11
+ constructor(adbClient) {
12
+ this.adbClient = adbClient || new adb_shell_1.AdbShell();
13
+ }
14
+ /**
15
+ * Detecta todos os dispositivos conectados via ADB
16
+ * e converte para o tipo Device compartilhado.
17
+ */
18
+ detect() {
19
+ if (!this.adbClient.hasAdb()) {
20
+ return [];
21
+ }
22
+ const adbDevices = this.adbClient.listDevices();
23
+ return adbDevices
24
+ .filter((d) => d.state === 'device') // Only online devices
25
+ .map((adbDevice) => {
26
+ const info = this.adbClient.getDeviceInfo(adbDevice.serial);
27
+ const isEmulator = this.adbClient.isEmulator(adbDevice.serial);
28
+ const device = {
29
+ id: generateId(),
30
+ serial: adbDevice.serial,
31
+ name: info.model || adbDevice.model || adbDevice.serial,
32
+ platform: 'android',
33
+ model: info.model || adbDevice.model || 'Unknown',
34
+ osVersion: info.osVersion || 'Unknown',
35
+ status: 'online',
36
+ type: isEmulator ? 'emulator' : 'physical',
37
+ connectionType: isEmulator ? 'wifi' : 'usb',
38
+ };
39
+ return device;
40
+ });
41
+ }
42
+ }
43
+ exports.DeviceDetector = DeviceDetector;
44
+ //# sourceMappingURL=detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detector.js","sourceRoot":"","sources":["../../src/adb/detector.ts"],"names":[],"mappings":";;;AACA,2CAAuC;AAEvC,MAAM,UAAU,GAAG,GAAW,EAAE;IAC9B,4CAA4C;IAC5C,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC,CAAC;AAEF,MAAa,cAAc;IACjB,SAAS,CAAW;IAE5B,YAAY,SAAoB;QAC9B,IAAI,CAAC,SAAS,GAAG,SAAS,IAAI,IAAI,oBAAQ,EAAE,CAAC;IAC/C,CAAC;IAED;;;OAGG;IACH,MAAM;QACJ,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YAC7B,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;QAEhD,OAAO,UAAU;aACd,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,sBAAsB;aAC1D,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE;YACjB,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC5D,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAE/D,MAAM,MAAM,GAAW;gBACrB,EAAE,EAAE,UAAU,EAAE;gBAChB,MAAM,EAAE,SAAS,CAAC,MAAM;gBACxB,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM;gBACvD,QAAQ,EAAE,SAAS;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,SAAS,CAAC,KAAK,IAAI,SAAS;gBACjD,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,SAAS;gBACtC,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;gBAC1C,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;aAC5C,CAAC;YAEF,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC,CAAC;IACP,CAAC;CACF;AAvCD,wCAuCC"}
@@ -0,0 +1,23 @@
1
+ import { EventEmitter } from 'events';
2
+ import { Device } from '@testdroid-ai/shared';
3
+ /**
4
+ * Event-driven device tracker using adbkit.
5
+ * Replaces 5-second polling with instant USB/emulator detection.
6
+ */
7
+ export declare class DeviceTracker extends EventEmitter {
8
+ private client;
9
+ private adbShell;
10
+ private devices;
11
+ private backoffMs;
12
+ private maxBackoff;
13
+ private running;
14
+ constructor();
15
+ start(): Promise<void>;
16
+ stop(): void;
17
+ getDevices(): Device[];
18
+ private startTracking;
19
+ private handleAdd;
20
+ private handleRemove;
21
+ private reconnect;
22
+ }
23
+ //# sourceMappingURL=device-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-tracker.d.ts","sourceRoot":"","sources":["../../src/adb/device-tracker.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAY9C;;;GAGG;AACH,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,OAAO,CAAkC;IACjD,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAS;;IASlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAsB5B,IAAI,IAAI,IAAI;IAKZ,UAAU,IAAI,MAAM,EAAE;YAIR,aAAa;YAqCb,SAAS;IA8BvB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,SAAS;CAOlB"}
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DeviceTracker = void 0;
7
+ const adbkit_1 = __importDefault(require("@devicefarmer/adbkit"));
8
+ const events_1 = require("events");
9
+ const adb_shell_1 = require("./adb-shell");
10
+ const emulator_detector_1 = require("./emulator-detector");
11
+ const adb_path_resolver_1 = require("./adb-path-resolver");
12
+ /**
13
+ * Event-driven device tracker using adbkit.
14
+ * Replaces 5-second polling with instant USB/emulator detection.
15
+ */
16
+ class DeviceTracker extends events_1.EventEmitter {
17
+ client;
18
+ adbShell;
19
+ devices = new Map();
20
+ backoffMs = 2000;
21
+ maxBackoff = 60000;
22
+ running = false;
23
+ constructor() {
24
+ super();
25
+ const adbPath = (0, adb_path_resolver_1.resolveAdbPath)();
26
+ this.adbShell = new adb_shell_1.AdbShell(adbPath);
27
+ this.client = adbkit_1.default.createClient({ bin: adbPath });
28
+ }
29
+ async start() {
30
+ this.running = true;
31
+ // Auto-start ADB server
32
+ this.adbShell.startServer();
33
+ // Initial device list (baseline)
34
+ try {
35
+ const initialDevices = await this.client.listDevices();
36
+ for (const d of initialDevices) {
37
+ if (d.type === 'device') {
38
+ await this.handleAdd(d.id);
39
+ }
40
+ }
41
+ }
42
+ catch (err) {
43
+ this.emit('error', err);
44
+ }
45
+ // Event-driven tracking
46
+ await this.startTracking();
47
+ }
48
+ stop() {
49
+ this.running = false;
50
+ this.devices.clear();
51
+ }
52
+ getDevices() {
53
+ return Array.from(this.devices.values());
54
+ }
55
+ async startTracking() {
56
+ try {
57
+ const tracker = await this.client.trackDevices();
58
+ tracker.on('add', async (device) => {
59
+ if (device.type === 'device') {
60
+ await this.handleAdd(device.id);
61
+ }
62
+ });
63
+ tracker.on('remove', (device) => {
64
+ this.handleRemove(device.id);
65
+ });
66
+ tracker.on('change', async (device) => {
67
+ if (device.type === 'device') {
68
+ await this.handleAdd(device.id);
69
+ }
70
+ else {
71
+ this.handleRemove(device.id);
72
+ }
73
+ });
74
+ tracker.on('end', () => {
75
+ if (this.running)
76
+ this.reconnect();
77
+ });
78
+ tracker.on('error', () => {
79
+ if (this.running)
80
+ this.reconnect();
81
+ });
82
+ // Reset backoff on successful connection
83
+ this.backoffMs = 2000;
84
+ }
85
+ catch (err) {
86
+ if (this.running)
87
+ this.reconnect();
88
+ }
89
+ }
90
+ async handleAdd(serial) {
91
+ try {
92
+ const info = this.adbShell.getDeviceInfo(serial);
93
+ const emulator = await (0, emulator_detector_1.isEmulator)(serial, this.adbShell);
94
+ const device = {
95
+ id: `dev_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
96
+ serial,
97
+ name: info.model || serial,
98
+ platform: 'android',
99
+ model: info.model,
100
+ osVersion: info.osVersion,
101
+ status: 'online',
102
+ type: emulator ? 'emulator' : 'physical',
103
+ connectionType: (0, emulator_detector_1.getConnectionType)(serial),
104
+ };
105
+ const isNew = !this.devices.has(serial);
106
+ this.devices.set(serial, device);
107
+ if (isNew) {
108
+ this.emit('add', device);
109
+ }
110
+ else {
111
+ this.emit('change', device);
112
+ }
113
+ }
114
+ catch (err) {
115
+ this.emit('error', err);
116
+ }
117
+ }
118
+ handleRemove(serial) {
119
+ if (this.devices.has(serial)) {
120
+ this.devices.delete(serial);
121
+ this.emit('remove', serial);
122
+ }
123
+ }
124
+ reconnect() {
125
+ setTimeout(async () => {
126
+ if (!this.running)
127
+ return;
128
+ this.backoffMs = Math.min(this.backoffMs * 2, this.maxBackoff);
129
+ await this.startTracking();
130
+ }, this.backoffMs);
131
+ }
132
+ }
133
+ exports.DeviceTracker = DeviceTracker;
134
+ //# sourceMappingURL=device-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-tracker.js","sourceRoot":"","sources":["../../src/adb/device-tracker.ts"],"names":[],"mappings":";;;;;;AAAA,kEAAuC;AACvC,mCAAsC;AAEtC,2CAAuC;AACvC,2DAAoE;AACpE,2DAAqD;AASrD;;;GAGG;AACH,MAAa,aAAc,SAAQ,qBAAY;IACrC,MAAM,CAAM;IACZ,QAAQ,CAAW;IACnB,OAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;IACzC,SAAS,GAAG,IAAI,CAAC;IACjB,UAAU,GAAG,KAAK,CAAC;IACnB,OAAO,GAAG,KAAK,CAAC;IAExB;QACE,KAAK,EAAE,CAAC;QACR,MAAM,OAAO,GAAG,IAAA,kCAAc,GAAE,CAAC;QACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAQ,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,MAAM,GAAG,gBAAG,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,wBAAwB;QACxB,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;QAE5B,iCAAiC;QACjC,IAAI,CAAC;YACH,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC;YACvD,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;gBAC/B,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACxB,MAAM,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBAC7B,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1B,CAAC;QAED,wBAAwB;QACxB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,UAAU;QACR,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC3C,CAAC;IAEO,KAAK,CAAC,aAAa;QACzB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;YAEjD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,MAAW,EAAE,EAAE;gBACtC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAClC,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,MAAW,EAAE,EAAE;gBACnC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC/B,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,MAAW,EAAE,EAAE;gBACzC,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAClC,CAAC;qBAAM,CAAC;oBACN,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC/B,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE;gBACrB,IAAI,IAAI,CAAC,OAAO;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,CAAC,CAAC,CAAC;YAEH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBACvB,IAAI,IAAI,CAAC,OAAO;oBAAE,IAAI,CAAC,SAAS,EAAE,CAAC;YACrC,CAAC,CAAC,CAAC;YAEH,yCAAyC;YACzC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,IAAI,CAAC,OAAO;gBAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QACrC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,SAAS,CAAC,MAAc;QACpC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YACjD,MAAM,QAAQ,GAAG,MAAM,IAAA,8BAAU,EAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAEzD,MAAM,MAAM,GAAW;gBACrB,EAAE,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;gBACjE,MAAM;gBACN,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI,MAAM;gBAC1B,QAAQ,EAAE,SAAS;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,SAAS,EAAE,IAAI,CAAC,SAAS;gBACzB,MAAM,EAAE,QAAQ;gBAChB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU;gBACxC,cAAc,EAAE,IAAA,qCAAiB,EAAC,MAAM,CAAC;aAC1C,CAAC;YAEF,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACxC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAEjC,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC3B,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,MAAc;QACjC,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC5B,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAEO,SAAS;QACf,UAAU,CAAC,KAAK,IAAI,EAAE;YACpB,IAAI,CAAC,IAAI,CAAC,OAAO;gBAAE,OAAO;YAC1B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YAC/D,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC;QAC7B,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACrB,CAAC;CACF;AA/HD,sCA+HC"}
@@ -0,0 +1,11 @@
1
+ import { AdbShell } from './adb-shell';
2
+ /**
3
+ * Multi-signal emulator detection.
4
+ * Checks: serial prefix → ro.kernel.qemu → ro.hardware → ro.build.fingerprint
5
+ */
6
+ export declare function isEmulator(serial: string, adbShell: AdbShell): Promise<boolean>;
7
+ /**
8
+ * Determines connection type from serial format.
9
+ */
10
+ export declare function getConnectionType(serial: string): 'usb' | 'wifi';
11
+ //# sourceMappingURL=emulator-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emulator-detector.d.ts","sourceRoot":"","sources":["../../src/adb/emulator-detector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAavC;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,QAAQ,GACjB,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,GACb,KAAK,GAAG,MAAM,CAWhB"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isEmulator = isEmulator;
4
+ exports.getConnectionType = getConnectionType;
5
+ const EMULATOR_HARDWARE = [
6
+ 'goldfish',
7
+ 'ranchu',
8
+ 'vbox86',
9
+ 'vbox86p',
10
+ 'nox',
11
+ 'saturn',
12
+ 'kirin',
13
+ 'windows',
14
+ ];
15
+ /**
16
+ * Multi-signal emulator detection.
17
+ * Checks: serial prefix → ro.kernel.qemu → ro.hardware → ro.build.fingerprint
18
+ */
19
+ async function isEmulator(serial, adbShell) {
20
+ // Fast path: serial prefix
21
+ if (serial.startsWith('emulator-'))
22
+ return true;
23
+ // Primary: kernel qemu flag (AVD, Genymotion, BlueStacks, Nox)
24
+ const qemu = adbShell.getDeviceProperty(serial, 'ro.kernel.qemu');
25
+ if (qemu === '1')
26
+ return true;
27
+ // Secondary: hardware check
28
+ const hw = adbShell.getDeviceProperty(serial, 'ro.hardware');
29
+ if (EMULATOR_HARDWARE.includes(hw))
30
+ return true;
31
+ // Tertiary: build fingerprint
32
+ const fp = adbShell.getDeviceProperty(serial, 'ro.build.fingerprint');
33
+ if (fp.includes('generic') ||
34
+ fp.includes('sdk') ||
35
+ fp.includes('vbox')) {
36
+ return true;
37
+ }
38
+ return false;
39
+ }
40
+ /**
41
+ * Determines connection type from serial format.
42
+ */
43
+ function getConnectionType(serial) {
44
+ // TCP/IP connections (IP:port format)
45
+ if (/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}:\d+$/.test(serial))
46
+ return 'wifi';
47
+ if (serial.startsWith('127.0.0.1:') ||
48
+ serial.startsWith('localhost:'))
49
+ return 'wifi';
50
+ if (serial.startsWith('emulator-'))
51
+ return 'wifi';
52
+ return 'usb';
53
+ }
54
+ //# sourceMappingURL=emulator-detector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emulator-detector.js","sourceRoot":"","sources":["../../src/adb/emulator-detector.ts"],"names":[],"mappings":";;AAiBA,gCA0BC;AAKD,8CAaC;AA3DD,MAAM,iBAAiB,GAAG;IACxB,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,SAAS;IACT,KAAK;IACL,QAAQ;IACR,OAAO;IACP,SAAS;CACV,CAAC;AAEF;;;GAGG;AACI,KAAK,UAAU,UAAU,CAC9B,MAAc,EACd,QAAkB;IAElB,2BAA2B;IAC3B,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAEhD,+DAA+D;IAC/D,MAAM,IAAI,GAAG,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAClE,IAAI,IAAI,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IAE9B,4BAA4B;IAC5B,MAAM,EAAE,GAAG,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC7D,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;QAAE,OAAO,IAAI,CAAC;IAEhD,8BAA8B;IAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,iBAAiB,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;IACtE,IACE,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC;QACtB,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;QAClB,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,EACnB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,SAAgB,iBAAiB,CAC/B,MAAc;IAEd,sCAAsC;IACtC,IAAI,0CAA0C,CAAC,IAAI,CAAC,MAAM,CAAC;QACzD,OAAO,MAAM,CAAC;IAChB,IACE,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;QAC/B,MAAM,CAAC,UAAU,CAAC,YAAY,CAAC;QAE/B,OAAO,MAAM,CAAC;IAChB,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,MAAM,CAAC;IAClD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Checks if Appium server is reachable AND webdriverio is importable.
3
+ * Both conditions must be true for Appium mode to work.
4
+ */
5
+ export declare function isAppiumRunning(url?: string): Promise<boolean>;
6
+ //# sourceMappingURL=health-check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-check.d.ts","sourceRoot":"","sources":["../../src/appium/health-check.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAsB,eAAe,CAAC,GAAG,SAA0B,GAAG,OAAO,CAAC,OAAO,CAAC,CAkBrF"}