@xenon-device-management/xenon 2.13.2 → 2.15.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 (350) hide show
  1. package/README.md +17 -8
  2. package/lib/package.json +5 -5
  3. package/lib/public/assets/{AnnotationOverlay-BXruClDk.js → AnnotationOverlay-Btq3dZRI.js} +1 -1
  4. package/lib/public/assets/{ApiKeyGate-qTS4LPLC.js → ApiKeyGate-C9OoAgg_.js} +1 -1
  5. package/lib/public/assets/DeviceMosaicView-DBC_xczB.js +2 -0
  6. package/lib/public/assets/{EmptyState-Cr17PdDv.js → EmptyState-DqWU2-vM.js} +1 -1
  7. package/lib/public/assets/{FieldGroup-Bvn08svv.js → FieldGroup-CveQ3xrA.js} +1 -1
  8. package/lib/public/assets/{FilterMenu-DDSO8aDf.js → FilterMenu-BfKDSfHz.js} +1 -1
  9. package/lib/public/assets/{Menu-B-Qn2X3T.js → Menu-CtdCybzA.js} +1 -1
  10. package/lib/public/assets/{Modal-Cg9V5JYU.js → Modal-Bsvj1tm2.js} +1 -1
  11. package/lib/public/assets/{RecordingPage-BTUs9VTW.js → RecordingPage-CRofOiyx.js} +1 -1
  12. package/lib/public/assets/{RecordingsPage-DYcfxITK.js → RecordingsPage-jNQHb2IR.js} +2 -2
  13. package/lib/public/assets/{SegmentedControl-Zy7suhT5.js → SegmentedControl-C8HtTha-.js} +1 -1
  14. package/lib/public/assets/{SettingCard-CWYmycoe.js → SettingCard-D8K1LZNo.js} +1 -1
  15. package/lib/public/assets/{Table-io9fwa98.js → Table-zNTX92Pn.js} +1 -1
  16. package/lib/public/assets/{activity-Bdf_uIWl.js → activity-CJ8LwZq9.js} +1 -1
  17. package/lib/public/assets/ai-settings-CgxQZqrc.js +16 -0
  18. package/lib/public/assets/{api-keys-CPqtVpm3.js → api-keys-ECpo-zTo.js} +1 -1
  19. package/lib/public/assets/{apps-BgZan0H9.js → apps-BjGymyf3.js} +2 -2
  20. package/lib/public/assets/{arrow-left-B27ckB31.js → arrow-left-BWfCbeHP.js} +1 -1
  21. package/lib/public/assets/{arrow-right-DOF8ITCz.js → arrow-right-DC7UGf_n.js} +1 -1
  22. package/lib/public/assets/{arrow-up-right-eFG5KTFS.js → arrow-up-right-BOjwybDk.js} +1 -1
  23. package/lib/public/assets/{auth-shell-DlC3_27j.js → auth-shell-CxMTo9aH.js} +2 -2
  24. package/lib/public/assets/{builds-page-BuXpPfKo.js → builds-page-DOCm4HkA.js} +1 -1
  25. package/lib/public/assets/{button-fIW8owMI.js → button-Cg08-EMT.js} +1 -1
  26. package/lib/public/assets/{calendar-WNjmrF-a.js → calendar-CA1ikLJs.js} +1 -1
  27. package/lib/public/assets/{check-BdTh1Sq7.js → check-BMTaH72W.js} +1 -1
  28. package/lib/public/assets/{chevron-right-B4BKlsqk.js → chevron-right-B2QOv9Nx.js} +1 -1
  29. package/lib/public/assets/{circle-check-zJU80_EF.js → circle-check-CYXBoUqT.js} +1 -1
  30. package/lib/public/assets/{circle-x-5Uwquo0h.js → circle-x-DTwnSAnl.js} +1 -1
  31. package/lib/public/assets/{clock-BtUprDsZ.js → clock-C8_HViQP.js} +1 -1
  32. package/lib/public/assets/{copy-DGSbZI3u.js → copy-Be7LNMXV.js} +1 -1
  33. package/lib/public/assets/derive-UnLRp4r3.js +1 -0
  34. package/lib/public/assets/device-explorer-BOqtfGXz.js +282 -0
  35. package/lib/public/assets/{download-WG6l7BgD.js → download-B56lwxWP.js} +1 -1
  36. package/lib/public/assets/forgot-password-CCU6bzLn.js +1 -0
  37. package/lib/public/assets/h264Stream-C-OtmIuk.js +26 -0
  38. package/lib/public/assets/index-B9KQ6LsY.js +15 -0
  39. package/lib/public/assets/{index-DI1fGIyj.js → index-BOxe43p1.js} +5 -5
  40. package/lib/public/assets/{index-HDQVe1gi.js → index-CfxsUslp.js} +1 -1
  41. package/lib/public/assets/{input-BjDRKCea.js → input-CZHFjbSg.js} +1 -1
  42. package/lib/public/assets/{line-chart-C0zdgd0v.js → line-chart-Gl_Dz3X_.js} +1 -1
  43. package/lib/public/assets/{list-checks-BdW5CjM8.js → list-checks-CCgjeyGY.js} +1 -1
  44. package/lib/public/assets/{lock-Dy3L4I8E.js → lock-CkOwgDcx.js} +1 -1
  45. package/lib/public/assets/{login-BHbY9CLG.js → login-D5cc4w7M.js} +1 -1
  46. package/lib/public/assets/maintenance-settings-t7qr3fvX.js +6 -0
  47. package/lib/public/assets/{monitor-8xjkeHHi.js → monitor-DEJixKQO.js} +1 -1
  48. package/lib/public/assets/{mouse-pointer-2-CXdKMXQ8.js → mouse-pointer-2-CtOrk4M8.js} +1 -1
  49. package/lib/public/assets/{network-Cj8JOKON.js → network-Dii9qdvk.js} +1 -1
  50. package/lib/public/assets/{overview-CTg7F0im.js → overview-rolAACrO.js} +1 -1
  51. package/lib/public/assets/{page-header--aTyJXq6.js → page-header-COQZxJfR.js} +1 -1
  52. package/lib/public/assets/{play-B-FodgHV.js → play-DrN1Se_R.js} +1 -1
  53. package/lib/public/assets/{plus-CsIk10Cq.js → plus-5aq-9uRx.js} +1 -1
  54. package/lib/public/assets/{profile-page-DkFKkMfl.js → profile-page-6i5kY6kF.js} +1 -1
  55. package/lib/public/assets/{reset-password-I2-zqLlI.js → reset-password-sp2IBrc7.js} +1 -1
  56. package/lib/public/assets/runbook-page-DJDjeopU.js +253 -0
  57. package/lib/public/assets/{select-DvCSv25z.js → select-Bpyn7rWO.js} +1 -1
  58. package/lib/public/assets/{selector-detail-redirect-BLVfMJs_.js → selector-detail-redirect-BH74vmKv.js} +1 -1
  59. package/lib/public/assets/{selector-health-page-oqadRokn.js → selector-health-page-Cw_g218H.js} +2 -2
  60. package/lib/public/assets/session-detail-page-AZJE6XXE.js +4 -0
  61. package/lib/public/assets/settings-C3uyGhyc.js +6 -0
  62. package/lib/public/assets/{settings-Dep_3kbA.css → settings-K8UHWMdI.css} +1 -1
  63. package/lib/public/assets/{stat-tile-DV9Ix-4O.js → stat-tile-xVqAKIlI.js} +1 -1
  64. package/lib/public/assets/{tablet-6b_SEN2X.js → tablet-BxUScAeO.js} +1 -1
  65. package/lib/public/assets/{teams-BjZyfuHh.js → teams-B5ljGkY2.js} +1 -1
  66. package/lib/public/assets/{trash-2-CTZpPSdd.js → trash-2-B701i8sy.js} +1 -1
  67. package/lib/public/assets/{upload-P3XzwQUb.js → upload-C2gr44RS.js} +1 -1
  68. package/lib/public/assets/{use-builds-data-1cOCMf-z.js → use-builds-data-NeQOFEoy.js} +1 -1
  69. package/lib/public/assets/{use-password-reset-mode-DgF9w088.js → use-password-reset-mode-DEzJq5ef.js} +1 -1
  70. package/lib/public/assets/{users-DMF9Mk5H.js → users-D_vv_yz4.js} +1 -1
  71. package/lib/public/assets/{users-CiNTKUiz.js → users-MY6eNe6s.js} +1 -1
  72. package/lib/public/assets/{video-off-CHp1KU_T.js → video-off-OK1lNZQn.js} +1 -1
  73. package/lib/public/assets/webhook-settings-BU-C9lBf.js +1 -0
  74. package/lib/public/assets/{zap-DRz0tDq5.js → zap-DO9ry1iz.js} +1 -1
  75. package/lib/public/index.html +1 -1
  76. package/lib/schema.json +23 -25
  77. package/lib/src/XenonCapabilityManager.js +22 -5
  78. package/lib/src/app/dashboardPluginLink.js +117 -0
  79. package/lib/src/app/index.js +13 -34
  80. package/lib/src/app/openapi/control.yaml +73 -20
  81. package/lib/src/app/openapi/grid.yaml +31 -7
  82. package/lib/src/app/openapi/identity.yaml +103 -31
  83. package/lib/src/app/openapi/platform.yaml +165 -39
  84. package/lib/src/app/openapi/sessions.yaml +10 -3
  85. package/lib/src/app/routers/apikeys.js +14 -2
  86. package/lib/src/app/routers/auth.js +29 -5
  87. package/lib/src/app/routers/control.js +20 -2
  88. package/lib/src/app/routers/dashboard.js +69 -26
  89. package/lib/src/app/routers/grid.js +37 -13
  90. package/lib/src/app/routers/profile.js +21 -0
  91. package/lib/src/app/routers/streamType.js +7 -2
  92. package/lib/src/app/routers/users.js +10 -5
  93. package/lib/src/app/routers/webhook.js +8 -4
  94. package/lib/src/app/swagger.js +2 -0
  95. package/lib/src/app/ws/h264StreamWs.js +10 -1
  96. package/lib/src/config.js +51 -5
  97. package/lib/src/dashboard/commands.js +185 -141
  98. package/lib/src/dashboard/event-manager.js +88 -67
  99. package/lib/src/dashboard/services/failure-analysis-service.js +136 -45
  100. package/lib/src/dashboard/sessionCommandSummary.js +39 -0
  101. package/lib/src/data-service/appleFamily.js +43 -0
  102. package/lib/src/data-service/db.js +11 -0
  103. package/lib/src/data-service/device-service.js +6 -1
  104. package/lib/src/data-service/device-store.js +76 -3
  105. package/lib/src/data-service/deviceClaims.js +37 -0
  106. package/lib/src/data-service/deviceFieldOwners.js +25 -11
  107. package/lib/src/data-service/deviceSettings.js +79 -0
  108. package/lib/src/data-service/prisma-store.js +169 -15
  109. package/lib/src/data-service/web-config-service.js +50 -92
  110. package/lib/src/device-managers/AndroidDeviceManager.js +9 -31
  111. package/lib/src/device-managers/android/AndroidH264StreamService.js +69 -20
  112. package/lib/src/device-managers/android/H264Multiplexer.js +38 -4
  113. package/lib/src/device-managers/ios/WDAClient.js +44 -43
  114. package/lib/src/device-managers/shellCommands.js +96 -0
  115. package/lib/src/device-utils.js +114 -40
  116. package/lib/src/gateway/defaultGateway.js +1 -1
  117. package/lib/src/gateway/forwardToNode.js +2 -0
  118. package/lib/src/gateway/healReport.js +87 -0
  119. package/lib/src/gateway/sessionGateway.js +12 -2
  120. package/lib/src/generated/client/edge.js +18 -3
  121. package/lib/src/generated/client/index-browser.js +15 -0
  122. package/lib/src/generated/client/index.d.ts +2086 -379
  123. package/lib/src/generated/client/index.js +18 -3
  124. package/lib/src/generated/client/package.json +1 -1
  125. package/lib/src/generated/client/schema.prisma +38 -7
  126. package/lib/src/generated/client/wasm.js +15 -0
  127. package/lib/src/interceptors/CommandInterceptor.js +271 -188
  128. package/lib/src/interceptors/xenonScripts.js +55 -0
  129. package/lib/src/interfaces/IPluginArgs.js +1 -2
  130. package/lib/src/middleware/authMiddleware.js +15 -3
  131. package/lib/src/middleware/commandCaller.js +3 -3
  132. package/lib/src/middleware/verifyCredential.js +58 -1
  133. package/lib/src/plugin.js +23 -4
  134. package/lib/src/prisma.js +1 -1
  135. package/lib/src/scripts/database-check.js +124 -0
  136. package/lib/src/services/AICommandService.js +9 -2
  137. package/lib/src/services/AIService.js +281 -32
  138. package/lib/src/services/CleanupService.js +6 -1
  139. package/lib/src/services/EmailService.js +29 -0
  140. package/lib/src/services/InterceptorService.js +70 -13
  141. package/lib/src/services/NetworkConditioningService.js +85 -88
  142. package/lib/src/services/NotificationService.js +36 -29
  143. package/lib/src/services/OrphanSweeper.js +7 -0
  144. package/lib/src/services/PortAllocator.js +5 -0
  145. package/lib/src/services/SelectorVerificationJob.js +15 -4
  146. package/lib/src/services/ServerManager.js +105 -9
  147. package/lib/src/services/SessionLifecycleService.js +133 -75
  148. package/lib/src/services/ShutdownCoordinator.js +33 -0
  149. package/lib/src/services/SocketServer.js +19 -3
  150. package/lib/src/services/TeamService.js +20 -3
  151. package/lib/src/services/bug-report/video-slice.js +4 -1
  152. package/lib/src/services/device-access/leaseOverride.js +7 -5
  153. package/lib/src/services/healing/FuzzyXmlHealingProvider.js +51 -0
  154. package/lib/src/services/healing/HealEtalonService.js +3 -2
  155. package/lib/src/services/healing/HealingOrchestrator.js +85 -71
  156. package/lib/src/services/healing/OcrHealingProvider.js +41 -64
  157. package/lib/src/services/healing/ResilioTreeHealingProvider.js +41 -50
  158. package/lib/src/services/healing/VisualAiHealingProvider.js +1 -1
  159. package/lib/src/services/healing/fingerprintIdentity.js +126 -0
  160. package/lib/src/services/healing/resilioPath.js +274 -0
  161. package/lib/src/services/interceptor/AndroidProxyAdapter.js +18 -0
  162. package/lib/src/services/interceptor/interceptorOptions.js +44 -0
  163. package/lib/src/services/logcat/SessionDeviceLogs.js +271 -0
  164. package/lib/src/services/logcat/deviceLogBook.js +163 -0
  165. package/lib/src/services/network/AndroidRadios.js +71 -0
  166. package/lib/src/services/network/PhoneNetworkLedger.js +184 -0
  167. package/lib/src/services/network/PhoneNetworkRestore.js +330 -0
  168. package/lib/src/services/network/adbForPhone.js +60 -0
  169. package/lib/src/services/network/phoneNetworkLock.js +20 -0
  170. package/lib/src/services/network/xenonProxy.js +107 -0
  171. package/lib/src/services/ocr/ocrData.js +118 -0
  172. package/lib/src/services/ocr/vendor/LICENSE-tessdata.txt +202 -0
  173. package/lib/src/services/ocr/vendor/eng.traineddata.gz +0 -0
  174. package/lib/src/services/omni-vision/OmniVisionService.js +132 -95
  175. package/lib/src/services/omni-vision/VisionAssertionService.js +28 -25
  176. package/lib/src/services/omni-vision/ocrTextMatch.js +105 -0
  177. package/lib/src/services/omni-vision/screenScale.js +68 -0
  178. package/lib/src/services/passwordResetLink.js +50 -9
  179. package/lib/src/services/passwordResetMode.js +3 -1
  180. package/lib/src/services/publicUrl.js +45 -0
  181. package/lib/src/services/recording/concurrency-gate.js +12 -3
  182. package/lib/src/services/session/sessionIdentity.js +5 -3
  183. package/lib/src/services/session/shutdownReason.js +26 -0
  184. package/lib/src/services/settings/SelfHealingSwitch.js +70 -0
  185. package/lib/src/services/settings/aiEngineSettings.js +219 -0
  186. package/lib/src/services/settings/labSettings.js +149 -0
  187. package/lib/src/services/token/mintedLifetime.js +51 -0
  188. package/lib/src/services/webhookEvents.js +173 -0
  189. package/lib/src/sessions/SessionManager.js +8 -2
  190. package/lib/src/sessions/sessionMemory.js +25 -0
  191. package/lib/test/helpers/fake-adb.js +58 -0
  192. package/lib/test/helpers/fake-ai-provider.js +188 -0
  193. package/lib/test/helpers/fake-device-table.js +63 -24
  194. package/lib/test/helpers/loki-stores.js +33 -0
  195. package/lib/test/helpers/page-sources.js +164 -0
  196. package/lib/test/helpers/scratch-database.js +58 -13
  197. package/lib/test/integration/audit-ingest.spec.js +10 -10
  198. package/lib/test/integration/auth-flow.spec.js +9 -14
  199. package/lib/test/integration/auth-rate-limit.spec.js +6 -3
  200. package/lib/test/integration/bug-report-route.spec.js +22 -2
  201. package/lib/test/integration/forgot-password-rate-limit.spec.js +6 -3
  202. package/lib/test/integration/forgot-password.spec.js +17 -18
  203. package/lib/test/integration/legacy-deprecation-headers.spec.js +5 -2
  204. package/lib/test/integration/migration.spec.js +6 -1
  205. package/lib/test/integration/node-pair-auth-rest.spec.js +5 -9
  206. package/lib/test/integration/ports-router.spec.js +4 -4
  207. package/lib/test/integration/prisma-device-store-add-devices.spec.js +2 -3
  208. package/lib/test/integration/prisma-device-store-team-filter.spec.js +2 -5
  209. package/lib/test/integration/profile-tokens.spec.js +10 -16
  210. package/lib/test/integration/recordings-router.spec.js +16 -16
  211. package/lib/test/integration/reset-revokes-sessions.spec.js +4 -9
  212. package/lib/test/integration/role-matrix.spec.js +4 -9
  213. package/lib/test/integration/sdk-leases-router.spec.js +9 -9
  214. package/lib/test/integration/sdk-version.spec.js +2 -2
  215. package/lib/test/integration/selector-health-endpoint.spec.js +5 -5
  216. package/lib/test/integration/team-membership-migration.spec.js +73 -12
  217. package/lib/test/integration/team-visibility-apps.spec.js +15 -22
  218. package/lib/test/integration/team-visibility-control.spec.js +96 -69
  219. package/lib/test/integration/team-visibility-dashboard.spec.js +7 -23
  220. package/lib/test/integration/team-visibility-grid.spec.js +16 -15
  221. package/lib/test/integration/team-visibility-leases.spec.js +8 -11
  222. package/lib/test/integration/team-visibility-recordings.spec.js +6 -19
  223. package/lib/test/integration/team-visibility-sessions.spec.js +6 -19
  224. package/lib/test/integration/users-flow.spec.js +7 -12
  225. package/lib/test/integration/users-lockout.spec.js +5 -3
  226. package/lib/test/unit/EmailService.test.js +66 -0
  227. package/lib/test/unit/ResilioTreeHealingProvider.test.js +46 -19
  228. package/lib/test/unit/TeamService.test.js +3 -0
  229. package/lib/test/unit/XenonCapabilityManager.spec.js +4 -2
  230. package/lib/test/unit/ai-call-time-limit.spec.js +130 -0
  231. package/lib/test/unit/ai-engine-settings.spec.js +338 -0
  232. package/lib/test/unit/ai-provider-switch.spec.js +130 -0
  233. package/lib/test/unit/ai-rate-limit.spec.js +126 -0
  234. package/lib/test/unit/android-h264-viewers.spec.js +272 -0
  235. package/lib/test/unit/android-preview-hold.spec.js +3 -2
  236. package/lib/test/unit/apikeys-router.spec.js +84 -0
  237. package/lib/test/unit/apple-family.spec.js +36 -0
  238. package/lib/test/unit/authMiddleware.bearer.spec.js +9 -0
  239. package/lib/test/unit/authMiddleware.credentialLifetime.spec.js +149 -0
  240. package/lib/test/unit/bug-report/video-slice.spec.js +19 -0
  241. package/lib/test/unit/cleanup-settings-db.spec.js +103 -0
  242. package/lib/test/unit/cleanup-settings.spec.js +244 -0
  243. package/lib/test/unit/dashboard-api-paths.spec.js +101 -0
  244. package/lib/test/unit/dashboard-commands.spec.js +249 -0
  245. package/lib/test/unit/dashboard-events-device-logs.spec.js +207 -0
  246. package/lib/test/unit/dashboard-events-team-scope.spec.js +9 -6
  247. package/lib/test/unit/dashboard-plugin-link.spec.js +213 -0
  248. package/lib/test/unit/database-check.spec.js +108 -0
  249. package/lib/test/unit/default-plugin-args.spec.js +33 -0
  250. package/lib/test/unit/device-log-book.spec.js +180 -0
  251. package/lib/test/unit/device-offline-webhook.spec.js +81 -0
  252. package/lib/test/unit/device-setting-columns.spec.js +66 -0
  253. package/lib/test/unit/device-settings-loki.spec.js +87 -0
  254. package/lib/test/unit/device-settings-survive.spec.js +555 -0
  255. package/lib/test/unit/device-sync-lost-update.spec.js +5 -0
  256. package/lib/test/unit/emulator-boot.spec.js +91 -0
  257. package/lib/test/unit/enable-dashboard-option.spec.js +57 -0
  258. package/lib/test/unit/event-log-session-data.spec.js +244 -0
  259. package/lib/test/unit/failure-analysis.spec.js +182 -0
  260. package/lib/test/unit/failure-categories.spec.js +128 -0
  261. package/lib/test/unit/fingerprint-identity.spec.js +433 -0
  262. package/lib/test/unit/h264-multiplexer.spec.js +46 -0
  263. package/lib/test/unit/heal-report.spec.js +71 -0
  264. package/lib/test/unit/healing-instrumentation.spec.js +6 -1
  265. package/lib/test/unit/healing-tier-gate.spec.js +73 -29
  266. package/lib/test/unit/healing-tiers-every-session.spec.js +219 -0
  267. package/lib/test/unit/hub-node-gateway-appium-server.spec.js +219 -0
  268. package/lib/test/unit/hub-node-same-host.spec.js +5 -0
  269. package/lib/test/unit/interceptor-visual-elements.spec.js +192 -0
  270. package/lib/test/unit/iphone-ipad-only.spec.js +132 -0
  271. package/lib/test/unit/json-logging-option.spec.js +74 -0
  272. package/lib/test/unit/lab-settings.spec.js +218 -0
  273. package/lib/test/unit/lease/lease-override.spec.js +23 -6
  274. package/lib/test/unit/lease/session-lease-proof.spec.js +16 -4
  275. package/lib/test/unit/max-sessions.spec.js +240 -0
  276. package/lib/test/unit/ocr-healing-tier-real-ocr.spec.js +113 -0
  277. package/lib/test/unit/ocr-healing-tier.spec.js +122 -0
  278. package/lib/test/unit/ocr-offline.spec.js +213 -0
  279. package/lib/test/unit/ocr-text-match.spec.js +44 -0
  280. package/lib/test/unit/omni-virtual-element-store.spec.js +301 -0
  281. package/lib/test/unit/omni-vision-analyze-screen.spec.js +72 -0
  282. package/lib/test/unit/omni-vision-ios-points.spec.js +159 -0
  283. package/lib/test/unit/omni-vision-tap-text.spec.js +129 -0
  284. package/lib/test/unit/omni-vision.spec.js +6 -8
  285. package/lib/test/unit/package-engines.spec.js +27 -0
  286. package/lib/test/unit/partial-config-file.spec.js +14 -0
  287. package/lib/test/unit/passwordResetMode.test.js +10 -2
  288. package/lib/test/unit/phone-network/boot-clean-up.spec.js +64 -0
  289. package/lib/test/unit/phone-network/interceptor-options.spec.js +77 -0
  290. package/lib/test/unit/phone-network/interceptor-proxy-restore.spec.js +145 -0
  291. package/lib/test/unit/phone-network/network-conditioning.spec.js +145 -0
  292. package/lib/test/unit/phone-network/phone-network-restore.spec.js +246 -0
  293. package/lib/test/unit/phone-network/session-end-paths.spec.js +182 -0
  294. package/lib/test/unit/phone-network/session-start.spec.js +110 -0
  295. package/lib/test/unit/phone-network/xenon-proxy.spec.js +69 -0
  296. package/lib/test/unit/plugin.spec.js +3 -3
  297. package/lib/test/unit/profile-router.test.js +122 -1
  298. package/lib/test/unit/queue-requester.spec.js +1 -1
  299. package/lib/test/unit/recording-options.spec.js +181 -0
  300. package/lib/test/unit/reset-link-address.spec.js +266 -0
  301. package/lib/test/unit/reset-link.test.js +10 -4
  302. package/lib/test/unit/resilio-path-healing.spec.js +270 -0
  303. package/lib/test/unit/selector-learning-every-session.spec.js +179 -0
  304. package/lib/test/unit/selector-verification-clean-build.spec.js +130 -0
  305. package/lib/test/unit/selector-verification-job.spec.js +13 -13
  306. package/lib/test/unit/self-healing-boot.spec.js +80 -0
  307. package/lib/test/unit/self-healing-setting.spec.js +273 -0
  308. package/lib/test/unit/session-app-resolution.spec.js +5 -1
  309. package/lib/test/unit/session-attribution-wiring.spec.js +41 -13
  310. package/lib/test/unit/session-create-credential-owner.spec.js +242 -0
  311. package/lib/test/unit/session-credential-strip.spec.js +1 -1
  312. package/lib/test/unit/session-device-logs.spec.js +347 -0
  313. package/lib/test/unit/session-end-failure-analysis.spec.js +133 -0
  314. package/lib/test/unit/session-failed-webhook.spec.js +170 -0
  315. package/lib/test/unit/session-log-indexes.spec.js +64 -3
  316. package/lib/test/unit/shell-commands.spec.js +133 -0
  317. package/lib/test/unit/socketServer.scopedEmit.spec.js +2 -0
  318. package/lib/test/unit/socketServer.sessionCookie.spec.js +2 -1
  319. package/lib/test/unit/stream-start-pipelines.spec.js +264 -0
  320. package/lib/test/unit/stream-status-type.spec.js +4 -0
  321. package/lib/test/unit/token-mint-limits.spec.js +165 -0
  322. package/lib/test/unit/unexpected-shutdown-reason.spec.js +163 -0
  323. package/lib/test/unit/verify-credential.spec.js +33 -0
  324. package/lib/test/unit/vision-assertion.spec.js +119 -0
  325. package/lib/test/unit/wda-client-shell.spec.js +133 -0
  326. package/lib/test/unit/web-config-service.spec.js +98 -0
  327. package/lib/test/unit/webhook-delivery.spec.js +24 -0
  328. package/lib/test/unit/webhook-payloads.spec.js +273 -0
  329. package/lib/test/unit/xenon-execute-scripts.spec.js +138 -0
  330. package/lib/tsconfig.tsbuildinfo +1 -1
  331. package/lib/web/src/components/webhook-settings/webhookEventVariables.json +30 -0
  332. package/package.json +5 -5
  333. package/prisma/migrations/20261004140000_keep_device_settings/migration.sql +19 -0
  334. package/prisma/migrations/20261004174413_locator_etalon_path/migration.sql +2 -0
  335. package/prisma/schema.prisma +38 -7
  336. package/schema.json +23 -25
  337. package/scripts/generate-types-from-schema.js +1 -2
  338. package/scripts/lib/always-present-plugin-args.js +4 -1
  339. package/lib/public/assets/BugReportButton-BoGhlI7F.js +0 -15
  340. package/lib/public/assets/DeviceMosaicView-8J0oYqMM.js +0 -2
  341. package/lib/public/assets/ai-settings-Bce5SJob.js +0 -21
  342. package/lib/public/assets/device-explorer-C-KnhMHI.js +0 -279
  343. package/lib/public/assets/forgot-password-DnudqFFo.js +0 -1
  344. package/lib/public/assets/maintenance-settings-zDVlOMVK.js +0 -6
  345. package/lib/public/assets/recording-group-store-WVM3hoXn.js +0 -26
  346. package/lib/public/assets/runbook-page-DJTVCJX7.js +0 -124
  347. package/lib/public/assets/session-detail-page-CGn55Pvl.js +0 -4
  348. package/lib/public/assets/settings-MsVU2ukE.js +0 -6
  349. package/lib/public/assets/webhook-settings-DiS8geIm.js +0 -1
  350. /package/lib/public/assets/{BugReportButton-CPBjfiv4.css → index-CPBjfiv4.css} +0 -0
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ /**
3
+ * What a stored fingerprint (`LocatorSignature.attributes`) says about which
4
+ * element it is, as opposed to where the element was (x, y, width, height).
5
+ *
6
+ * Through 2.14 every learnt fingerprint held only the rect and the type: the
7
+ * attribute reads failed (CommandInterceptor.triggerLearning). Fuzzy XML, which
8
+ * weighs position above everything else, then healed a selector to whatever
9
+ * element of that type sat at that spot. A fingerprint with no identity isn't
10
+ * used for position, and is learnt again.
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.FINGERPRINT_IDENTITY_ATTRIBUTES = void 0;
14
+ exports.meaningful = meaningful;
15
+ exports.hasIdentity = hasIdentity;
16
+ exports.attributesToLearn = attributesToLearn;
17
+ exports.resourceIdName = resourceIdName;
18
+ exports.stableIdentifierOf = stableIdentifierOf;
19
+ exports.sameIdentifier = sameIdentifier;
20
+ exports.sameText = sameText;
21
+ /**
22
+ * The attributes that say which element a fingerprint is. Not `value`: on a
23
+ * text field it is what the test typed, which fingerprints no longer keep.
24
+ */
25
+ exports.FINGERPRINT_IDENTITY_ATTRIBUTES = [
26
+ 'resource-id',
27
+ 'content-desc',
28
+ 'accessibility-id',
29
+ 'text',
30
+ 'name',
31
+ 'label',
32
+ 'id',
33
+ 'hint',
34
+ ];
35
+ /**
36
+ * A value that says something: a string with more than spaces in it, and not
37
+ * "null", which is what UiAutomator2 answers for an attribute the element
38
+ * hasn't set (its getAttribute is String(value)).
39
+ */
40
+ function meaningful(value) {
41
+ return typeof value === 'string' && value.trim() !== '' && value.trim() !== 'null';
42
+ }
43
+ /** Whether a fingerprint says anything about which element it is. */
44
+ function hasIdentity(attributes) {
45
+ return exports.FINGERPRINT_IDENTITY_ATTRIBUTES.some((name) => meaningful(attributes === null || attributes === void 0 ? void 0 : attributes[name]));
46
+ }
47
+ /**
48
+ * The attributes learning asks a driver for: those it has. UiAutomator2
49
+ * throws for `id` and `label`, and its `name` is the text again; WebDriverAgent
50
+ * throws for anything but its own, so five of the old list were five failed
51
+ * round trips per selector learnt.
52
+ */
53
+ function attributesToLearn(platformName) {
54
+ const platform = String(platformName !== null && platformName !== void 0 ? platformName : '').toLowerCase();
55
+ if (platform === 'android')
56
+ return ['resource-id', 'content-desc', 'text', 'hint'];
57
+ if (platform === 'ios' || platform === 'tvos')
58
+ return ['name', 'label'];
59
+ return ['resource-id', 'content-desc', 'text', 'hint', 'name', 'label'];
60
+ }
61
+ /**
62
+ * An Android resource-id without its package: `com.shop:id/pay` is `pay`.
63
+ * Fuzzy XML's veto asks whether two ids are the same this way: ids of one
64
+ * app share the package, and of a debug build another one. Its score still
65
+ * compares whole ids, where the shared package earns a share of the weight.
66
+ */
67
+ function resourceIdName(resourceId) {
68
+ const at = resourceId.lastIndexOf(':id/');
69
+ if (at >= 0)
70
+ return resourceId.slice(at + 4);
71
+ return resourceId.slice(resourceId.lastIndexOf('/') + 1);
72
+ }
73
+ /**
74
+ * The identifier a developer gave the element, which stays when its text
75
+ * changes: an Android resource-id, or an iOS accessibility identifier (`name`
76
+ * when it isn't just the label; an element without one has its label as name).
77
+ */
78
+ function stableIdentifierOf(attributes) {
79
+ const resourceId = attributes === null || attributes === void 0 ? void 0 : attributes['resource-id'];
80
+ if (meaningful(resourceId))
81
+ return { attribute: 'resource-id', value: resourceId };
82
+ const name = attributes === null || attributes === void 0 ? void 0 : attributes.name;
83
+ if (meaningful(name) && name !== (attributes === null || attributes === void 0 ? void 0 : attributes.label))
84
+ return { attribute: 'name', value: name };
85
+ return null;
86
+ }
87
+ // Built at run time: the compiler's target predates Unicode property escapes
88
+ // in regular expression literals. Letters, their combining marks and digits,
89
+ // in any script.
90
+ const NOT_A_WORD = new RegExp('[^\\p{L}\\p{M}\\p{N}]+', 'gu');
91
+ const CAMEL_TURN = new RegExp('([\\p{Ll}\\p{N}])(\\p{Lu})', 'gu');
92
+ /** An identifier's words: split where camelCase turns and at anything but a letter or digit. */
93
+ function identifierWords(identifier) {
94
+ return identifier
95
+ .normalize('NFC')
96
+ .replace(CAMEL_TURN, '$1 $2')
97
+ .toLowerCase()
98
+ .split(NOT_A_WORD)
99
+ .filter(Boolean);
100
+ }
101
+ /**
102
+ * Whether two identifiers name the same element: they have the same words,
103
+ * however written (btn-pay, pay_btn, payBtn). Any other pair names another
104
+ * element, and the text decides: an id that gains words is as often another
105
+ * element (pay_later, undo_delete) as a rename (checkout_pay), and letters
106
+ * alone can't tell follow from unfollow, or checkout.cancel from
107
+ * checkout.pay (64% of their letter pairs are shared). Two with no letter or
108
+ * digit between them can't be told apart, and count as the same.
109
+ */
110
+ function sameIdentifier(a, b) {
111
+ const [wordsA, wordsB] = [new Set(identifierWords(a)), new Set(identifierWords(b))];
112
+ if (wordsA.size !== wordsB.size)
113
+ return false;
114
+ return [...wordsA].every((w) => wordsB.has(w));
115
+ }
116
+ /**
117
+ * Whether two texts read the same: case, punctuation and spacing aside, with
118
+ * accents composed (NFC). Combining marks count: Hindi दें and दो differ only
119
+ * by theirs. Nothing looser: "Log in" and "Log out", "Enable" and "Disable"
120
+ * are as alike by their letters as a reworded label is.
121
+ */
122
+ function sameText(a, b) {
123
+ const read = (t) => t.normalize('NFC').toLowerCase().replace(NOT_A_WORD, ' ').trim();
124
+ const [textA, textB] = [read(a), read(b)];
125
+ return textA !== '' && textA === textB;
126
+ }
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ Object.defineProperty(exports, "__esModule", { value: true });
14
+ exports.MIN_LEAD = exports.MIN_SCORE = exports.RESILIO_PATH_FORMAT = void 0;
15
+ exports.resilioPathOf = resilioPathOf;
16
+ exports.isResilioPath = isResilioPath;
17
+ exports.findLearntElement = findLearntElement;
18
+ exports.nearestElement = nearestElement;
19
+ exports.locatorsSelectingOnly = locatorsSelectingOnly;
20
+ exports.contradictsSelector = contradictsSelector;
21
+ const xmldom_1 = require("@xmldom/xmldom");
22
+ const resiliotree_1 = require("resiliotree");
23
+ const xpath_1 = require("xpath");
24
+ /**
25
+ * The Resilio healing tier's view of a page source: an element's path from
26
+ * the root of the driver's element tree, as resiliotree compares paths.
27
+ *
28
+ * The page source is parsed as the XML it is. Through 2.14 it went through
29
+ * resiliotree's HTML parser, which lowercases every tag
30
+ * (`android.widget.button`, which the drivers' XPath doesn't match) and nests
31
+ * every element written `<x/>` around its next siblings.
32
+ *
33
+ * A path is stored with the selector's fingerprint (`LocatorEtalon.path`).
34
+ * Each node keeps what resiliotree compares (tag, id, labels, index, other
35
+ * attributes), not its children or text, so a path is a few kilobytes.
36
+ */
37
+ /** Marks a path made here. A path without it (an HTML parse, before 2.15) is not used. */
38
+ exports.RESILIO_PATH_FORMAT = 'page-source-1';
39
+ /**
40
+ * How sure Resilio must be. An element that kept its id scores about 0.99
41
+ * after moving anywhere in the tree; once its id changed, or it is gone, the
42
+ * best element scores about 0.55, and a neighbour of the same type comes
43
+ * within a few hundredths of it. Below this, or with a second element as
44
+ * close as MIN_LEAD, the next tier decides.
45
+ */
46
+ exports.MIN_SCORE = 0.8;
47
+ exports.MIN_LEAD = 0.05;
48
+ function platformOf(pageSource) {
49
+ if (/<XCUIElementType/.test(pageSource))
50
+ return 'ios';
51
+ if (/<hierarchy[\s>]/.test(pageSource))
52
+ return 'android';
53
+ return 'other';
54
+ }
55
+ const isElement = (n) => !!n && n.nodeType === 1;
56
+ function childElements(el) {
57
+ const out = [];
58
+ for (let c = el.firstChild; c; c = c.nextSibling)
59
+ if (isElement(c))
60
+ out.push(c);
61
+ return out;
62
+ }
63
+ /**
64
+ * One element as a resiliotree node, without children. The platform decides
65
+ * what its id is: Android's resource-id, iOS's name, else `id`.
66
+ */
67
+ function nodeBuilderFor(el, index, platform) {
68
+ const attributes = new Map();
69
+ for (let i = 0; i < el.attributes.length; i++) {
70
+ attributes.set(el.attributes[i].name, el.attributes[i].value);
71
+ }
72
+ const builder = new resiliotree_1.NodeBuilder().setTag(el.tagName).setIndex(index);
73
+ if (platform === 'android')
74
+ builder.setAndroidAttributes(attributes);
75
+ else if (platform === 'ios')
76
+ builder.setIOSAttributes(attributes);
77
+ else
78
+ builder.setAttributes(attributes);
79
+ return builder;
80
+ }
81
+ function parse(pageSource) {
82
+ return new xmldom_1.DOMParser({
83
+ errorHandler: { warning: () => { }, error: () => { }, fatalError: () => { } },
84
+ }).parseFromString(pageSource, 'text/xml');
85
+ }
86
+ /** The page source as a resiliotree tree, each node knowing its element. */
87
+ function treeOf(pageSource) {
88
+ const doc = parse(pageSource);
89
+ const top = doc === null || doc === void 0 ? void 0 : doc.documentElement;
90
+ if (!isElement(top))
91
+ return null;
92
+ const platform = platformOf(pageSource);
93
+ const elementOf = new Map();
94
+ const build = (el, index) => {
95
+ const builder = nodeBuilderFor(el, index, platform);
96
+ childElements(el).forEach((child, i) => builder.addChild(build(child, i)));
97
+ const node = builder.build();
98
+ elementOf.set(node, el);
99
+ return node;
100
+ };
101
+ return { root: build(top, 0), elementOf };
102
+ }
103
+ function compact(node) {
104
+ const _a = node.toJSON(), { children: _children, innerText: _text } = _a, rest = __rest(_a, ["children", "innerText"]);
105
+ return rest;
106
+ }
107
+ /**
108
+ * The path of an element of a parsed page source (an xmldom Element, as the
109
+ * Fuzzy XML and Resilio tiers find them), from the root of the page source.
110
+ * `pageSource` decides the platform. Null for anything that isn't such an
111
+ * element.
112
+ */
113
+ function resilioPathOf(element, pageSource) {
114
+ if (!isElement(element))
115
+ return null;
116
+ const platform = platformOf(pageSource);
117
+ const lineage = [];
118
+ for (let el = element; isElement(el); el = el.parentNode)
119
+ lineage.unshift(el);
120
+ const nodes = lineage.map((el) => {
121
+ const parent = el.parentNode;
122
+ const index = isElement(parent) ? childElements(parent).indexOf(el) : 0;
123
+ return compact(nodeBuilderFor(el, index, platform).build());
124
+ });
125
+ return { format: exports.RESILIO_PATH_FORMAT, nodes };
126
+ }
127
+ /** Whether `path` is one made here (not an older HTML parse). */
128
+ function isResilioPath(path) {
129
+ return (!!path &&
130
+ typeof path === 'object' &&
131
+ path.format === exports.RESILIO_PATH_FORMAT &&
132
+ Array.isArray(path.nodes) &&
133
+ path.nodes.length > 0);
134
+ }
135
+ /** Attributes that say which element an element is, not where it is or what state it is in. */
136
+ const IDENTITY_ATTRIBUTES = new Set([
137
+ 'resource-id',
138
+ 'content-desc',
139
+ 'text',
140
+ 'name',
141
+ 'label',
142
+ 'value',
143
+ 'id',
144
+ 'hint',
145
+ 'accessibility-id',
146
+ ]);
147
+ /**
148
+ * The element of the page source that the driver found, from its tag and the
149
+ * attributes Xenon read from it (`name`/`value` pairs: resource-id, text,
150
+ * name, label, ..., and x, y, width, height). The element of that tag with
151
+ * the most of them, among those that share at least one identity attribute or
152
+ * the whole rect with it: the page source is read after the find answered,
153
+ * so the screen may have changed, and a size alone names nothing. Null when
154
+ * none qualifies, or two qualify equally well.
155
+ */
156
+ function findLearntElement(pageSource, nodeName, attributes) {
157
+ const doc = parse(pageSource);
158
+ if (!isElement(doc === null || doc === void 0 ? void 0 : doc.documentElement))
159
+ return null;
160
+ const tag = (nodeName || '').toLowerCase();
161
+ const anyTag = !tag || tag === 'xcuielementtypeany' || tag === 'unknown';
162
+ const wanted = new Map(attributes.map((a) => [a.name.toLowerCase(), String(a.value)]));
163
+ const rect = ['x', 'y', 'width', 'height'].map((k) => wanted.get(k));
164
+ const hasRect = rect.every((v) => v !== undefined);
165
+ /** How many of the attributes `el` shares, or 0 when it shares no identity and not the rect. */
166
+ const matchesOf = (el) => {
167
+ let all = 0;
168
+ let identity = 0;
169
+ for (const [name, value] of wanted) {
170
+ if (el.getAttribute(name) !== value)
171
+ continue;
172
+ all++;
173
+ if (IDENTITY_ATTRIBUTES.has(name))
174
+ identity++;
175
+ }
176
+ // Android writes a rect as bounds="[x1,y1][x2,y2]"; iOS as x, y, width, height.
177
+ let wholeRect = hasRect && ['x', 'y', 'width', 'height'].every((k, i) => el.getAttribute(k) === rect[i]);
178
+ const bounds = el.getAttribute('bounds');
179
+ if (bounds && hasRect) {
180
+ const [x, y, w, h] = rect.map(Number);
181
+ if (bounds === `[${x},${y}][${x + w},${y + h}]`) {
182
+ all++;
183
+ wholeRect = true;
184
+ }
185
+ }
186
+ return identity > 0 || wholeRect ? all : 0;
187
+ };
188
+ let best = null;
189
+ let bestCount = 0;
190
+ let tie = false;
191
+ const walk = (el) => {
192
+ if (anyTag || el.tagName.toLowerCase() === tag) {
193
+ const n = matchesOf(el);
194
+ if (n > bestCount) {
195
+ best = el;
196
+ bestCount = n;
197
+ tie = false;
198
+ }
199
+ else if (n > 0 && n === bestCount) {
200
+ tie = true;
201
+ }
202
+ }
203
+ childElements(el).forEach(walk);
204
+ };
205
+ walk(doc.documentElement);
206
+ return tie ? null : best;
207
+ }
208
+ /**
209
+ * The element of `pageSource` at the end of the path most like `path`, and
210
+ * how alike they are (0 to 1). Null when no element scores MIN_SCORE, or
211
+ * another comes within MIN_LEAD of the best: Resilio then has no answer.
212
+ */
213
+ function nearestElement(path, pageSource) {
214
+ const tree = treeOf(pageSource);
215
+ if (!tree)
216
+ return null;
217
+ const finder = new resiliotree_1.PathFinder(new resiliotree_1.LCSPathDistance(), new resiliotree_1.HeuristicNodeDistance());
218
+ // resiliotree scores an element once for each leaf below it, so an element
219
+ // holding others (a list row) comes back several times at one score. Every
220
+ // result, best first, and the best of each element.
221
+ const scored = finder.find(resiliotree_1.Path.fromJSON(path), tree.root, Number.MAX_SAFE_INTEGER);
222
+ const best = scored[0];
223
+ if (!best || best.score < exports.MIN_SCORE)
224
+ return null;
225
+ const second = scored.find((s) => s.value !== best.value);
226
+ if (second && best.score - second.score < exports.MIN_LEAD)
227
+ return null;
228
+ const element = tree.elementOf.get(best.value);
229
+ return element ? { element, score: best.score } : null;
230
+ }
231
+ /**
232
+ * The locators among `candidates` that select `element` and nothing else in
233
+ * its page source. A driver answers a find with the first match, so a
234
+ * locator that also matches an element before it would hand back that one.
235
+ */
236
+ function locatorsSelectingOnly(element, candidates) {
237
+ const doc = element.ownerDocument;
238
+ return candidates.filter((xpath) => {
239
+ try {
240
+ const found = (0, xpath_1.select)(xpath, doc);
241
+ return Array.isArray(found) && found.length === 1 && found[0] === element;
242
+ }
243
+ catch (_a) {
244
+ return false;
245
+ }
246
+ });
247
+ }
248
+ /** The text-like attributes a selector can state that the element it means must have. */
249
+ const STATED_ATTRIBUTES = 'text|content-desc|label|name|value';
250
+ /**
251
+ * Whether `element` has, for an attribute the XPath `selector` states (the
252
+ * text, description, label, name or value), something other than what it
253
+ * says: `@text='OK'` on an element reading "Delete". Resilio compares paths,
254
+ * in which a changed text weighs little, so a dialog's OK button that now
255
+ * reads Delete would otherwise be healed to. A stated attribute may belong to
256
+ * another element of the XPath (an ancestor, a sibling); Resilio then
257
+ * declines a heal it could have made, and the next tier decides.
258
+ */
259
+ function contradictsSelector(element, strategy, selector) {
260
+ if (strategy !== 'xpath' || typeof selector !== 'string')
261
+ return false;
262
+ const valueOf = (name) => { var _a; return (_a = element.getAttribute(name)) !== null && _a !== void 0 ? _a : ''; };
263
+ const equals = new RegExp(`@(${STATED_ATTRIBUTES})\\s*=\\s*(['"])(.*?)\\2`, 'g');
264
+ for (const [, name, , value] of selector.matchAll(equals)) {
265
+ if (valueOf(name) !== value)
266
+ return true;
267
+ }
268
+ const contains = new RegExp(`contains\\(\\s*@(${STATED_ATTRIBUTES})\\s*,\\s*(['"])(.*?)\\2\\s*\\)`, 'g');
269
+ for (const [, name, , value] of selector.matchAll(contains)) {
270
+ if (!valueOf(name).includes(value))
271
+ return true;
272
+ }
273
+ return false;
274
+ }
@@ -10,6 +10,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.AndroidProxyAdapter = void 0;
13
+ const xenonProxy_1 = require("../network/xenonProxy");
13
14
  class AndroidProxyAdapter {
14
15
  constructor(getAdb) {
15
16
  this.getAdb = getAdb;
@@ -38,6 +39,23 @@ class AndroidProxyAdapter {
38
39
  yield adb.adbExec(['-s', udid, 'shell', 'settings', 'put', 'global', 'http_proxy', ':0']);
39
40
  });
40
41
  }
42
+ /** The phone's global HTTP proxy as stored: `host:port`, or `null` / `:0` / '' for none. */
43
+ readProxy(udid) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ const adb = yield this.getAdb(udid);
46
+ const out = yield adb.adbExec(['-s', udid, 'shell', 'settings', 'get', 'global', 'http_proxy']);
47
+ return String(out !== null && out !== void 0 ? out : '').trim();
48
+ });
49
+ }
50
+ /** Puts `previous` back as the phone's proxy, or clears it when there was none. */
51
+ restoreProxy(udid, previous) {
52
+ return __awaiter(this, void 0, void 0, function* () {
53
+ if (previous === null || (0, xenonProxy_1.isUnsetProxy)(previous))
54
+ return this.clearProxy(udid);
55
+ const adb = yield this.getAdb(udid);
56
+ yield adb.adbExec(['-s', udid, 'shell', 'settings', 'put', 'global', 'http_proxy', previous]);
57
+ });
58
+ }
41
59
  // Forwards a port on the device back to a port on the host over the adb transport
42
60
  // (USB or wireless adb). The device sees `127.0.0.1:devicePort` and that traffic
43
61
  // reaches the host's `hostPort`. This is the standard way to make a host-side
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveInterceptorOptions = resolveInterceptorOptions;
4
+ const XenonCapabilityManager_1 = require("../../XenonCapabilityManager");
5
+ /**
6
+ * The network capture a session gets: its own capability (any of the shapes
7
+ * getXenonCapabilities reads) wins field by field, and the server's
8
+ * `interceptor` option fills in what the session leaves unset.
9
+ *
10
+ * - `enabled`: the session's, when it says true or false; else the server's;
11
+ * else off.
12
+ * - `bufferSize`, `captureBodies`: the session's, else the server's, else the
13
+ * service's defaults (1000, true).
14
+ * - `mocks`, `includeHosts`, `excludeHosts`: the session's only.
15
+ *
16
+ * `sessionCaps` is getXenonCapabilities' output, where a field the session
17
+ * didn't set is `undefined`.
18
+ */
19
+ function resolveInterceptorOptions(sessionCaps, server) {
20
+ var _a;
21
+ const own = (key) => sessionCaps[key];
22
+ const enabled = own(XenonCapabilityManager_1.XENON_CAPABILITIES.INTERCEPTOR_ENABLED);
23
+ const bufferSize = own(XenonCapabilityManager_1.XENON_CAPABILITIES.INTERCEPTOR_BUFFER_SIZE);
24
+ const captureBodies = own(XenonCapabilityManager_1.XENON_CAPABILITIES.INTERCEPTOR_CAPTURE_BODIES);
25
+ return {
26
+ enabled: typeof enabled === 'boolean' ? enabled : (server === null || server === void 0 ? void 0 : server.enabled) === true,
27
+ bufferSize: (_a = positive(bufferSize)) !== null && _a !== void 0 ? _a : positive(server === null || server === void 0 ? void 0 : server.bufferSize),
28
+ captureBodies: typeof captureBodies === 'boolean'
29
+ ? captureBodies
30
+ : typeof (server === null || server === void 0 ? void 0 : server.captureBodies) === 'boolean'
31
+ ? server.captureBodies
32
+ : true,
33
+ mocks: listOr(own(XenonCapabilityManager_1.XENON_CAPABILITIES.INTERCEPTOR_MOCKS)),
34
+ includeHosts: listOr(own(XenonCapabilityManager_1.XENON_CAPABILITIES.INTERCEPTOR_INCLUDE_HOSTS)),
35
+ excludeHosts: listOr(own(XenonCapabilityManager_1.XENON_CAPABILITIES.INTERCEPTOR_EXCLUDE_HOSTS)),
36
+ };
37
+ }
38
+ function positive(value) {
39
+ const n = typeof value === 'string' && value.trim() !== '' ? Number(value) : value;
40
+ return typeof n === 'number' && Number.isFinite(n) && n > 0 ? n : undefined;
41
+ }
42
+ function listOr(value) {
43
+ return Array.isArray(value) ? value : [];
44
+ }