@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,320 @@
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.TestRunner = void 0;
37
+ const fs_1 = require("fs");
38
+ const adb_shell_1 = require("../adb/adb-shell");
39
+ const adb_executor_1 = require("./adb-executor");
40
+ const script_parser_1 = require("./script-parser");
41
+ const step_executor_1 = require("./step-executor");
42
+ const execution_manager_1 = require("../services/execution-manager");
43
+ const healer_1 = require("../healing/healer");
44
+ /**
45
+ * Runner principal de testes.
46
+ *
47
+ * Suporta dois modos de execucao:
48
+ * - Modo A (adb): Executa via ADB direto - MVP, nao requer Appium
49
+ * - Modo B (appium): Executa via Appium/WebdriverIO - futuro
50
+ *
51
+ * O modo padrao e ADB (Modo A).
52
+ */
53
+ class TestRunner {
54
+ parser;
55
+ mode;
56
+ constructor(mode = 'adb') {
57
+ this.parser = new script_parser_1.ScriptParser(); // screen size e injectado em runAdbMode
58
+ this.mode = mode;
59
+ }
60
+ /**
61
+ * Executa um arquivo de teste no dispositivo.
62
+ *
63
+ * 1. Verifica se o dispositivo esta conectado
64
+ * 2. Le e parseia o arquivo de teste
65
+ * 3. Executa os passos via ADB
66
+ * 4. Captura screenshot em caso de falha
67
+ * 5. Retorna resultado
68
+ */
69
+ async run(options, onStep) {
70
+ const { serial, testFile, appPackage, timeout = 60000 } = options;
71
+ // 1. Verificar dispositivo
72
+ const adbClient = new adb_shell_1.AdbShell();
73
+ if (!adbClient.hasAdb()) {
74
+ return this.errorResult('ADB nao encontrado no sistema');
75
+ }
76
+ const adbExecutor = new adb_executor_1.AdbExecutor(serial);
77
+ if (!adbExecutor.isConnected()) {
78
+ return this.errorResult(`Dispositivo ${serial} nao esta conectado ou disponivel`);
79
+ }
80
+ // 2. Ler arquivo de teste
81
+ if (!(0, fs_1.existsSync)(testFile)) {
82
+ return this.errorResult(`Arquivo de teste nao encontrado: ${testFile}`);
83
+ }
84
+ const code = (0, fs_1.readFileSync)(testFile, 'utf-8');
85
+ if (!code.trim()) {
86
+ return this.errorResult('Arquivo de teste esta vazio');
87
+ }
88
+ // Fallback: if appPackage is empty, try to extract from test code
89
+ const resolvedPackage = appPackage || (0, execution_manager_1.extractAppPackageFromCode)(code) || '';
90
+ // 3. Executar conforme o modo
91
+ if (this.mode === 'appium') {
92
+ return this.runAppiumMode(options, onStep);
93
+ }
94
+ return this.runAdbMode(adbExecutor, code, resolvedPackage, timeout, onStep, { noHeal: options.noHeal, testRunId: options.testRunId });
95
+ }
96
+ /**
97
+ * Parseia o codigo de teste e retorna os passos sem executar.
98
+ * Util para preview / dry-run.
99
+ */
100
+ parseTestFile(testFile) {
101
+ const code = (0, fs_1.readFileSync)(testFile, 'utf-8');
102
+ return this.parser.parse(code);
103
+ }
104
+ /**
105
+ * Modo A: Execucao via ADB direto (MVP).
106
+ *
107
+ * Parseia o codigo gerado, extrai os passos,
108
+ * e executa cada um via AdbExecutor.
109
+ */
110
+ async runAdbMode(adbExecutor, code, appPackage, timeout, onStep, stepOptions) {
111
+ // Obter resolucao real do device para coordenadas relativas
112
+ const screenSize = adbExecutor.getScreenSize();
113
+ const parser = new script_parser_1.ScriptParser(screenSize);
114
+ // Parsear codigo em passos
115
+ const steps = parser.parse(code);
116
+ if (steps.length === 0) {
117
+ return this.errorResult('Nenhum passo de teste encontrado no arquivo. Verifique o formato do codigo.');
118
+ }
119
+ // Abrir o app antes de executar (se nao houver passo launch_app)
120
+ const hasLaunch = steps.some((s) => s.action === 'launch_app');
121
+ if (!hasLaunch && appPackage) {
122
+ try {
123
+ await adbExecutor.launchApp(appPackage);
124
+ // Aguarda o app iniciar
125
+ await this.sleep(2000);
126
+ }
127
+ catch {
128
+ // Continua mesmo se nao conseguir abrir o app
129
+ }
130
+ }
131
+ // Executar com timeout (inclui beforeEach/afterEach)
132
+ const executor = new step_executor_1.StepExecutor(adbExecutor, {
133
+ ...stepOptions,
134
+ appPackage,
135
+ });
136
+ const result = await Promise.race([
137
+ executor.executeAll(steps, onStep),
138
+ this.timeoutPromise(timeout),
139
+ ]);
140
+ return result;
141
+ }
142
+ /**
143
+ * Modo B: Execucao via Appium/WebDriverIO.
144
+ *
145
+ * Requer Appium server rodando e WebdriverIO instalado.
146
+ * Conecta ao Appium, parseia o script, e executa cada passo
147
+ * com suporte a self-healing e callbacks onStep.
148
+ */
149
+ async runAppiumMode(options, onStep) {
150
+ const { serial, testFile, appPackage, timeout = 60000 } = options;
151
+ // Dynamic import guard
152
+ try {
153
+ await Promise.resolve().then(() => __importStar(require('webdriverio')));
154
+ }
155
+ catch {
156
+ return this.errorResult('WebDriverIO nao instalado. Execute: npm install webdriverio');
157
+ }
158
+ const { AppiumExecutor } = await Promise.resolve().then(() => __importStar(require('./appium-executor')));
159
+ const code = (0, fs_1.readFileSync)(testFile, 'utf-8');
160
+ const screenSize = new adb_executor_1.AdbExecutor(serial).getScreenSize();
161
+ const parser = new script_parser_1.ScriptParser(screenSize);
162
+ const steps = parser.parse(code);
163
+ if (steps.length === 0) {
164
+ return this.errorResult('Nenhum passo de teste encontrado no arquivo.');
165
+ }
166
+ const executor = new AppiumExecutor(serial, options.appiumUrl || 'http://localhost:4723');
167
+ try {
168
+ await executor.connect();
169
+ }
170
+ catch (err) {
171
+ return this.errorResult(`Falha ao conectar Appium: ${err.message}`);
172
+ }
173
+ // Launch app if needed
174
+ const resolvedPackage = appPackage || (0, execution_manager_1.extractAppPackageFromCode)(code) || '';
175
+ if (!steps.some(s => s.action === 'launch_app') && resolvedPackage) {
176
+ try {
177
+ await executor.executeStep({ action: 'launch_app', params: { packageName: resolvedPackage }, line: 0, raw: '' });
178
+ await this.sleep(2000);
179
+ }
180
+ catch {
181
+ // Continue even if app launch fails
182
+ }
183
+ }
184
+ let timeoutTimer;
185
+ const abortFlag = { aborted: false };
186
+ const timeoutP = new Promise((resolve) => {
187
+ timeoutTimer = setTimeout(() => {
188
+ abortFlag.aborted = true;
189
+ resolve({
190
+ status: 'error',
191
+ duration: timeout,
192
+ logs: `Teste excedeu o timeout de ${timeout}ms`,
193
+ errorMessage: `Timeout: execucao excedeu ${timeout}ms`,
194
+ stepsTotal: steps.length,
195
+ stepsPassed: 0,
196
+ stepsFailed: 0,
197
+ healingAttempts: [],
198
+ });
199
+ }, timeout);
200
+ });
201
+ const result = await Promise.race([
202
+ this.executeAppiumSteps(executor, steps, options, onStep, abortFlag),
203
+ timeoutP,
204
+ ]);
205
+ clearTimeout(timeoutTimer);
206
+ await executor.disconnect();
207
+ return result;
208
+ }
209
+ /**
210
+ * Executa passos de teste sequencialmente via AppiumExecutor.
211
+ * Inclui self-healing e callbacks onStep.
212
+ */
213
+ async executeAppiumSteps(executor, steps, options, onStep, abortFlag) {
214
+ const startTime = Date.now();
215
+ let passed = 0;
216
+ let failed = 0;
217
+ const healingAttempts = [];
218
+ const logs = [];
219
+ for (let i = 0; i < steps.length; i++) {
220
+ if (abortFlag?.aborted)
221
+ break; // Stop executing after timeout
222
+ const step = steps[i];
223
+ const result = await executor.executeStep(step);
224
+ let stepResult = { success: result.success, error: result.error };
225
+ // Self-healing
226
+ if (!result.success && step.params.selector && !options.noHeal) {
227
+ try {
228
+ const selectorType = healer_1.Healer.detectSelectorType(step.params.selector);
229
+ const adb = new adb_executor_1.AdbExecutor(options.serial);
230
+ const healer = new healer_1.Healer(adb);
231
+ const healResult = await healer.heal(step.params.selector, selectorType);
232
+ if (healResult.healed && healResult.attempt) {
233
+ const originalSelector = step.params.selector;
234
+ step.params.selector = healResult.attempt.newSelector;
235
+ const retryResult = await executor.executeStep(step);
236
+ if (retryResult.success) {
237
+ healingAttempts.push(healResult.attempt);
238
+ stepResult = { success: true, healed: true, healingAttempt: healResult.attempt };
239
+ passed++;
240
+ logs.push(`[${i + 1}] ${step.action} — HEALED (${originalSelector} → ${healResult.attempt.newSelector})`);
241
+ if (onStep)
242
+ onStep(i, step, stepResult);
243
+ continue;
244
+ }
245
+ else {
246
+ step.params.selector = originalSelector;
247
+ }
248
+ }
249
+ }
250
+ catch {
251
+ /* healing best-effort */
252
+ }
253
+ }
254
+ if (result.success) {
255
+ passed++;
256
+ logs.push(`[${i + 1}] ${step.action} — OK (${result.duration}ms)`);
257
+ }
258
+ else {
259
+ failed++;
260
+ logs.push(`[${i + 1}] ${step.action} — FALHOU: ${result.error}`);
261
+ }
262
+ if (onStep)
263
+ onStep(i, step, stepResult);
264
+ if (!result.success && !stepResult.healed)
265
+ break; // Break on first failure (consistent with ADB mode)
266
+ }
267
+ return {
268
+ status: failed === 0 ? 'passed' : 'failed',
269
+ duration: Date.now() - startTime,
270
+ logs: logs.join('\n'),
271
+ stepsTotal: steps.length,
272
+ stepsPassed: passed,
273
+ stepsFailed: failed,
274
+ healingAttempts,
275
+ errorMessage: failed > 0 ? `${failed} passo(s) falharam` : undefined,
276
+ };
277
+ }
278
+ /**
279
+ * Cria um resultado de erro.
280
+ */
281
+ errorResult(message) {
282
+ return {
283
+ status: 'error',
284
+ duration: 0,
285
+ logs: message,
286
+ errorMessage: message,
287
+ stepsTotal: 0,
288
+ stepsPassed: 0,
289
+ stepsFailed: 0,
290
+ healingAttempts: [],
291
+ };
292
+ }
293
+ /**
294
+ * Promise que rejeita apos o timeout.
295
+ */
296
+ timeoutPromise(ms) {
297
+ return new Promise((resolve) => {
298
+ setTimeout(() => {
299
+ resolve({
300
+ status: 'error',
301
+ duration: ms,
302
+ logs: `Teste excedeu o timeout de ${ms}ms`,
303
+ errorMessage: `Timeout: execucao excedeu ${ms}ms`,
304
+ stepsTotal: 0,
305
+ stepsPassed: 0,
306
+ stepsFailed: 0,
307
+ healingAttempts: [],
308
+ });
309
+ }, ms);
310
+ });
311
+ }
312
+ /**
313
+ * Aguarda ms milissegundos.
314
+ */
315
+ sleep(ms) {
316
+ return new Promise((resolve) => setTimeout(resolve, ms));
317
+ }
318
+ }
319
+ exports.TestRunner = TestRunner;
320
+ //# sourceMappingURL=test-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-runner.js","sourceRoot":"","sources":["../../src/runner/test-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ChildProcess } from 'child_process';
2
+ export interface ScrcpyOptions {
3
+ maxSize?: number;
4
+ bitRate?: string;
5
+ noAudio?: boolean;
6
+ windowTitle?: string;
7
+ }
8
+ export declare class ScrcpyLauncher {
9
+ private process;
10
+ private resolveScrcpy;
11
+ hasScrcpy(): boolean;
12
+ start(serial: string, options?: ScrcpyOptions): ChildProcess;
13
+ stop(): void;
14
+ isRunning(): boolean;
15
+ }
16
+ //# sourceMappingURL=launcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.d.ts","sourceRoot":"","sources":["../../src/scrcpy/launcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAuB,MAAM,eAAe,CAAC;AAIlE,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAA6B;IAE5C,OAAO,CAAC,aAAa;IAQrB,SAAS,IAAI,OAAO;IAUpB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,YAAY;IAuB5D,IAAI,IAAI,IAAI;IAOZ,SAAS,IAAI,OAAO;CAGrB"}
@@ -0,0 +1,87 @@
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.ScrcpyLauncher = void 0;
37
+ const child_process_1 = require("child_process");
38
+ const fs = __importStar(require("fs"));
39
+ const paths_1 = require("../setup/paths");
40
+ class ScrcpyLauncher {
41
+ process = null;
42
+ resolveScrcpy() {
43
+ const testdroidPath = (0, paths_1.getScrcpyPath)();
44
+ if (fs.existsSync(testdroidPath)) {
45
+ return testdroidPath;
46
+ }
47
+ return 'scrcpy';
48
+ }
49
+ hasScrcpy() {
50
+ try {
51
+ const scrcpyBin = this.resolveScrcpy();
52
+ (0, child_process_1.execFileSync)(scrcpyBin, ['--version'], { stdio: 'pipe' });
53
+ return true;
54
+ }
55
+ catch {
56
+ return false;
57
+ }
58
+ }
59
+ start(serial, options) {
60
+ const scrcpyBin = this.resolveScrcpy();
61
+ const args = ['-s', serial, '--no-audio'];
62
+ if (options?.maxSize) {
63
+ args.push('--max-size', options.maxSize.toString());
64
+ }
65
+ if (options?.bitRate) {
66
+ args.push('--video-bit-rate', options.bitRate);
67
+ }
68
+ if (options?.windowTitle) {
69
+ args.push('--window-title', options.windowTitle);
70
+ }
71
+ this.process = (0, child_process_1.spawn)(scrcpyBin, args, {
72
+ stdio: 'pipe',
73
+ });
74
+ return this.process;
75
+ }
76
+ stop() {
77
+ if (this.process) {
78
+ this.process.kill();
79
+ this.process = null;
80
+ }
81
+ }
82
+ isRunning() {
83
+ return this.process !== null && !this.process.killed;
84
+ }
85
+ }
86
+ exports.ScrcpyLauncher = ScrcpyLauncher;
87
+ //# sourceMappingURL=launcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launcher.js","sourceRoot":"","sources":["../../src/scrcpy/launcher.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAAkE;AAClE,uCAAyB;AACzB,0CAA+C;AAS/C,MAAa,cAAc;IACjB,OAAO,GAAwB,IAAI,CAAC;IAEpC,aAAa;QACnB,MAAM,aAAa,GAAG,IAAA,qBAAa,GAAE,CAAC;QACtC,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,OAAO,aAAa,CAAC;QACvB,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,SAAS;QACP,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;YACvC,IAAA,4BAAY,EAAC,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC1D,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAc,EAAE,OAAuB;QAC3C,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,IAAI,GAAa,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC;QAEpD,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;YACrB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,OAAO,EAAE,WAAW,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;QACnD,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,IAAA,qBAAK,EAAC,SAAS,EAAE,IAAI,EAAE;YACpC,KAAK,EAAE,MAAM;SACd,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;IACvD,CAAC;CACF;AAtDD,wCAsDC"}
@@ -0,0 +1,10 @@
1
+ import { Device } from '@testdroid-ai/shared';
2
+ import { DeviceDetector } from '../adb/detector';
3
+ import { WebSocketClient } from '../ws/socket';
4
+ import { RecordingManager } from './recording-manager';
5
+ export declare class DevicePoller {
6
+ private pollInterval;
7
+ start(intervalMs: number, wsClient: WebSocketClient, detector: DeviceDetector, devices: Device[], recordingManager: RecordingManager): void;
8
+ stop(): void;
9
+ }
10
+ //# sourceMappingURL=device-poller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-poller.d.ts","sourceRoot":"","sources":["../../src/services/device-poller.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,qBAAa,YAAY;IACvB,OAAO,CAAC,YAAY,CAA+C;IAEnE,KAAK,CACH,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,eAAe,EACzB,QAAQ,EAAE,cAAc,EACxB,OAAO,EAAE,MAAM,EAAE,EACjB,gBAAgB,EAAE,gBAAgB,GACjC,IAAI;IA+BP,IAAI,IAAI,IAAI;CAMb"}
@@ -0,0 +1,44 @@
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.DevicePoller = void 0;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ class DevicePoller {
9
+ pollInterval = null;
10
+ start(intervalMs, wsClient, detector, devices, recordingManager) {
11
+ this.pollInterval = setInterval(() => {
12
+ const currentDevices = detector.detect();
13
+ const currentSerials = new Set(currentDevices.map((d) => d.serial));
14
+ const previousSerials = new Set(devices.map((d) => d.serial));
15
+ // Novos dispositivos
16
+ for (const d of currentDevices) {
17
+ if (!previousSerials.has(d.serial)) {
18
+ wsClient.registerDevice(d);
19
+ devices.push(d);
20
+ console.log(chalk_1.default.green(` + Novo dispositivo: ${d.serial} (${d.model})`));
21
+ }
22
+ }
23
+ // Dispositivos removidos
24
+ for (let i = devices.length - 1; i >= 0; i--) {
25
+ if (!currentSerials.has(devices[i].serial)) {
26
+ const removedSerial = devices[i].serial;
27
+ // If recording was active on this device, send error
28
+ recordingManager.handleDeviceRemoved(removedSerial, wsClient);
29
+ wsClient.unregisterDevice(removedSerial);
30
+ console.log(chalk_1.default.red(` - Dispositivo desconectado: ${removedSerial}`));
31
+ devices.splice(i, 1);
32
+ }
33
+ }
34
+ }, intervalMs);
35
+ }
36
+ stop() {
37
+ if (this.pollInterval) {
38
+ clearInterval(this.pollInterval);
39
+ this.pollInterval = null;
40
+ }
41
+ }
42
+ }
43
+ exports.DevicePoller = DevicePoller;
44
+ //# sourceMappingURL=device-poller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-poller.js","sourceRoot":"","sources":["../../src/services/device-poller.ts"],"names":[],"mappings":";;;;;;AAAA,kDAA0B;AAM1B,MAAa,YAAY;IACf,YAAY,GAA0C,IAAI,CAAC;IAEnE,KAAK,CACH,UAAkB,EAClB,QAAyB,EACzB,QAAwB,EACxB,OAAiB,EACjB,gBAAkC;QAElC,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE;YACnC,MAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC;YACzC,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACpE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YAE9D,qBAAqB;YACrB,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;gBAC/B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;oBACnC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;oBAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;oBAChB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;gBAC7E,CAAC;YACH,CAAC;YAED,yBAAyB;YACzB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7C,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC;oBAC3C,MAAM,aAAa,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;oBAExC,qDAAqD;oBACrD,gBAAgB,CAAC,mBAAmB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;oBAE9D,QAAQ,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAC;oBACzC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,iCAAiC,aAAa,EAAE,CAAC,CAAC,CAAC;oBACzE,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACvB,CAAC;YACH,CAAC;QACH,CAAC,EAAE,UAAU,CAAC,CAAC;IACjB,CAAC;IAED,IAAI;QACF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,aAAa,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACjC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAC3B,CAAC;IACH,CAAC;CACF;AA9CD,oCA8CC"}
@@ -0,0 +1,18 @@
1
+ import { Device } from '@testdroid-ai/shared';
2
+ import { WebSocketClient } from '../ws/socket';
3
+ interface ExecutionOptions {
4
+ url: string;
5
+ token: string;
6
+ }
7
+ export declare class ExecutionManager {
8
+ private activeExecutions;
9
+ private pollTimer;
10
+ setupListeners(wsClient: WebSocketClient, devices: Device[], options: ExecutionOptions): void;
11
+ private handleQueuedRun;
12
+ cleanup(): void;
13
+ private apiFetch;
14
+ private apiPost;
15
+ }
16
+ export declare function extractAppPackageFromCode(code: string): string;
17
+ export {};
18
+ //# sourceMappingURL=execution-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-manager.d.ts","sourceRoot":"","sources":["../../src/services/execution-manager.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAK/C,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,SAAS,CAA+C;IAEhE,cAAc,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI;YAyB/E,eAAe;IAoG7B,OAAO,IAAI,IAAI;IAQf,OAAO,CAAC,QAAQ;IAsBhB,OAAO,CAAC,OAAO;CAqBhB;AAED,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAG9D"}