@xenon-device-management/xenon 2.11.0 → 2.12.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 (96) hide show
  1. package/lib/package.json +1 -1
  2. package/lib/public/assets/{AnnotationOverlay-BQPQ5bPF.js → AnnotationOverlay-Crkn72_3.js} +1 -1
  3. package/lib/public/assets/{ApiKeyGate-Bd7Pumwv.js → ApiKeyGate-BThVlj_j.js} +1 -1
  4. package/lib/public/assets/{BugReportButton-iC7fxPxl.js → BugReportButton-Dwa0GnBh.js} +1 -1
  5. package/lib/public/assets/DeviceMosaicView-Ccc-pOls.js +2 -0
  6. package/lib/public/assets/{EmptyState-wZeJbGhN.js → EmptyState-BeuTrlN_.js} +1 -1
  7. package/lib/public/assets/{FieldGroup-tpRfmhlE.js → FieldGroup-DBIaNxl1.js} +1 -1
  8. package/lib/public/assets/{FilterMenu-BZwOppId.js → FilterMenu-BgSAS6iT.js} +1 -1
  9. package/lib/public/assets/{Menu-CahoAx8L.js → Menu-GCbP6gYN.js} +1 -1
  10. package/lib/public/assets/{Modal-mcM5W_Ji.js → Modal-ByESeBRC.js} +1 -1
  11. package/lib/public/assets/RecordingPage-Bwyf3WMl.js +1 -0
  12. package/lib/public/assets/{RecordingsPage-BOez3f_9.js → RecordingsPage-7kM1rB3i.js} +2 -2
  13. package/lib/public/assets/{SegmentedControl-qMSiMN1d.js → SegmentedControl-B8tTU8kD.js} +1 -1
  14. package/lib/public/assets/{SettingCard-rcPtJ7HG.js → SettingCard-Clg_Ijbc.js} +1 -1
  15. package/lib/public/assets/{Table-J3uognu0.js → Table-CIaR0QWV.js} +1 -1
  16. package/lib/public/assets/{activity-_5pNSfKT.js → activity-Bengh9SD.js} +1 -1
  17. package/lib/public/assets/{ai-settings-DTPRbkei.js → ai-settings-G9SymiPH.js} +2 -2
  18. package/lib/public/assets/{api-keys-CxkIUo76.js → api-keys-CrGlbfn-.js} +1 -1
  19. package/lib/public/assets/{apps-Bv0pAfxz.js → apps-DIbcGVlU.js} +3 -3
  20. package/lib/public/assets/{arrow-left-uY7F6z1K.js → arrow-left-BtJIXXMY.js} +1 -1
  21. package/lib/public/assets/{arrow-right-BbAm_2Wa.js → arrow-right-zm-NagQh.js} +1 -1
  22. package/lib/public/assets/{arrow-up-right-x4H5NuvE.js → arrow-up-right-DdU8YEYp.js} +1 -1
  23. package/lib/public/assets/{auth-shell-CtMFhbnC.js → auth-shell-CHmBFmOz.js} +2 -2
  24. package/lib/public/assets/{builds-page-B_O5uBSZ.js → builds-page-JkzWKRpU.js} +1 -1
  25. package/lib/public/assets/{button-CQoMQEj_.js → button-CqhPBGRj.js} +1 -1
  26. package/lib/public/assets/{calendar-BZkpCqlL.js → calendar-C7eYYJTo.js} +1 -1
  27. package/lib/public/assets/{check-CAB6RYuc.js → check-DpbIM4E0.js} +1 -1
  28. package/lib/public/assets/{chevron-right-ec0unu3u.js → chevron-right-Dl4X1PRz.js} +1 -1
  29. package/lib/public/assets/{circle-check-Dfg-gpjg.js → circle-check-Du3sjbfV.js} +1 -1
  30. package/lib/public/assets/{circle-x-cbPq6Btp.js → circle-x-BSSqhpXi.js} +1 -1
  31. package/lib/public/assets/{clock-DU9cBLi8.js → clock-DMT60v1C.js} +1 -1
  32. package/lib/public/assets/{copy-VM9kWPpE.js → copy-BKNyOehd.js} +1 -1
  33. package/lib/public/assets/device-explorer-CHv1miyr.css +1 -0
  34. package/lib/public/assets/device-explorer-CoPR8DW3.js +279 -0
  35. package/lib/public/assets/{download-WgW4AVid.js → download-BM6Xn22t.js} +1 -1
  36. package/lib/public/assets/{forgot-password-BGRpjTtt.js → forgot-password-B8WqMqBT.js} +1 -1
  37. package/lib/public/assets/{index-DQa193-A.css → index-BTYMAqNW.css} +1 -1
  38. package/lib/public/assets/index-ClrpAMAT.js +219 -0
  39. package/lib/public/assets/{index-DNDdHt3h.js → index-DauQh6ie.js} +1 -1
  40. package/lib/public/assets/{input-DwiVcO3Q.js → input-CyKdLnEx.js} +1 -1
  41. package/lib/public/assets/{line-chart-PE5e9PeN.js → line-chart-EIBXwYGo.js} +1 -1
  42. package/lib/public/assets/{list-checks-Bgn9GEEO.js → list-checks-fWsgD9bI.js} +1 -1
  43. package/lib/public/assets/{lock-Cb7My6hc.js → lock-CVCe56TH.js} +1 -1
  44. package/lib/public/assets/{login-CDmyzSpl.js → login-BJ8a7yVD.js} +1 -1
  45. package/lib/public/assets/{maintenance-settings-Bq6pKoBt.js → maintenance-settings-DcRmTLS6.js} +1 -1
  46. package/lib/public/assets/{monitor-BZSwrnPV.js → monitor-Bw1YQZnL.js} +1 -1
  47. package/lib/public/assets/{mouse-pointer-2-BbFj8y8i.js → mouse-pointer-2-C01jbqkO.js} +1 -1
  48. package/lib/public/assets/{network-DpwYGB0-.js → network-CBGUjJDJ.js} +1 -1
  49. package/lib/public/assets/{overview-B4_IO-X8.js → overview-Cxe8aQ7C.js} +1 -1
  50. package/lib/public/assets/{page-header-BpLEuo7i.js → page-header-B92DKLiq.js} +1 -1
  51. package/lib/public/assets/play-Ck0L-0_m.js +11 -0
  52. package/lib/public/assets/{plus-DHZS0EGU.js → plus-Dq3tCy2N.js} +1 -1
  53. package/lib/public/assets/{profile-page-DsHDIq-Y.js → profile-page--dkDiKbr.js} +2 -2
  54. package/lib/public/assets/recording-group-store-5BYIFFN9.js +26 -0
  55. package/lib/public/assets/{reset-password-DuUjhw_l.js → reset-password-KYWlfjia.js} +1 -1
  56. package/lib/public/assets/{runbook-page-BI_ayvLd.js → runbook-page-mnsxgS1d.js} +1 -1
  57. package/lib/public/assets/{select-xiba9PSx.js → select-BBOIZTYm.js} +1 -1
  58. package/lib/public/assets/{selector-detail-redirect-Emz2obK_.js → selector-detail-redirect-CcI2j_Su.js} +1 -1
  59. package/lib/public/assets/{selector-health-page-zpwrgalC.js → selector-health-page-BdJb_x5L.js} +2 -2
  60. package/lib/public/assets/{session-detail-page-BhlTJ1Oq.js → session-detail-page-BjLaJy8z.js} +1 -1
  61. package/lib/public/assets/{settings-B-mabJFm.js → settings-B6cpMhsx.js} +1 -1
  62. package/lib/public/assets/{stat-tile-lT8WcPgu.js → stat-tile-BU9e4s36.js} +1 -1
  63. package/lib/public/assets/{tablet-DM8dp75P.js → tablet-hgbEwrWq.js} +1 -1
  64. package/lib/public/assets/{teams-CRkb5-Fe.js → teams-uiiG4hZM.js} +1 -1
  65. package/lib/public/assets/{trash-2-Dxgryn4o.js → trash-2-NK_Iazmg.js} +1 -1
  66. package/lib/public/assets/{upload-Ci0vz0BP.js → upload-BUX8TNFi.js} +1 -1
  67. package/lib/public/assets/{use-builds-data-DaaqMjjL.js → use-builds-data-DZszmFyl.js} +1 -1
  68. package/lib/public/assets/{use-password-reset-mode-BvIyZtaF.js → use-password-reset-mode-BK4B9kRC.js} +1 -1
  69. package/lib/public/assets/{users-CWYHk75q.js → users-BDh1xjad.js} +1 -1
  70. package/lib/public/assets/{users-BT8qx3ea.js → users-BU4XBbMT.js} +1 -1
  71. package/lib/public/assets/{video-off-BvY08g6I.js → video-off-BOjNwT4R.js} +1 -1
  72. package/lib/public/assets/webhook-settings-BMzyUcx5.js +1 -0
  73. package/lib/public/assets/{zap-qG2Li6rI.js → zap-DTWwVMUg.js} +1 -1
  74. package/lib/public/index.html +2 -2
  75. package/lib/src/device-managers/iOSTracker.js +14 -1
  76. package/lib/src/device-managers/ios/IOSDiscoveryService.js +9 -5
  77. package/lib/src/device-managers/ios/usbmuxd.js +46 -0
  78. package/lib/src/gateway/nodeSessionMetrics.js +5 -2
  79. package/lib/src/services/metrics/NodeMetricsCollector.js +4 -2
  80. package/lib/src/services/metrics/SessionMetricsService.js +5 -1
  81. package/lib/src/services/metrics/nodeMetrics.js +33 -3
  82. package/lib/src/sessions/RemoteSession.js +1 -1
  83. package/lib/test/unit/dashboard-events-metrics.spec.js +1 -0
  84. package/lib/test/unit/hub-node-session-metrics.spec.js +83 -13
  85. package/lib/test/unit/ios-usbmuxd-missing.spec.js +111 -0
  86. package/lib/test/unit/node-metrics-collector.spec.js +53 -0
  87. package/lib/test/unit/node-session-metrics-route.spec.js +2 -1
  88. package/lib/tsconfig.tsbuildinfo +1 -1
  89. package/package.json +1 -1
  90. package/lib/public/assets/DeviceMosaicView-CNdES7nm.js +0 -2
  91. package/lib/public/assets/RecordingPage-B4dFBndn.js +0 -11
  92. package/lib/public/assets/device-explorer-D2AqrrLN.css +0 -1
  93. package/lib/public/assets/device-explorer-ai0usQ8m.js +0 -268
  94. package/lib/public/assets/index-C33GjwPr.js +0 -219
  95. package/lib/public/assets/keycodes-CvCtpVJD.js +0 -26
  96. package/lib/public/assets/webhook-settings-aHIlSJFP.js +0 -1
@@ -44,6 +44,7 @@ const appiumUmbrella_1 = require("../../src/sessions/appiumUmbrella");
44
44
  const config_1 = require("../../src/config");
45
45
  const container_registration_1 = require("../helpers/container-registration");
46
46
  const scratch_database_1 = require("../helpers/scratch-database");
47
+ const selector_health_fixture_1 = require("../helpers/selector-health-fixture");
47
48
  const appium_umbrella_1 = require("../helpers/appium-umbrella");
48
49
  /**
49
50
  * A hub collects CPU and memory for a session on a node's phone from the
@@ -67,6 +68,19 @@ class NodeSideMetrics extends SessionMetricsService_1.SessionMetricsService {
67
68
  return { start: () => undefined, stop: () => __awaiter(this, void 0, void 0, function* () { return void (this.stopped += 1); }) };
68
69
  }
69
70
  }
71
+ const hubContext = () => ({
72
+ pluginArgs: Object.assign(Object.assign({}, IPluginArgs_1.DefaultPluginArgs), { bindHostOrIp: '127.0.0.1' }),
73
+ port: 4799,
74
+ nodeId: 'hub-1',
75
+ });
76
+ const fastCollector = (source, hooks, after) => new NodeMetricsCollector_1.NodeMetricsCollector({
77
+ source,
78
+ hooks,
79
+ after,
80
+ support: typedi_1.Container.get(nodeMetrics_1.NodeMetricsSupport),
81
+ logger: quiet,
82
+ intervalMs: 50,
83
+ });
70
84
  /** The hub's sampler service: this hub's own phones are none, it asks the node every 50 ms. */
71
85
  class HubSideMetrics extends SessionMetricsService_1.SessionMetricsService {
72
86
  constructor() {
@@ -74,11 +88,7 @@ class HubSideMetrics extends SessionMetricsService_1.SessionMetricsService {
74
88
  this.written = [];
75
89
  }
76
90
  context() {
77
- return {
78
- pluginArgs: Object.assign(Object.assign({}, IPluginArgs_1.DefaultPluginArgs), { bindHostOrIp: '127.0.0.1' }),
79
- port: 4799,
80
- nodeId: 'hub-1',
81
- };
91
+ return hubContext();
82
92
  }
83
93
  writeSamples(_id, samples) {
84
94
  return __awaiter(this, void 0, void 0, function* () {
@@ -86,16 +96,29 @@ class HubSideMetrics extends SessionMetricsService_1.SessionMetricsService {
86
96
  });
87
97
  }
88
98
  collectorFor(source, hooks, after) {
89
- return new NodeMetricsCollector_1.NodeMetricsCollector({
90
- source,
91
- hooks,
92
- after,
93
- support: typedi_1.Container.get(nodeMetrics_1.NodeMetricsSupport),
94
- logger: quiet,
95
- intervalMs: 50,
96
- });
99
+ return fastCollector(source, hooks, after);
100
+ }
101
+ }
102
+ /** The same, writing to the hub's database every 100 ms, as the page reads it. */
103
+ class HubStoringMetrics extends SessionMetricsService_1.SessionMetricsService {
104
+ context() {
105
+ return hubContext();
106
+ }
107
+ flushIntervalMs() {
108
+ return 100;
109
+ }
110
+ collectorFor(source, hooks, after) {
111
+ return fastCollector(source, hooks, after);
97
112
  }
98
113
  }
114
+ const untilAsync = (ok_1, ...args_1) => __awaiter(void 0, [ok_1, ...args_1], void 0, function* (ok, ms = 5000) {
115
+ const end = Date.now() + ms;
116
+ while (!(yield ok())) {
117
+ if (Date.now() > end)
118
+ throw new Error('timed out');
119
+ yield new Promise((r) => setTimeout(r, 50));
120
+ }
121
+ });
99
122
  const until = (ok_1, ...args_1) => __awaiter(void 0, [ok_1, ...args_1], void 0, function* (ok, ms = 5000) {
100
123
  const end = Date.now() + ms;
101
124
  while (!ok()) {
@@ -310,6 +333,53 @@ describe('a hub collects a node session’s CPU and memory', function () {
310
333
  yield hub.stop(sessionId);
311
334
  (0, chai_1.expect)(hub.written).to.deep.equal([1000, 2000, 3000]);
312
335
  }));
336
+ it("shows a node session's figures on the hub's own metrics route while it runs", () => __awaiter(this, void 0, void 0, function* () {
337
+ yield boot();
338
+ const sessionId = yield nodeSession();
339
+ nodeMetrics.hooks[0].onSample(at(1000));
340
+ nodeMetrics.hooks[0].onSample(at(2000));
341
+ // The hub's row for the session, as onSessionStarted writes it.
342
+ yield scratch.db.session.create({
343
+ data: {
344
+ id: sessionId,
345
+ device_udid: 'phone-1',
346
+ device_platform: 'android',
347
+ device_version: '14',
348
+ desired_capabilities: '{}',
349
+ session_capabilities: '{}',
350
+ node_id: NODE_ID,
351
+ has_live_video: false,
352
+ status: 'running',
353
+ },
354
+ });
355
+ const hub = new HubStoringMetrics();
356
+ const device = {
357
+ udid: 'phone-1',
358
+ host: nodeOrigin,
359
+ nodeId: NODE_ID,
360
+ platform: 'android',
361
+ realDevice: true,
362
+ };
363
+ hub.start({ sessionId, device, capabilities: {}, source: hubSide(sessionId) });
364
+ // The route asks the server's own service whether the session is sampled.
365
+ typedi_1.Container.set(SessionMetricsService_1.SessionMetricsService, hub);
366
+ try {
367
+ const page = (0, selector_health_fixture_1.selectorHealthApp)(selector_health_fixture_1.ADMIN);
368
+ let body;
369
+ yield untilAsync(() => __awaiter(this, void 0, void 0, function* () {
370
+ var _a;
371
+ body = (yield (0, loopbackRequest_1.default)(page).get(`/session/${sessionId}/metrics`)).body;
372
+ return ((_a = body === null || body === void 0 ? void 0 : body.samples) === null || _a === void 0 ? void 0 : _a.length) === 2;
373
+ }));
374
+ (0, chai_1.expect)(body.recording).to.equal('sampling');
375
+ (0, chai_1.expect)(body.samples.map((x) => x.t)).to.deep.equal([1000, 2000]);
376
+ (0, chai_1.expect)(body.samples[1]).to.include({ deviceCpu: 12, app: 'com.android.settings' });
377
+ }
378
+ finally {
379
+ typedi_1.Container.set(SessionMetricsService_1.SessionMetricsService, nodeMetrics);
380
+ yield hub.stop(sessionId);
381
+ }
382
+ }));
313
383
  it("an older node's sessions say they aren't recorded", () => __awaiter(this, void 0, void 0, function* () {
314
384
  yield boot();
315
385
  const sessionId = yield nodeSession();
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ require("reflect-metadata");
16
+ const chai_1 = require("chai");
17
+ const sinon_1 = __importDefault(require("sinon"));
18
+ const events_1 = require("events");
19
+ const usbmux_1 = __importDefault(require("usbmux"));
20
+ const typedi_1 = require("typedi");
21
+ const appium_ios_device_1 = require("appium-ios-device");
22
+ const iOSTracker_1 = require("../../src/device-managers/iOSTracker");
23
+ const IOSDiscoveryService_1 = require("../../src/device-managers/ios/IOSDiscoveryService");
24
+ const usbmuxd_1 = require("../../src/device-managers/ios/usbmuxd");
25
+ const logger_1 = __importDefault(require("../../src/logger"));
26
+ /**
27
+ * A Linux machine with no usbmuxd (an Android-only node, a container): the
28
+ * tracker's usbmux socket emitted 'error' with nobody listening, Node threw it
29
+ * as an uncaught exception, and Xenon's handler ended the process seconds
30
+ * after boot. Discovery's own poll caught its error but logged it every time.
31
+ */
32
+ const enoent = Object.assign(new Error('connect ENOENT /var/run/usbmuxd'), {
33
+ code: 'ENOENT',
34
+ syscall: 'connect',
35
+ address: '/var/run/usbmuxd',
36
+ });
37
+ const missingSocket = new Error("The usbmuxd socket at '/var/run/usbmuxd' does not exist or is not accessible");
38
+ describe('iOS without usbmuxd', () => {
39
+ let warn;
40
+ let error;
41
+ beforeEach(() => {
42
+ (0, usbmuxd_1.resetUsbmuxdNotice)();
43
+ warn = sinon_1.default.spy();
44
+ error = sinon_1.default.spy();
45
+ sinon_1.default.stub(logger_1.default, 'scope').returns({ warn, error, info: sinon_1.default.spy(), debug: sinon_1.default.spy() });
46
+ });
47
+ afterEach(() => {
48
+ sinon_1.default.restore();
49
+ typedi_1.Container.remove(iOSTracker_1.IosTracker);
50
+ (0, usbmuxd_1.resetUsbmuxdNotice)();
51
+ });
52
+ describe('isUsbmuxdUnavailable', () => {
53
+ it('knows the socket errors and the library’s own message', () => {
54
+ (0, chai_1.expect)((0, usbmuxd_1.isUsbmuxdUnavailable)(enoent)).to.equal(true);
55
+ (0, chai_1.expect)((0, usbmuxd_1.isUsbmuxdUnavailable)(Object.assign(new Error('connect ECONNREFUSED /var/run/usbmuxd'), {
56
+ code: 'ECONNREFUSED',
57
+ address: '/var/run/usbmuxd',
58
+ }))).to.equal(true);
59
+ (0, chai_1.expect)((0, usbmuxd_1.isUsbmuxdUnavailable)(missingSocket)).to.equal(true);
60
+ });
61
+ it('leaves every other error alone', () => {
62
+ (0, chai_1.expect)((0, usbmuxd_1.isUsbmuxdUnavailable)(new Error('Listen failed'))).to.equal(false);
63
+ (0, chai_1.expect)((0, usbmuxd_1.isUsbmuxdUnavailable)(Object.assign(new Error('ENOENT'), { code: 'ENOENT', path: '/tmp/x' }))).to.equal(false);
64
+ (0, chai_1.expect)((0, usbmuxd_1.isUsbmuxdUnavailable)(undefined)).to.equal(false);
65
+ });
66
+ });
67
+ describe('the tracker', () => {
68
+ it('survives the socket failing to connect, and says so once', () => {
69
+ const socket = new events_1.EventEmitter();
70
+ sinon_1.default.stub(usbmux_1.default, 'createListener').returns(socket);
71
+ const tracker = new iOSTracker_1.IosTracker();
72
+ (0, chai_1.expect)(tracker.getListener()).to.equal(socket);
73
+ // An EventEmitter with no 'error' listener throws from emit: the crash.
74
+ (0, chai_1.expect)(() => socket.emit('error', enoent)).not.to.throw();
75
+ (0, chai_1.expect)(() => socket.emit('error', enoent)).not.to.throw();
76
+ (0, chai_1.expect)(warn.callCount).to.equal(1);
77
+ (0, chai_1.expect)(String(warn.firstCall.args[0])).to.match(/usbmuxd isn’t running/);
78
+ });
79
+ it('logs any other socket error rather than crashing', () => {
80
+ const socket = new events_1.EventEmitter();
81
+ sinon_1.default.stub(usbmux_1.default, 'createListener').returns(socket);
82
+ new iOSTracker_1.IosTracker();
83
+ (0, chai_1.expect)(() => socket.emit('error', new Error('Listen failed'))).not.to.throw();
84
+ (0, chai_1.expect)(error.callCount).to.equal(1);
85
+ (0, chai_1.expect)(warn.callCount).to.equal(0);
86
+ });
87
+ });
88
+ describe('discovery', () => {
89
+ it('finds no iPhones, warning once over repeated polls', () => __awaiter(void 0, void 0, void 0, function* () {
90
+ sinon_1.default.stub(appium_ios_device_1.utilities, 'getConnectedDevices').rejects(missingSocket);
91
+ const discovery = new IOSDiscoveryService_1.IOSDiscoveryService({});
92
+ (0, chai_1.expect)(yield discovery.getConnectedDevices()).to.deep.equal([]);
93
+ (0, chai_1.expect)(yield discovery.getConnectedDevices()).to.deep.equal([]);
94
+ (0, chai_1.expect)(warn.callCount).to.equal(1);
95
+ (0, chai_1.expect)(error.callCount).to.equal(0);
96
+ }));
97
+ it('still logs any other failure as an error', () => __awaiter(void 0, void 0, void 0, function* () {
98
+ sinon_1.default.stub(appium_ios_device_1.utilities, 'getConnectedDevices').rejects(new Error('lockdown failed'));
99
+ const discovery = new IOSDiscoveryService_1.IOSDiscoveryService({});
100
+ (0, chai_1.expect)(yield discovery.getConnectedDevices()).to.deep.equal([]);
101
+ (0, chai_1.expect)(error.callCount).to.equal(1);
102
+ (0, chai_1.expect)(warn.callCount).to.equal(0);
103
+ }));
104
+ });
105
+ it('usbmuxdNotice is one warning until it is reset', () => {
106
+ const logger = { warn: sinon_1.default.spy() };
107
+ (0, usbmuxd_1.usbmuxdNotice)(logger, enoent);
108
+ (0, usbmuxd_1.usbmuxdNotice)(logger, enoent);
109
+ (0, chai_1.expect)(logger.warn.callCount).to.equal(1);
110
+ });
111
+ });
@@ -17,6 +17,8 @@ const chai_1 = require("chai");
17
17
  const sinon_1 = __importDefault(require("sinon"));
18
18
  const NodeMetricsCollector_1 = require("../../src/services/metrics/NodeMetricsCollector");
19
19
  const nodeMetrics_1 = require("../../src/services/metrics/nodeMetrics");
20
+ const RemoteSession_1 = require("../../src/sessions/RemoteSession");
21
+ const CloudSession_1 = require("../../src/sessions/CloudSession");
20
22
  const sample = (at) => ({
21
23
  at,
22
24
  deviceCpuPct: 5,
@@ -163,6 +165,16 @@ describe('NodeMetricsCollector: the hub collects a node session’s figures', ()
163
165
  (0, chai_1.expect)(warned).to.have.length(2);
164
166
  (0, chai_1.expect)(c.state()).to.equal('sampling');
165
167
  }));
168
+ it("doesn't wait on a last ask when the node already wasn't answering", () => __awaiter(void 0, void 0, void 0, function* () {
169
+ // A dark node's sessions are ended one after another by the heartbeat;
170
+ // each would wait up to 5 s more for an answer that won't come.
171
+ replies = [{ kind: 'unavailable', reason: 'ECONNREFUSED' }];
172
+ const c = make();
173
+ c.start();
174
+ yield clock.tickAsync(10000);
175
+ yield c.stop();
176
+ (0, chai_1.expect)(asked).to.have.length(1);
177
+ }));
166
178
  it('finishes stopping when the node is unreachable', () => __awaiter(void 0, void 0, void 0, function* () {
167
179
  replies = [{ kind: 'unavailable', reason: 'timeout' }];
168
180
  const c = make();
@@ -188,6 +200,27 @@ describe('NodeMetricsCollector: the hub collects a node session’s figures', ()
188
200
  });
189
201
  describe("readNodeMetricsReply: what a node's answer means", () => {
190
202
  const h = { [nodeMetrics_1.NODE_METRICS_HEADER]: '1' };
203
+ it('keeps only well-formed samples: one bad sample would block every later write', () => {
204
+ const bad = [
205
+ null,
206
+ 'x',
207
+ Object.assign(Object.assign({}, sample(5)), { at: '6' }),
208
+ Object.assign(Object.assign({}, sample(7)), { at: Number.NaN }),
209
+ Object.assign(Object.assign({}, sample(8)), { deviceCpuPct: '12' }),
210
+ Object.assign(Object.assign({}, sample(9)), { appId: 3 }),
211
+ ];
212
+ const reply = (0, nodeMetrics_1.readNodeMetricsReply)(200, h, {
213
+ value: {
214
+ platform: 'android',
215
+ state: 'sampling',
216
+ samples: [sample(1), ...bad, Object.assign(Object.assign({}, sample(2)), { extra: 1 })],
217
+ },
218
+ });
219
+ (0, chai_1.expect)(reply).to.deep.equal({
220
+ kind: 'answer',
221
+ answer: { platform: 'android', state: 'sampling', samples: [sample(1), sample(2)] },
222
+ });
223
+ });
191
224
  it('reads each answer', () => {
192
225
  (0, chai_1.expect)((0, nodeMetrics_1.readNodeMetricsReply)(404, {}, undefined)).to.deep.equal({
193
226
  kind: 'unsupported',
@@ -224,3 +257,23 @@ describe("readNodeMetricsReply: what a node's answer means", () => {
224
257
  });
225
258
  });
226
259
  });
260
+ describe('nodeMetricsSourceOf: only a session a node runs is collected from', () => {
261
+ const options = (cloud) => ({
262
+ sessionId: 's1',
263
+ device: { udid: 'p1', host: 'http://node:4723', platform: 'android', cloud },
264
+ sessionResponse: {},
265
+ xenonOption: {},
266
+ baseUrl: 'http://node:4723/wd/hub',
267
+ });
268
+ it("takes a node's session, never a cloud provider's or this server's own", () => {
269
+ const remote = new RemoteSession_1.RemoteSession(options());
270
+ (0, chai_1.expect)((0, nodeMetrics_1.nodeMetricsSourceOf)(remote)).to.equal(remote);
271
+ // Both inherit nodeMetrics from RemoteSession; neither runs on a node.
272
+ (0, chai_1.expect)((0, nodeMetrics_1.nodeMetricsSourceOf)(new CloudSession_1.CloudSession(options('browserstack')))).to.equal(undefined);
273
+ const local = Object.assign(Object.create(RemoteSession_1.RemoteSession.prototype), {
274
+ getType: () => 'local',
275
+ });
276
+ (0, chai_1.expect)((0, nodeMetrics_1.nodeMetricsSourceOf)(local)).to.equal(undefined);
277
+ (0, chai_1.expect)((0, nodeMetrics_1.nodeMetricsSourceOf)({ nodeOrigin: () => 'x', nodeMetrics: () => __awaiter(void 0, void 0, void 0, function* () { return null; }) })).to.equal(undefined);
278
+ });
279
+ });
@@ -76,7 +76,8 @@ describe("a node's session metrics route", () => {
76
76
  it('reads anything but a time as no `after`', () => {
77
77
  (0, chai_1.expect)((0, nodeSessionMetrics_1.parseAfter)('1500')).to.equal(1500);
78
78
  (0, chai_1.expect)((0, nodeSessionMetrics_1.parseAfter)('1500.5')).to.equal(1500.5);
79
- for (const bad of [undefined, '', 'abc', '-5', '1e3', ['1']]) {
79
+ // A 400-digit number is Infinity: it would drop every sample the node holds.
80
+ for (const bad of [undefined, '', 'abc', '-5', '1e3', ['1'], '9'.repeat(400)]) {
80
81
  (0, chai_1.expect)((0, nodeSessionMetrics_1.parseAfter)(bad), String(bad)).to.equal(null);
81
82
  }
82
83
  });
@@ -1 +1 @@
1
- {"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/appiumBasePath.ts","../src/app/index.ts","../src/app/insertBeforeRoutes.ts","../src/app/registerCommandAuth.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/androidH264Config.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/audit.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/capabilities.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/iosStreamPort.ts","../src/app/routers/nodePhoneControl.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/profileIdentity.ts","../src/app/routers/projects.ts","../src/app/routers/recordingRequests.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/selector-health.ts","../src/app/routers/sessionInsights.ts","../src/app/routers/streamLeave.ts","../src/app/routers/streamStartConflict.ts","../src/app/routers/streamType.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/app/ws/h264StreamWs.ts","../src/app/ws/logcatWs.ts","../src/app/ws/nodeSocketRelay.ts","../src/app/ws/upgradeRouter.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/deviceClaims.ts","../src/data-service/deviceColumns.ts","../src/data-service/deviceFieldOwners.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/clipboardErrors.ts","../src/device-managers/deviceIdentity.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/localDeviceHosts.ts","../src/device-managers/ownDeviceRow.ts","../src/device-managers/android/AndroidH264StreamService.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/android/H264Multiplexer.ts","../src/device-managers/android/LogcatMultiplexer.ts","../src/device-managers/android/LogcatStreamService.ts","../src/device-managers/android/ScrcpyServerSession.ts","../src/device-managers/android/androidIdentity.ts","../src/device-managers/android/androidStreamReuse.ts","../src/device-managers/android/clipboardBroadcast.ts","../src/device-managers/android/displayState.ts","../src/device-managers/android/h264NalParser.ts","../src/device-managers/android/previewHold.ts","../src/device-managers/android/scrcpyVersion.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSLogStreamService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/IOSTunnels.ts","../src/device-managers/ios/WDAClient.ts","../src/device-managers/ios/appleIdentity.ts","../src/device-managers/ios/goIosBinary.ts","../src/device-managers/ios/iosAppIds.ts","../src/device-managers/ios/iosBattery.ts","../src/device-managers/ios/iosStreamDiagnostics.ts","../src/device-managers/ios/tunnelProcess.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/gateway/createHandoff.ts","../src/gateway/defaultGateway.ts","../src/gateway/forwardToNode.ts","../src/gateway/hubSessionToken.ts","../src/gateway/internalCall.ts","../src/gateway/nodeSessionMetrics.ts","../src/gateway/nodeSessionStatus.ts","../src/gateway/nodeWebDriverUrl.ts","../src/gateway/sessionCreate.ts","../src/gateway/sessionGateway.ts","../src/gateway/sessionLocator.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/ffmpegPath.ts","../src/helpers/index.ts","../src/helpers/networkAddresses.ts","../src/helpers/singleFlight.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/commandAuth.ts","../src/middleware/commandCaller.ts","../src/middleware/controlDevice.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/deviceAccessGuard.ts","../src/middleware/deviceTeamGuard.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/middleware/sessionListingFilter.ts","../src/middleware/sessionUpgradeGuard.ts","../src/middleware/verifyCredential.ts","../src/scripts/generate-database-migration.ts","../src/scripts/goIosVersion.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/DisplayStateService.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/EventLogService.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/fillMissingScreenSize.ts","../src/services/passwordResetLink.ts","../src/services/passwordResetMode.ts","../src/services/sessionTokenGate.ts","../src/services/artifacts/ArtifactStore.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/device-access/DeviceTeamResolver.ts","../src/services/device-access/LiveSessionOwners.ts","../src/services/device-access/SessionOwnerResolver.ts","../src/services/device-access/actor.ts","../src/services/device-access/appVisibility.ts","../src/services/device-access/callerTeamIds.ts","../src/services/device-access/deviceAccessPolicy.ts","../src/services/device-access/deviceVisibility.ts","../src/services/device-access/leaseOverride.ts","../src/services/device-access/queueVisibility.ts","../src/services/device-access/sessionVisibility.ts","../src/services/device-access/ticketActorAccess.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/inspector/verifyLocator.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseSessionCaps.ts","../src/services/lease/leaseToken.ts","../src/services/logcat/PackageResolver.ts","../src/services/logcat/logSource.ts","../src/services/logcat/logcatParse.ts","../src/services/logcat/ostraceParse.ts","../src/services/metrics/AndroidMetricsSampler.ts","../src/services/metrics/IOSMetricsSampler.ts","../src/services/metrics/NodeMetricsCollector.ts","../src/services/metrics/NodeMetricsStore.ts","../src/services/metrics/SessionMetricsService.ts","../src/services/metrics/androidMetrics.ts","../src/services/metrics/iosMetrics.ts","../src/services/metrics/metricsBody.ts","../src/services/metrics/nodeMetrics.ts","../src/services/metrics/types.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/activeRecordings.ts","../src/services/recording/annotation-render.ts","../src/services/recording/annotationImage.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/ensureMjpegForRecording.ts","../src/services/recording/manualLock.ts","../src/services/recording/nodeRecordingSource.ts","../src/services/recording/probeDuration.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/recording/recordingCleanup.ts","../src/services/recording/recordingFiles.ts","../src/services/recording/recordingSummary.ts","../src/services/recording/recordingTiming.ts","../src/services/selector-health/access.ts","../src/services/selector-health/healingTrend.ts","../src/services/selector-health/people.ts","../src/services/selector-health/selectorDetail.ts","../src/services/selector-health/selectorKeys.ts","../src/services/selector-health/selectorList.ts","../src/services/selector-health/stateView.ts","../src/services/session/appCapability.ts","../src/services/session/nodeCreateCaps.ts","../src/services/session/sessionCredentials.ts","../src/services/session/sessionIdentity.ts","../src/services/session/xenonOptions.ts","../src/services/telemetry/attributes.ts","../src/services/token/AppDownloadTicketService.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/services/token/singleUseLedger.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/sessions/appiumUmbrella.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/appium-umbrella.ts","../test/helpers/artifact-store.ts","../test/helpers/container-registration.ts","../test/helpers/fake-device-table.ts","../test/helpers/loki-stores.ts","../test/helpers/loopbackRequest.ts","../test/helpers/loopbackServer.ts","../test/helpers/own-node-id.ts","../test/helpers/scratch-database.ts","../test/helpers/scratch-port-leases.ts","../test/helpers/seedUser.ts","../test/helpers/selector-health-fixture.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/audit-ingest.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/healing-events-sessionfilter.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/prisma-device-store-add-devices.spec.ts","../test/integration/prisma-device-store-team-filter.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-health-endpoint.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-apps.spec.ts","../test/integration/team-visibility-control.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-leases.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/team-visibility-sessions.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/setup/scratch-default-database.js","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/AppDownloadTicketService.spec.ts","../test/unit/ArtifactStore.spec.ts","../test/unit/AutowaitService.spec.ts","../test/unit/CapabilitiesRouter.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/EventLogService.spec.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/JwtKeyService.spec.ts","../test/unit/McpScopes.spec.ts","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/ProjectsRouter.spec.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/SessionLifecycleCaps.spec.ts","../test/unit/SessionTokenGate.spec.ts","../test/unit/StreamTicketService.spec.ts","../test/unit/TeamService.test.ts","../test/unit/TokenEndpoint.spec.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/active-recordings.spec.ts","../test/unit/aggregate-hotspots-session-scope.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/android-clipboard.spec.ts","../test/unit/android-h264-config.spec.ts","../test/unit/android-h264-service.spec.ts","../test/unit/android-identity.spec.ts","../test/unit/android-preview-hold.spec.ts","../test/unit/android-stream-adb-path.spec.ts","../test/unit/android-stream-encoder.spec.ts","../test/unit/android-stream-fast-start.spec.ts","../test/unit/android-stream-release.spec.ts","../test/unit/android-stream-reuse-service.spec.ts","../test/unit/android-stream-reuse.spec.ts","../test/unit/android-stream-stall-eof.spec.ts","../test/unit/annotation-image.spec.ts","../test/unit/annotation-render.spec.ts","../test/unit/apple-identity.spec.ts","../test/unit/apps-download.spec.ts","../test/unit/apps-team-visibility.spec.ts","../test/unit/auth-disabled-resolution.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.appTicket.spec.ts","../test/unit/authMiddleware.bearer.spec.ts","../test/unit/authMiddleware.mcpAudience.spec.ts","../test/unit/authMiddleware.streamTicket.spec.ts","../test/unit/authMiddleware.test.ts","../test/unit/boot-go-ios-reap.spec.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/cliargs-admin-only.spec.ts","../test/unit/clipboard-route.spec.ts","../test/unit/command-auth-appium-server.spec.ts","../test/unit/command-auth.spec.ts","../test/unit/command-caller.spec.ts","../test/unit/commands.spec.js","../test/unit/composite-geometry.spec.ts","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/container-registration.spec.ts","../test/unit/control-device-lookup.spec.ts","../test/unit/control-forward-decision.spec.ts","../test/unit/control-lookup-failure.spec.ts","../test/unit/create-error-message.spec.ts","../test/unit/create-handoff.spec.ts","../test/unit/dashboard-events-metrics.spec.ts","../test/unit/dashboard-events-team-scope.spec.ts","../test/unit/device-access-guard.spec.ts","../test/unit/device-access-policy.spec.ts","../test/unit/device-columns.spec.ts","../test/unit/device-service.spec.ts","../test/unit/device-store-clear-at-boot.spec.ts","../test/unit/device-sync-lost-update.spec.ts","../test/unit/device-team-guard.spec.ts","../test/unit/device-team-resolver.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/display-state.spec.ts","../test/unit/enrich-devices-team-names.test.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/extract-team-cap.spec.ts","../test/unit/ffmpeg-path.spec.ts","../test/unit/fill-missing-screen-size.spec.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/go-ios-version.spec.ts","../test/unit/grid-admin-only.spec.ts","../test/unit/h264-multiplexer.spec.ts","../test/unit/h264-nal-parser.spec.ts","../test/unit/h264-ws-frame.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-no-cost.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/healing-trend.spec.ts","../test/unit/health-monitor-own-phones.spec.ts","../test/unit/health-monitor-stream-lookup.spec.ts","../test/unit/helpers.spec.ts","../test/unit/hub-boot-sweep-recovery.spec.ts","../test/unit/hub-create-once.spec.ts","../test/unit/hub-create-session-umbrella.spec.ts","../test/unit/hub-gateway-create-appium-server.spec.ts","../test/unit/hub-node-control-forward.spec.ts","../test/unit/hub-node-gateway-appium-server.spec.ts","../test/unit/hub-node-race.spec.ts","../test/unit/hub-node-same-host.spec.ts","../test/unit/hub-node-session-metrics.spec.ts","../test/unit/hub-register-removal.spec.ts","../test/unit/hub-remote-session-heartbeat.spec.ts","../test/unit/hub-routed-session-recovery.spec.ts","../test/unit/hub-session-token.spec.ts","../test/unit/insert-before-routes.spec.ts","../test/unit/inspector-hierarchy.spec.ts","../test/unit/install-repository-app-team.spec.ts","../test/unit/internal-call.spec.ts","../test/unit/ios-discovery-same-host.spec.ts","../test/unit/ios-go-ios-tunnel-env.spec.ts","../test/unit/ios-idle-hold.spec.ts","../test/unit/ios-no-network-fallback.spec.ts","../test/unit/ios-stream-appium-tunnel.spec.ts","../test/unit/ios-stream-port-leases.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/ios-tunnels.spec.ts","../test/unit/ios-wda-status-identity.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.spec.ts","../test/unit/is-xenon-running.spec.ts","../test/unit/logcat-multiplexer.spec.ts","../test/unit/logcat-parse.spec.ts","../test/unit/logcat-stream-service.spec.ts","../test/unit/logcat-ws.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/loopback-request.spec.ts","../test/unit/manualLock.test.ts","../test/unit/mark-node-busy-loki.spec.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.ts","../test/unit/node-create-caps.spec.ts","../test/unit/node-gateway-create-appium-server.spec.ts","../test/unit/node-hub-session-owner.spec.ts","../test/unit/node-metrics-collector.spec.ts","../test/unit/node-metrics-store.spec.ts","../test/unit/node-phone-control.spec.ts","../test/unit/node-recording-relay.spec.ts","../test/unit/node-session-metrics-route.spec.ts","../test/unit/node-socket-relay.spec.ts","../test/unit/normalize-eol.spec.js","../test/unit/omni-vision.spec.ts","../test/unit/ostrace-parse.spec.ts","../test/unit/package-resolver.spec.ts","../test/unit/passwordResetMode.test.ts","../test/unit/plugin.spec.ts","../test/unit/port-allocator-os-probe.spec.ts","../test/unit/port-allocator-pairs.spec.ts","../test/unit/port-exhaustion.spec.ts","../test/unit/prisma.spec.ts","../test/unit/probe-duration.spec.ts","../test/unit/profile-router.test.ts","../test/unit/profileIdentity.spec.ts","../test/unit/proof-bundle.spec.ts","../test/unit/queue-requester.spec.ts","../test/unit/queue-team-scope-routes.spec.ts","../test/unit/queue-visibility.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-cleanup.spec.ts","../test/unit/recording-downloads-visibility.spec.ts","../test/unit/recording-files.spec.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-requests.spec.ts","../test/unit/recording-source-ended.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/recording-summary.spec.ts","../test/unit/recording-timing.spec.ts","../test/unit/recordings-library-routes.spec.ts","../test/unit/recordings-write-visibility.spec.ts","../test/unit/remote-session-create.spec.ts","../test/unit/remux-to-standard-mp4.spec.ts","../test/unit/reservation-team-visibility.spec.ts","../test/unit/reset-link.test.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/schema-required-args.spec.ts","../test/unit/scrcpy-server-session.spec.ts","../test/unit/scrcpy-version.spec.ts","../test/unit/screenshot-route.spec.ts","../test/unit/selector-event-model.spec.ts","../test/unit/selector-health-actions.spec.ts","../test/unit/selector-health-detail.spec.ts","../test/unit/selector-health-list.spec.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/selector-verification-missed-regression.spec.ts","../test/unit/session-app-resolution.spec.ts","../test/unit/session-assets.spec.ts","../test/unit/session-attribution-wiring.spec.ts","../test/unit/session-create-layer.spec.ts","../test/unit/session-credential-strip.spec.ts","../test/unit/session-credentials.spec.ts","../test/unit/session-identity.spec.ts","../test/unit/session-list-insights.spec.ts","../test/unit/session-listing-auth.spec.ts","../test/unit/session-locator.spec.ts","../test/unit/session-log-indexes.spec.ts","../test/unit/session-metrics-lifecycle.spec.ts","../test/unit/session-metrics-parse.spec.ts","../test/unit/session-metrics-route.spec.ts","../test/unit/session-metrics-samplers.spec.ts","../test/unit/session-metrics-service.spec.ts","../test/unit/session-node-calls.spec.ts","../test/unit/session-owner-resolver.spec.ts","../test/unit/session-recovery-metrics.spec.ts","../test/unit/session-recovery-routing.spec.ts","../test/unit/session-upgrade-guard.spec.ts","../test/unit/session-visibility.spec.ts","../test/unit/shutdown-drain-remote.spec.ts","../test/unit/shutdown-sync-nets.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socket-team-scope.integration.spec.ts","../test/unit/socketServer.bearer.spec.ts","../test/unit/socketServer.scopedEmit.spec.ts","../test/unit/socketServer.sessionCookie.spec.ts","../test/unit/stored-session-capabilities.spec.ts","../test/unit/stream-leave-route.spec.ts","../test/unit/stream-leave.spec.ts","../test/unit/stream-own-device-row.spec.ts","../test/unit/stream-start-conflict.spec.ts","../test/unit/stream-status-type.spec.ts","../test/unit/stream-stop-ownership.spec.ts","../test/unit/stream-stop-recording.spec.ts","../test/unit/stream-ticket-identity.spec.ts","../test/unit/stream-viewer-hangup.spec.ts","../test/unit/stream-watchdog-timers.spec.ts","../test/unit/sync-dir.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/upgrade-router.spec.ts","../test/unit/upload-install-route.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/verify-credential.spec.ts","../test/unit/verify-locator.spec.ts","../test/unit/video-pipeline-args.spec.ts","../test/unit/video-pipeline-exit.spec.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/wda-cap-injection.spec.ts","../test/unit/webdriver-info-route.spec.ts","../test/unit/ws-upgrade-routing-appium-server.spec.ts","../test/unit/xenon-options.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/allocate-lease-branch.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/lease-override.spec.ts","../test/unit/lease/lease-reap-held-phone.spec.ts","../test/unit/lease/lease-session-ownership.spec.ts","../test/unit/lease/lease-sweeper-expiry.spec.ts","../test/unit/lease/lease-team-visibility.spec.ts","../test/unit/lease/lease-token-log-filter.spec.ts","../test/unit/lease/lease-token-oracle.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/lease/session-lease-proof.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
1
+ {"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/appiumBasePath.ts","../src/app/index.ts","../src/app/insertBeforeRoutes.ts","../src/app/registerCommandAuth.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/androidH264Config.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/audit.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/capabilities.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/iosStreamPort.ts","../src/app/routers/nodePhoneControl.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/profileIdentity.ts","../src/app/routers/projects.ts","../src/app/routers/recordingRequests.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/selector-health.ts","../src/app/routers/sessionInsights.ts","../src/app/routers/streamLeave.ts","../src/app/routers/streamStartConflict.ts","../src/app/routers/streamType.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/app/ws/h264StreamWs.ts","../src/app/ws/logcatWs.ts","../src/app/ws/nodeSocketRelay.ts","../src/app/ws/upgradeRouter.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/deviceClaims.ts","../src/data-service/deviceColumns.ts","../src/data-service/deviceFieldOwners.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/clipboardErrors.ts","../src/device-managers/deviceIdentity.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/localDeviceHosts.ts","../src/device-managers/ownDeviceRow.ts","../src/device-managers/android/AndroidH264StreamService.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/android/H264Multiplexer.ts","../src/device-managers/android/LogcatMultiplexer.ts","../src/device-managers/android/LogcatStreamService.ts","../src/device-managers/android/ScrcpyServerSession.ts","../src/device-managers/android/androidIdentity.ts","../src/device-managers/android/androidStreamReuse.ts","../src/device-managers/android/clipboardBroadcast.ts","../src/device-managers/android/displayState.ts","../src/device-managers/android/h264NalParser.ts","../src/device-managers/android/previewHold.ts","../src/device-managers/android/scrcpyVersion.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSLogStreamService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/IOSTunnels.ts","../src/device-managers/ios/WDAClient.ts","../src/device-managers/ios/appleIdentity.ts","../src/device-managers/ios/goIosBinary.ts","../src/device-managers/ios/iosAppIds.ts","../src/device-managers/ios/iosBattery.ts","../src/device-managers/ios/iosStreamDiagnostics.ts","../src/device-managers/ios/tunnelProcess.ts","../src/device-managers/ios/usbmuxd.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/gateway/createHandoff.ts","../src/gateway/defaultGateway.ts","../src/gateway/forwardToNode.ts","../src/gateway/hubSessionToken.ts","../src/gateway/internalCall.ts","../src/gateway/nodeSessionMetrics.ts","../src/gateway/nodeSessionStatus.ts","../src/gateway/nodeWebDriverUrl.ts","../src/gateway/sessionCreate.ts","../src/gateway/sessionGateway.ts","../src/gateway/sessionLocator.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/ffmpegPath.ts","../src/helpers/index.ts","../src/helpers/networkAddresses.ts","../src/helpers/singleFlight.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/commandAuth.ts","../src/middleware/commandCaller.ts","../src/middleware/controlDevice.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/deviceAccessGuard.ts","../src/middleware/deviceTeamGuard.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/middleware/sessionListingFilter.ts","../src/middleware/sessionUpgradeGuard.ts","../src/middleware/verifyCredential.ts","../src/scripts/generate-database-migration.ts","../src/scripts/goIosVersion.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/DisplayStateService.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/EventLogService.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/fillMissingScreenSize.ts","../src/services/passwordResetLink.ts","../src/services/passwordResetMode.ts","../src/services/sessionTokenGate.ts","../src/services/artifacts/ArtifactStore.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/device-access/DeviceTeamResolver.ts","../src/services/device-access/LiveSessionOwners.ts","../src/services/device-access/SessionOwnerResolver.ts","../src/services/device-access/actor.ts","../src/services/device-access/appVisibility.ts","../src/services/device-access/callerTeamIds.ts","../src/services/device-access/deviceAccessPolicy.ts","../src/services/device-access/deviceVisibility.ts","../src/services/device-access/leaseOverride.ts","../src/services/device-access/queueVisibility.ts","../src/services/device-access/sessionVisibility.ts","../src/services/device-access/ticketActorAccess.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/inspector/verifyLocator.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseSessionCaps.ts","../src/services/lease/leaseToken.ts","../src/services/logcat/PackageResolver.ts","../src/services/logcat/logSource.ts","../src/services/logcat/logcatParse.ts","../src/services/logcat/ostraceParse.ts","../src/services/metrics/AndroidMetricsSampler.ts","../src/services/metrics/IOSMetricsSampler.ts","../src/services/metrics/NodeMetricsCollector.ts","../src/services/metrics/NodeMetricsStore.ts","../src/services/metrics/SessionMetricsService.ts","../src/services/metrics/androidMetrics.ts","../src/services/metrics/iosMetrics.ts","../src/services/metrics/metricsBody.ts","../src/services/metrics/nodeMetrics.ts","../src/services/metrics/types.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/activeRecordings.ts","../src/services/recording/annotation-render.ts","../src/services/recording/annotationImage.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/ensureMjpegForRecording.ts","../src/services/recording/manualLock.ts","../src/services/recording/nodeRecordingSource.ts","../src/services/recording/probeDuration.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/recording/recordingCleanup.ts","../src/services/recording/recordingFiles.ts","../src/services/recording/recordingSummary.ts","../src/services/recording/recordingTiming.ts","../src/services/selector-health/access.ts","../src/services/selector-health/healingTrend.ts","../src/services/selector-health/people.ts","../src/services/selector-health/selectorDetail.ts","../src/services/selector-health/selectorKeys.ts","../src/services/selector-health/selectorList.ts","../src/services/selector-health/stateView.ts","../src/services/session/appCapability.ts","../src/services/session/nodeCreateCaps.ts","../src/services/session/sessionCredentials.ts","../src/services/session/sessionIdentity.ts","../src/services/session/xenonOptions.ts","../src/services/telemetry/attributes.ts","../src/services/token/AppDownloadTicketService.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/services/token/singleUseLedger.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/sessions/appiumUmbrella.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/appium-umbrella.ts","../test/helpers/artifact-store.ts","../test/helpers/container-registration.ts","../test/helpers/fake-device-table.ts","../test/helpers/loki-stores.ts","../test/helpers/loopbackRequest.ts","../test/helpers/loopbackServer.ts","../test/helpers/own-node-id.ts","../test/helpers/scratch-database.ts","../test/helpers/scratch-port-leases.ts","../test/helpers/seedUser.ts","../test/helpers/selector-health-fixture.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/audit-ingest.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/healing-events-sessionfilter.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/prisma-device-store-add-devices.spec.ts","../test/integration/prisma-device-store-team-filter.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-health-endpoint.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-apps.spec.ts","../test/integration/team-visibility-control.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-leases.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/team-visibility-sessions.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/setup/scratch-default-database.js","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/AppDownloadTicketService.spec.ts","../test/unit/ArtifactStore.spec.ts","../test/unit/AutowaitService.spec.ts","../test/unit/CapabilitiesRouter.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/EventLogService.spec.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/JwtKeyService.spec.ts","../test/unit/McpScopes.spec.ts","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/ProjectsRouter.spec.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/SessionLifecycleCaps.spec.ts","../test/unit/SessionTokenGate.spec.ts","../test/unit/StreamTicketService.spec.ts","../test/unit/TeamService.test.ts","../test/unit/TokenEndpoint.spec.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/active-recordings.spec.ts","../test/unit/aggregate-hotspots-session-scope.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/android-clipboard.spec.ts","../test/unit/android-h264-config.spec.ts","../test/unit/android-h264-service.spec.ts","../test/unit/android-identity.spec.ts","../test/unit/android-preview-hold.spec.ts","../test/unit/android-stream-adb-path.spec.ts","../test/unit/android-stream-encoder.spec.ts","../test/unit/android-stream-fast-start.spec.ts","../test/unit/android-stream-release.spec.ts","../test/unit/android-stream-reuse-service.spec.ts","../test/unit/android-stream-reuse.spec.ts","../test/unit/android-stream-stall-eof.spec.ts","../test/unit/annotation-image.spec.ts","../test/unit/annotation-render.spec.ts","../test/unit/apple-identity.spec.ts","../test/unit/apps-download.spec.ts","../test/unit/apps-team-visibility.spec.ts","../test/unit/auth-disabled-resolution.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.appTicket.spec.ts","../test/unit/authMiddleware.bearer.spec.ts","../test/unit/authMiddleware.mcpAudience.spec.ts","../test/unit/authMiddleware.streamTicket.spec.ts","../test/unit/authMiddleware.test.ts","../test/unit/boot-go-ios-reap.spec.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/cliargs-admin-only.spec.ts","../test/unit/clipboard-route.spec.ts","../test/unit/command-auth-appium-server.spec.ts","../test/unit/command-auth.spec.ts","../test/unit/command-caller.spec.ts","../test/unit/commands.spec.js","../test/unit/composite-geometry.spec.ts","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/container-registration.spec.ts","../test/unit/control-device-lookup.spec.ts","../test/unit/control-forward-decision.spec.ts","../test/unit/control-lookup-failure.spec.ts","../test/unit/create-error-message.spec.ts","../test/unit/create-handoff.spec.ts","../test/unit/dashboard-events-metrics.spec.ts","../test/unit/dashboard-events-team-scope.spec.ts","../test/unit/device-access-guard.spec.ts","../test/unit/device-access-policy.spec.ts","../test/unit/device-columns.spec.ts","../test/unit/device-service.spec.ts","../test/unit/device-store-clear-at-boot.spec.ts","../test/unit/device-sync-lost-update.spec.ts","../test/unit/device-team-guard.spec.ts","../test/unit/device-team-resolver.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/display-state.spec.ts","../test/unit/enrich-devices-team-names.test.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/extract-team-cap.spec.ts","../test/unit/ffmpeg-path.spec.ts","../test/unit/fill-missing-screen-size.spec.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/go-ios-version.spec.ts","../test/unit/grid-admin-only.spec.ts","../test/unit/h264-multiplexer.spec.ts","../test/unit/h264-nal-parser.spec.ts","../test/unit/h264-ws-frame.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-no-cost.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/healing-trend.spec.ts","../test/unit/health-monitor-own-phones.spec.ts","../test/unit/health-monitor-stream-lookup.spec.ts","../test/unit/helpers.spec.ts","../test/unit/hub-boot-sweep-recovery.spec.ts","../test/unit/hub-create-once.spec.ts","../test/unit/hub-create-session-umbrella.spec.ts","../test/unit/hub-gateway-create-appium-server.spec.ts","../test/unit/hub-node-control-forward.spec.ts","../test/unit/hub-node-gateway-appium-server.spec.ts","../test/unit/hub-node-race.spec.ts","../test/unit/hub-node-same-host.spec.ts","../test/unit/hub-node-session-metrics.spec.ts","../test/unit/hub-register-removal.spec.ts","../test/unit/hub-remote-session-heartbeat.spec.ts","../test/unit/hub-routed-session-recovery.spec.ts","../test/unit/hub-session-token.spec.ts","../test/unit/insert-before-routes.spec.ts","../test/unit/inspector-hierarchy.spec.ts","../test/unit/install-repository-app-team.spec.ts","../test/unit/internal-call.spec.ts","../test/unit/ios-discovery-same-host.spec.ts","../test/unit/ios-go-ios-tunnel-env.spec.ts","../test/unit/ios-idle-hold.spec.ts","../test/unit/ios-no-network-fallback.spec.ts","../test/unit/ios-stream-appium-tunnel.spec.ts","../test/unit/ios-stream-port-leases.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/ios-tunnels.spec.ts","../test/unit/ios-usbmuxd-missing.spec.ts","../test/unit/ios-wda-status-identity.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.spec.ts","../test/unit/is-xenon-running.spec.ts","../test/unit/logcat-multiplexer.spec.ts","../test/unit/logcat-parse.spec.ts","../test/unit/logcat-stream-service.spec.ts","../test/unit/logcat-ws.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/loopback-request.spec.ts","../test/unit/manualLock.test.ts","../test/unit/mark-node-busy-loki.spec.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.ts","../test/unit/node-create-caps.spec.ts","../test/unit/node-gateway-create-appium-server.spec.ts","../test/unit/node-hub-session-owner.spec.ts","../test/unit/node-metrics-collector.spec.ts","../test/unit/node-metrics-store.spec.ts","../test/unit/node-phone-control.spec.ts","../test/unit/node-recording-relay.spec.ts","../test/unit/node-session-metrics-route.spec.ts","../test/unit/node-socket-relay.spec.ts","../test/unit/normalize-eol.spec.js","../test/unit/omni-vision.spec.ts","../test/unit/ostrace-parse.spec.ts","../test/unit/package-resolver.spec.ts","../test/unit/passwordResetMode.test.ts","../test/unit/plugin.spec.ts","../test/unit/port-allocator-os-probe.spec.ts","../test/unit/port-allocator-pairs.spec.ts","../test/unit/port-exhaustion.spec.ts","../test/unit/prisma.spec.ts","../test/unit/probe-duration.spec.ts","../test/unit/profile-router.test.ts","../test/unit/profileIdentity.spec.ts","../test/unit/proof-bundle.spec.ts","../test/unit/queue-requester.spec.ts","../test/unit/queue-team-scope-routes.spec.ts","../test/unit/queue-visibility.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-cleanup.spec.ts","../test/unit/recording-downloads-visibility.spec.ts","../test/unit/recording-files.spec.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-requests.spec.ts","../test/unit/recording-source-ended.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/recording-summary.spec.ts","../test/unit/recording-timing.spec.ts","../test/unit/recordings-library-routes.spec.ts","../test/unit/recordings-write-visibility.spec.ts","../test/unit/remote-session-create.spec.ts","../test/unit/remux-to-standard-mp4.spec.ts","../test/unit/reservation-team-visibility.spec.ts","../test/unit/reset-link.test.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/schema-required-args.spec.ts","../test/unit/scrcpy-server-session.spec.ts","../test/unit/scrcpy-version.spec.ts","../test/unit/screenshot-route.spec.ts","../test/unit/selector-event-model.spec.ts","../test/unit/selector-health-actions.spec.ts","../test/unit/selector-health-detail.spec.ts","../test/unit/selector-health-list.spec.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/selector-verification-missed-regression.spec.ts","../test/unit/session-app-resolution.spec.ts","../test/unit/session-assets.spec.ts","../test/unit/session-attribution-wiring.spec.ts","../test/unit/session-create-layer.spec.ts","../test/unit/session-credential-strip.spec.ts","../test/unit/session-credentials.spec.ts","../test/unit/session-identity.spec.ts","../test/unit/session-list-insights.spec.ts","../test/unit/session-listing-auth.spec.ts","../test/unit/session-locator.spec.ts","../test/unit/session-log-indexes.spec.ts","../test/unit/session-metrics-lifecycle.spec.ts","../test/unit/session-metrics-parse.spec.ts","../test/unit/session-metrics-route.spec.ts","../test/unit/session-metrics-samplers.spec.ts","../test/unit/session-metrics-service.spec.ts","../test/unit/session-node-calls.spec.ts","../test/unit/session-owner-resolver.spec.ts","../test/unit/session-recovery-metrics.spec.ts","../test/unit/session-recovery-routing.spec.ts","../test/unit/session-upgrade-guard.spec.ts","../test/unit/session-visibility.spec.ts","../test/unit/shutdown-drain-remote.spec.ts","../test/unit/shutdown-sync-nets.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socket-team-scope.integration.spec.ts","../test/unit/socketServer.bearer.spec.ts","../test/unit/socketServer.scopedEmit.spec.ts","../test/unit/socketServer.sessionCookie.spec.ts","../test/unit/stored-session-capabilities.spec.ts","../test/unit/stream-leave-route.spec.ts","../test/unit/stream-leave.spec.ts","../test/unit/stream-own-device-row.spec.ts","../test/unit/stream-start-conflict.spec.ts","../test/unit/stream-status-type.spec.ts","../test/unit/stream-stop-ownership.spec.ts","../test/unit/stream-stop-recording.spec.ts","../test/unit/stream-ticket-identity.spec.ts","../test/unit/stream-viewer-hangup.spec.ts","../test/unit/stream-watchdog-timers.spec.ts","../test/unit/sync-dir.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/upgrade-router.spec.ts","../test/unit/upload-install-route.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/verify-credential.spec.ts","../test/unit/verify-locator.spec.ts","../test/unit/video-pipeline-args.spec.ts","../test/unit/video-pipeline-exit.spec.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/wda-cap-injection.spec.ts","../test/unit/webdriver-info-route.spec.ts","../test/unit/ws-upgrade-routing-appium-server.spec.ts","../test/unit/xenon-options.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/allocate-lease-branch.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/lease-override.spec.ts","../test/unit/lease/lease-reap-held-phone.spec.ts","../test/unit/lease/lease-session-ownership.spec.ts","../test/unit/lease/lease-sweeper-expiry.spec.ts","../test/unit/lease/lease-team-visibility.spec.ts","../test/unit/lease/lease-token-log-filter.spec.ts","../test/unit/lease/lease-token-oracle.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/lease/session-lease-proof.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenon-device-management/xenon",
3
- "version": "2.11.0",
3
+ "version": "2.12.0",
4
4
  "description": "Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.",
5
5
  "main": "./lib/src/index.js",
6
6
  "exports": {