@xenon-device-management/xenon 1.1.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.
Files changed (228) hide show
  1. package/README.md +446 -0
  2. package/lib/package.json +207 -0
  3. package/lib/public/assets/Layouts-7IT8aFLI.js +11 -0
  4. package/lib/public/assets/Layouts-DPMls9vh.css +1 -0
  5. package/lib/public/assets/ai-settings-BbnfgdEx.js +11 -0
  6. package/lib/public/assets/apps-CRMrI4_p.js +16 -0
  7. package/lib/public/assets/apps-CcM77dgg.css +1 -0
  8. package/lib/public/assets/badge-B1nKs8zj.css +1 -0
  9. package/lib/public/assets/badge-CSvl5xIU.js +11 -0
  10. package/lib/public/assets/button-CJlKn4PZ.css +1 -0
  11. package/lib/public/assets/button-CvLaGFYj.js +26 -0
  12. package/lib/public/assets/calendar-6w-D6Oaw.js +6 -0
  13. package/lib/public/assets/clock-DcdeWBPr.js +6 -0
  14. package/lib/public/assets/cpu-DiSoXT9n.js +6 -0
  15. package/lib/public/assets/device-explorer-CajM63OJ.js +193 -0
  16. package/lib/public/assets/device-explorer-CxdUAoTL.css +1 -0
  17. package/lib/public/assets/index-ByQwMN5T.js +174 -0
  18. package/lib/public/assets/index-C1DBaoSh.js +1 -0
  19. package/lib/public/assets/index-qzCez_kk.css +1 -0
  20. package/lib/public/assets/lock-B23ibZmo.js +6 -0
  21. package/lib/public/assets/maintenance-settings-CirzA6yG.js +6 -0
  22. package/lib/public/assets/mouse-pointer-2-Cz76SHFb.js +6 -0
  23. package/lib/public/assets/plus-BBwlIevt.js +6 -0
  24. package/lib/public/assets/session-dashboard-C2k7FFv_.css +1 -0
  25. package/lib/public/assets/session-dashboard-HPDtwPOZ.js +62 -0
  26. package/lib/public/assets/settings-DrZsZwdc.js +1 -0
  27. package/lib/public/assets/trash-2-DQpvzJec.js +6 -0
  28. package/lib/public/assets/useSocket-Dxsqae2a.js +16 -0
  29. package/lib/public/assets/webhook-settings-CDPgsgkb.css +1 -0
  30. package/lib/public/assets/webhook-settings-Cp-B4Nrw.js +1 -0
  31. package/lib/public/assets/zap-DovP6iow.js +6 -0
  32. package/lib/public/favicon.ico +0 -0
  33. package/lib/public/favicon.png +0 -0
  34. package/lib/public/favicon.svg +9 -0
  35. package/lib/public/index.html +46 -0
  36. package/lib/public/logo.svg +17 -0
  37. package/lib/public/logo192.png +0 -0
  38. package/lib/public/logo512.png +0 -0
  39. package/lib/public/manifest.json +25 -0
  40. package/lib/public/robots.txt +3 -0
  41. package/lib/schema.json +348 -0
  42. package/lib/src/InternalHttpClient.js +212 -0
  43. package/lib/src/PluginContext.js +29 -0
  44. package/lib/src/XenonCapabilityManager.js +199 -0
  45. package/lib/src/app/index.js +167 -0
  46. package/lib/src/app/routers/apps.js +79 -0
  47. package/lib/src/app/routers/config.js +131 -0
  48. package/lib/src/app/routers/control.js +835 -0
  49. package/lib/src/app/routers/dashboard.js +301 -0
  50. package/lib/src/app/routers/grid.js +352 -0
  51. package/lib/src/app/routers/reservation.js +190 -0
  52. package/lib/src/app/routers/webhook.js +83 -0
  53. package/lib/src/app/swagger-docs.js +203 -0
  54. package/lib/src/app/swagger.js +366 -0
  55. package/lib/src/chromeUtils.js +148 -0
  56. package/lib/src/commands/handle.js +19 -0
  57. package/lib/src/commands/index.js +8 -0
  58. package/lib/src/config.js +73 -0
  59. package/lib/src/dashboard/asset-manager.js +84 -0
  60. package/lib/src/dashboard/commands.js +284 -0
  61. package/lib/src/dashboard/event-manager.js +699 -0
  62. package/lib/src/dashboard/services/app-service.js +134 -0
  63. package/lib/src/dashboard/services/failure-analysis-service.js +173 -0
  64. package/lib/src/dashboard/services/session-service.js +113 -0
  65. package/lib/src/data-service/CircuitBreaker.js +83 -0
  66. package/lib/src/data-service/config-service.js +155 -0
  67. package/lib/src/data-service/db.js +122 -0
  68. package/lib/src/data-service/device-service.js +320 -0
  69. package/lib/src/data-service/device-store.interface.js +2 -0
  70. package/lib/src/data-service/device-store.js +345 -0
  71. package/lib/src/data-service/pending-sessions-service.js +25 -0
  72. package/lib/src/data-service/pluginArgs.js +25 -0
  73. package/lib/src/data-service/prisma-service.js +31 -0
  74. package/lib/src/data-service/prisma-store.js +385 -0
  75. package/lib/src/data-service/queue-service.js +150 -0
  76. package/lib/src/data-service/web-config-service.js +130 -0
  77. package/lib/src/device-managers/AndroidDeviceManager.js +1155 -0
  78. package/lib/src/device-managers/ChromeDriverManager.js +68 -0
  79. package/lib/src/device-managers/HealthMonitorService.js +325 -0
  80. package/lib/src/device-managers/IOSDeviceManager.js +351 -0
  81. package/lib/src/device-managers/NodeDevices.js +82 -0
  82. package/lib/src/device-managers/android/AndroidStreamService.js +370 -0
  83. package/lib/src/device-managers/android/DeviceLockManager.js +45 -0
  84. package/lib/src/device-managers/cloud/CapabilityManager.js +26 -0
  85. package/lib/src/device-managers/cloud/Devices.js +86 -0
  86. package/lib/src/device-managers/iOSTracker.js +44 -0
  87. package/lib/src/device-managers/index.js +89 -0
  88. package/lib/src/device-managers/ios/IOSDiscoveryService.js +268 -0
  89. package/lib/src/device-managers/ios/IOSStreamService.js +893 -0
  90. package/lib/src/device-managers/ios/WDAClient.js +866 -0
  91. package/lib/src/device-utils.js +663 -0
  92. package/lib/src/enums/Capabilities.js +8 -0
  93. package/lib/src/enums/Cloud.js +11 -0
  94. package/lib/src/enums/Platform.js +9 -0
  95. package/lib/src/enums/SessionType.js +9 -0
  96. package/lib/src/enums/SocketEvents.js +15 -0
  97. package/lib/src/helpers/UniversalMjpegProxy.js +273 -0
  98. package/lib/src/helpers/index.js +229 -0
  99. package/lib/src/index.js +95 -0
  100. package/lib/src/interceptors/CommandInterceptor.js +524 -0
  101. package/lib/src/interfaces/ICloudManager.js +2 -0
  102. package/lib/src/interfaces/IDevice.js +2 -0
  103. package/lib/src/interfaces/IDeviceFilterOptions.js +2 -0
  104. package/lib/src/interfaces/IDeviceManager.js +2 -0
  105. package/lib/src/interfaces/IOptions.js +2 -0
  106. package/lib/src/interfaces/IPluginArgs.js +55 -0
  107. package/lib/src/interfaces/ISessionCapability.js +2 -0
  108. package/lib/src/logger.js +225 -0
  109. package/lib/src/plugin.js +244 -0
  110. package/lib/src/prisma.js +12 -0
  111. package/lib/src/profiling/AndroidAppProfiler.js +213 -0
  112. package/lib/src/proxy/wd-command-proxy.js +221 -0
  113. package/lib/src/scripts/generate-database-migration.js +59 -0
  114. package/lib/src/scripts/initialize-database.js +55 -0
  115. package/lib/src/scripts/install-go-ios.js +66 -0
  116. package/lib/src/scripts/prepare-prisma.js +89 -0
  117. package/lib/src/services/AICommandService.js +143 -0
  118. package/lib/src/services/AIService.js +466 -0
  119. package/lib/src/services/CleanupService.js +141 -0
  120. package/lib/src/services/EventBus.js +74 -0
  121. package/lib/src/services/InspectorService.js +395 -0
  122. package/lib/src/services/MetricsService.js +134 -0
  123. package/lib/src/services/NetworkConditioningService.js +173 -0
  124. package/lib/src/services/NotificationService.js +163 -0
  125. package/lib/src/services/RequestLogService.js +252 -0
  126. package/lib/src/services/ResourceIsolationService.js +122 -0
  127. package/lib/src/services/SecurityService.js +120 -0
  128. package/lib/src/services/ServerManager.js +284 -0
  129. package/lib/src/services/SessionHeartbeatService.js +158 -0
  130. package/lib/src/services/SessionLifecycleService.js +572 -0
  131. package/lib/src/services/SocketClient.js +71 -0
  132. package/lib/src/services/SocketServer.js +87 -0
  133. package/lib/src/services/TracingService.js +132 -0
  134. package/lib/src/services/VideoPipelineService.js +220 -0
  135. package/lib/src/services/healing/FuzzyXmlHealingProvider.js +333 -0
  136. package/lib/src/services/healing/HealEtalonService.js +98 -0
  137. package/lib/src/services/healing/HealedLocatorGenerator.js +132 -0
  138. package/lib/src/services/healing/HealingOrchestrator.js +165 -0
  139. package/lib/src/services/healing/LlmHealingProvider.js +77 -0
  140. package/lib/src/services/healing/OcrHealingProvider.js +119 -0
  141. package/lib/src/services/healing/ResilioTreeHealingProvider.js +100 -0
  142. package/lib/src/services/healing/VisualAiHealingProvider.js +90 -0
  143. package/lib/src/services/healing/types.js +12 -0
  144. package/lib/src/services/omni-vision/OmniVisionService.js +718 -0
  145. package/lib/src/services/omni-vision/VisionAssertionService.js +68 -0
  146. package/lib/src/sessions/CloudSession.js +42 -0
  147. package/lib/src/sessions/LocalSession.js +313 -0
  148. package/lib/src/sessions/RemoteSession.js +287 -0
  149. package/lib/src/sessions/SessionManager.js +238 -0
  150. package/lib/src/sessions/XenonSession.js +44 -0
  151. package/lib/src/types/CLIArgs.js +2 -0
  152. package/lib/src/types/CloudArgs.js +2 -0
  153. package/lib/src/types/CloudSchema.js +131 -0
  154. package/lib/src/types/DeviceType.js +2 -0
  155. package/lib/src/types/DeviceUpdate.js +2 -0
  156. package/lib/src/types/IOSDevice.js +2 -0
  157. package/lib/src/types/Platform.js +2 -0
  158. package/lib/src/types/SessionStatus.js +11 -0
  159. package/lib/src/validators/CapabilityValidator.js +93 -0
  160. package/lib/test/e2e/android/conf.spec.js +43 -0
  161. package/lib/test/e2e/android/conf2.spec.js +44 -0
  162. package/lib/test/e2e/android/conf3.spec.js +44 -0
  163. package/lib/test/e2e/e2ehelper.js +113 -0
  164. package/lib/test/e2e/hubnode/forward-request.spec.js +224 -0
  165. package/lib/test/e2e/hubnode/hubnode.spec.js +214 -0
  166. package/lib/test/e2e/ios/conf1.spec.js +39 -0
  167. package/lib/test/e2e/ios/conf2.spec.js +39 -0
  168. package/lib/test/e2e/plugin-harness.js +236 -0
  169. package/lib/test/e2e/plugin.spec.js +97 -0
  170. package/lib/test/e2e/telemetry_verification.spec.js +83 -0
  171. package/lib/test/e2e/video-recording-test.spec.js +63 -0
  172. package/lib/test/helpers/test-container.js +112 -0
  173. package/lib/test/integration/androidDevices.spec.js +137 -0
  174. package/lib/test/integration/cliArgs.js +73 -0
  175. package/lib/test/integration/ios/01iOSSimulator.spec.js +291 -0
  176. package/lib/test/integration/ios/02iOSDevices.spec.js +75 -0
  177. package/lib/test/integration/testHelpers.js +74 -0
  178. package/lib/test/unit/AndroidDeviceManager.spec.js +178 -0
  179. package/lib/test/unit/ChromeDriverManager.spec.js +26 -0
  180. package/lib/test/unit/CleanupService.spec.js +21 -0
  181. package/lib/test/unit/DeviceModel.spec.js +157 -0
  182. package/lib/test/unit/FuzzyXmlHealingProvider.test.js +294 -0
  183. package/lib/test/unit/GetAdbOriginal.js +42 -0
  184. package/lib/test/unit/HealingCascade.test.js +128 -0
  185. package/lib/test/unit/IOSDeviceManager.spec.js +261 -0
  186. package/lib/test/unit/RemoteIOs.spec.js +78 -0
  187. package/lib/test/unit/ResilioTreeHealingProvider.test.js +96 -0
  188. package/lib/test/unit/commands.spec.js +27 -0
  189. package/lib/test/unit/config.spec.js +27 -0
  190. package/lib/test/unit/device-service.spec.js +307 -0
  191. package/lib/test/unit/device-utils.spec.js +313 -0
  192. package/lib/test/unit/fixtures/device.config.js +4 -0
  193. package/lib/test/unit/fixtures/devices.js +89 -0
  194. package/lib/test/unit/helpers.spec.js +62 -0
  195. package/lib/test/unit/omni-vision.spec.js +100 -0
  196. package/lib/test/unit/plugin.spec.js +133 -0
  197. package/lib/tsconfig.tsbuildinfo +1 -0
  198. package/package.json +207 -0
  199. package/prisma/data.db +0 -0
  200. package/prisma/dev.db +0 -0
  201. package/prisma/dev.db-journal +0 -0
  202. package/prisma/migrations/20231011074725_initial_tables/migration.sql +47 -0
  203. package/prisma/migrations/20231226115334_update_session_log/migration.sql +2 -0
  204. package/prisma/migrations/20251204113710_add_video_recording_enabled/migration.sql +29 -0
  205. package/prisma/migrations/20251204132449_add_log_table/migration.sql +11 -0
  206. package/prisma/migrations/20251205050111_add_profiling_support/migration.sql +47 -0
  207. package/prisma/migrations/20251205050947_add_is_error_field/migration.sql +24 -0
  208. package/prisma/migrations/20260126201337_add_app_model/migration.sql +18 -0
  209. package/prisma/migrations/20260130115722_add_performance_trace_and_xenon_sync/migration.sql +2 -0
  210. package/prisma/migrations/20260130135114_add_device_models/migration.sql +57 -0
  211. package/prisma/migrations/20260130140655_make_systemport_optional/migration.sql +45 -0
  212. package/prisma/migrations/20260130140932_make_device_fields_optional/migration.sql +45 -0
  213. package/prisma/migrations/20260130141040_final_schema_fix/migration.sql +45 -0
  214. package/prisma/migrations/20260130143234_add_device_health_fields/migration.sql +4 -0
  215. package/prisma/migrations/20260130144921_add_failure_category/migration.sql +2 -0
  216. package/prisma/migrations/20260131151456_add_webhook_config/migration.sql +10 -0
  217. package/prisma/migrations/20260201094507_add_device_tags/migration.sql +11 -0
  218. package/prisma/migrations/20260201103410_add_managed_process/migration.sql +15 -0
  219. package/prisma/migrations/20260201140637_add_web_config/migration.sql +22 -0
  220. package/prisma/migrations/20260201162232_add_session_progress/migration.sql +2 -0
  221. package/prisma/migrations/20260201174231_add_total_healed_count/migration.sql +2 -0
  222. package/prisma/migrations/migration_lock.toml +3 -0
  223. package/prisma/schema.prisma +210 -0
  224. package/schema.json +348 -0
  225. package/scripts/build-xenon.sh +32 -0
  226. package/scripts/dev/debug-gemini.ts +44 -0
  227. package/scripts/generate-types-from-schema.js +86 -0
  228. package/scripts/install-compatible-driver.js +39 -0
@@ -0,0 +1,268 @@
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 __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
19
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
20
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
21
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
22
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
23
+ };
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ var __metadata = (this && this.__metadata) || function (k, v) {
42
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
43
+ };
44
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
45
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
46
+ return new (P || (P = Promise))(function (resolve, reject) {
47
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
48
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
49
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
50
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
51
+ });
52
+ };
53
+ var __importDefault = (this && this.__importDefault) || function (mod) {
54
+ return (mod && mod.__esModule) ? mod : { "default": mod };
55
+ };
56
+ Object.defineProperty(exports, "__esModule", { value: true });
57
+ exports.IOSDiscoveryService = void 0;
58
+ const node_simctl_1 = __importDefault(require("node-simctl"));
59
+ const lodash_1 = require("lodash");
60
+ const appium_ios_device_1 = require("appium-ios-device");
61
+ const helpers_1 = require("../../helpers");
62
+ const logger_1 = __importDefault(require("../../logger"));
63
+ const path_1 = __importDefault(require("path"));
64
+ const fs_extra_1 = __importDefault(require("fs-extra"));
65
+ const device_utils_1 = require("../../device-utils");
66
+ const device_store_1 = require("../../data-service/device-store");
67
+ const PluginContext_1 = require("../../PluginContext");
68
+ const typedi_1 = require("typedi");
69
+ const Devices_1 = __importDefault(require("../cloud/Devices"));
70
+ const NodeDevices_1 = __importDefault(require("../NodeDevices"));
71
+ const device_service_1 = require("../../data-service/device-service");
72
+ const iOSTracker_1 = require("../iOSTracker");
73
+ let IOSDiscoveryService = class IOSDiscoveryService {
74
+ constructor(context) {
75
+ this.context = context;
76
+ this.log = logger_1.default.scope('IOSDiscovery');
77
+ this.trackingInitialized = false;
78
+ }
79
+ get pluginArgs() {
80
+ return this.context.pluginArgs;
81
+ }
82
+ get hostPort() {
83
+ return this.context.port;
84
+ }
85
+ get nodeId() {
86
+ return this.context.nodeId;
87
+ }
88
+ getDevices(deviceTypes, existingDeviceDetails) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ if (deviceTypes.iosDeviceType === 'real') {
91
+ return (0, lodash_1.flatten)(yield Promise.all([this.getRealDevices(existingDeviceDetails)]));
92
+ }
93
+ else if (deviceTypes.iosDeviceType === 'simulated') {
94
+ return yield this.getSimulators();
95
+ }
96
+ else {
97
+ return (0, lodash_1.flatten)(yield Promise.all([this.getRealDevices(existingDeviceDetails), this.getSimulators()]));
98
+ }
99
+ });
100
+ }
101
+ getConnectedDevices() {
102
+ return __awaiter(this, void 0, void 0, function* () {
103
+ try {
104
+ return yield appium_ios_device_1.utilities.getConnectedDevices();
105
+ }
106
+ catch (error) {
107
+ this.log.error(error);
108
+ return [];
109
+ }
110
+ });
111
+ }
112
+ getRealDevices(existingDeviceDetails) {
113
+ return __awaiter(this, void 0, void 0, function* () {
114
+ var _a;
115
+ let deviceState = [];
116
+ if ((_a = this.pluginArgs.cloud) === null || _a === void 0 ? void 0 : _a.cloudName) {
117
+ const cloud = new Devices_1.default(this.pluginArgs.cloud, deviceState, 'ios');
118
+ return yield cloud.getDevices();
119
+ }
120
+ else {
121
+ deviceState = yield this.fetchLocalIOSDevices(existingDeviceDetails);
122
+ }
123
+ return deviceState.filter((device) => device.realDevice === true);
124
+ });
125
+ }
126
+ fetchLocalIOSDevices(existingDeviceDetails) {
127
+ return __awaiter(this, void 0, void 0, function* () {
128
+ if (process.env.NODE_ENV === 'test') {
129
+ console.log('[POISON PILL] REAL fetchLocalIOSDevices CALLED IN TEST MODE!');
130
+ }
131
+ const devices = yield this.getConnectedDevices();
132
+ const deviceProcessingPromises = devices.map((udid) => __awaiter(this, void 0, void 0, function* () {
133
+ try {
134
+ const existingDevice = existingDeviceDetails.find((device) => device.udid === udid);
135
+ if (existingDevice) {
136
+ return Object.assign({}, existingDevice);
137
+ }
138
+ else {
139
+ return yield this.getDeviceInfo(udid);
140
+ }
141
+ }
142
+ catch (e) {
143
+ this.log.error(`Failed to initialize iOS device ${udid}: ${e.message}`);
144
+ return null;
145
+ }
146
+ }));
147
+ const deviceState = (yield Promise.all(deviceProcessingPromises)).filter((d) => d !== null);
148
+ if (!this.trackingInitialized && process.env.NODE_ENV !== 'test') {
149
+ this.trackIOSDevices();
150
+ }
151
+ return deviceState;
152
+ });
153
+ }
154
+ getDeviceInfo(udid) {
155
+ return __awaiter(this, void 0, void 0, function* () {
156
+ const store = device_store_1.DeviceStoreFactory.getStore();
157
+ const storeDevice = yield store.findDevice({ udid });
158
+ const host = this.pluginArgs.remoteMachineProxyIP
159
+ ? String(this.pluginArgs.remoteMachineProxyIP)
160
+ : `http://${this.pluginArgs.bindHostOrIp}:${this.hostPort}`;
161
+ const wdaLocalPort = (storeDevice === null || storeDevice === void 0 ? void 0 : storeDevice.wdaLocalPort) || (yield (0, helpers_1.getFreePort)());
162
+ const mjpegServerPort = (storeDevice === null || storeDevice === void 0 ? void 0 : storeDevice.mjpegServerPort) || (yield (0, helpers_1.getFreePort)());
163
+ const totalUtilizationTimeMilliSec = yield (0, device_utils_1.getUtilizationTime)(udid);
164
+ let sdk = 'Unknown';
165
+ let name = 'iPhone';
166
+ let ip = '';
167
+ try {
168
+ [sdk, name] = yield Promise.all([appium_ios_device_1.utilities.getOSVersion(udid), appium_ios_device_1.utilities.getDeviceName(udid)]);
169
+ // Principal Intelligence: Fetch network IP for health resilience
170
+ const goIOSDir = (0, helpers_1.cachePath)('goIOS');
171
+ const goIOSPath = path_1.default.join(goIOSDir, 'ios');
172
+ if (fs_extra_1.default.existsSync(goIOSPath)) {
173
+ const { exec } = yield Promise.resolve().then(() => __importStar(require('child_process')));
174
+ const { promisify } = yield Promise.resolve().then(() => __importStar(require('util')));
175
+ const execPromise = promisify(exec);
176
+ try {
177
+ const { stdout } = yield execPromise(`"${goIOSPath}" info --udid ${udid}`, {
178
+ env: Object.assign(Object.assign({}, process.env), { ENABLE_GO_IOS_AGENT: 'yes' }),
179
+ });
180
+ const info = JSON.parse(stdout);
181
+ ip = info.IPAddress || '';
182
+ }
183
+ catch (e) {
184
+ logger_1.default.debug(`Failed to fetch IP via go-ios for ${udid}: ${e}`);
185
+ }
186
+ }
187
+ }
188
+ catch (e) {
189
+ this.log.error(`Metadata discovery failed for ${udid}: ${e.message}`);
190
+ }
191
+ return Object.assign({ wdaLocalPort,
192
+ mjpegServerPort,
193
+ udid,
194
+ sdk,
195
+ name,
196
+ ip, busy: false, realDevice: true, deviceType: 'real', platform: (name.toLowerCase().includes('tv') ? 'tvos' : 'ios'), host: host, totalUtilizationTimeMilliSec, sessionStartTime: 0, state: (storeDevice === null || storeDevice === void 0 ? void 0 : storeDevice.state) || 'Unknown', userBlocked: (storeDevice === null || storeDevice === void 0 ? void 0 : storeDevice.userBlocked) || false }, (storeDevice || {}));
197
+ });
198
+ }
199
+ getSimulators() {
200
+ return __awaiter(this, void 0, void 0, function* () {
201
+ const simulators = yield this.fetchLocalSimulators();
202
+ simulators.sort((a, b) => (a.state > b.state ? 1 : -1));
203
+ if (this.pluginArgs.hub !== undefined) {
204
+ const nodeDevices = new NodeDevices_1.default(this.pluginArgs.hub, this.pluginArgs.tlsRejectUnauthorized);
205
+ yield nodeDevices.postDevicesToHub(simulators, 'add');
206
+ }
207
+ return simulators;
208
+ });
209
+ }
210
+ fetchLocalSimulators() {
211
+ return __awaiter(this, void 0, void 0, function* () {
212
+ if (process.env.NODE_ENV === 'test') {
213
+ console.log('[POISON PILL] REAL fetchLocalSimulators CALLED IN TEST MODE!');
214
+ }
215
+ const simctl = new node_simctl_1.default();
216
+ const list = yield simctl.list();
217
+ // Log unavailable runtimes
218
+ list.runtimes
219
+ .filter((r) => !r.isAvailable)
220
+ .forEach((r) => this.log.error(`Runtime not available: ${r.name}`));
221
+ const iosSims = (0, lodash_1.flatten)(Object.values((yield simctl.getDevicesByParsing('iOS'))));
222
+ const tvosSims = (0, lodash_1.flatten)(Object.values((yield simctl.getDevicesByParsing('tvOS'))));
223
+ let simulators = [...iosSims, ...tvosSims];
224
+ if (this.pluginArgs.bootedSimulators) {
225
+ simulators = simulators.filter((d) => d.state === 'Booted');
226
+ }
227
+ const localPluginArgs = this.pluginArgs;
228
+ if (localPluginArgs.simulators && localPluginArgs.simulators.length > 0) {
229
+ const allowedSimulators = localPluginArgs.simulators;
230
+ simulators = simulators.filter((d) => allowedSimulators.some((s) => d.name === s.name && d.sdk === s.sdk));
231
+ }
232
+ return yield Promise.all(simulators.map((d) => __awaiter(this, void 0, void 0, function* () {
233
+ var _a;
234
+ return (Object.assign(Object.assign({}, d), { wdaLocalPort: yield (0, helpers_1.getFreePort)(), mjpegServerPort: yield (0, helpers_1.getFreePort)(), busy: false, realDevice: false, platform: (((_a = d.name) === null || _a === void 0 ? void 0 : _a.toLowerCase().includes('tv')) ? 'tvos' : 'ios'), deviceType: 'simulator', host: `http://${this.pluginArgs.bindHostOrIp}:${this.hostPort}`, totalUtilizationTimeMilliSec: yield (0, device_utils_1.getUtilizationTime)(d.udid), sessionStartTime: 0 }));
235
+ })));
236
+ });
237
+ }
238
+ trackIOSDevices() {
239
+ if (this.trackingInitialized)
240
+ return;
241
+ this.trackingInitialized = true;
242
+ const tracker = typedi_1.Container.get(iOSTracker_1.IosTracker).getListener();
243
+ tracker.on('attached', (udid) => __awaiter(this, void 0, void 0, function* () {
244
+ try {
245
+ const device = Object.assign(Object.assign({}, (yield this.getDeviceInfo(udid))), { nodeId: this.nodeId });
246
+ if (this.pluginArgs.hub) {
247
+ yield new NodeDevices_1.default(this.pluginArgs.hub, this.pluginArgs.tlsRejectUnauthorized).postDevicesToHub([device], 'add');
248
+ }
249
+ yield (0, device_service_1.addNewDevice)([device], this.pluginArgs.bindHostOrIp);
250
+ }
251
+ catch (e) {
252
+ this.log.error(`Attach failed for ${udid}: ${e.message}`);
253
+ }
254
+ }));
255
+ tracker.on('detached', (udid) => __awaiter(this, void 0, void 0, function* () {
256
+ const deviceRemoved = [{ udid, host: this.pluginArgs.bindHostOrIp }];
257
+ if (this.pluginArgs.hub) {
258
+ yield new NodeDevices_1.default(this.pluginArgs.hub, this.pluginArgs.tlsRejectUnauthorized).postDevicesToHub(deviceRemoved, 'remove');
259
+ }
260
+ yield (0, device_service_1.removeDevice)(deviceRemoved);
261
+ }));
262
+ }
263
+ };
264
+ exports.IOSDiscoveryService = IOSDiscoveryService;
265
+ exports.IOSDiscoveryService = IOSDiscoveryService = __decorate([
266
+ (0, typedi_1.Service)(),
267
+ __metadata("design:paramtypes", [PluginContext_1.PluginContext])
268
+ ], IOSDiscoveryService);