@xenon-device-management/xenon 1.26.2 → 1.28.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.
- package/lib/package.json +1 -1
- package/lib/public/assets/{ApiKeyGate-vELAdQLu.js → ApiKeyGate-CYrHWuf9.js} +1 -1
- package/lib/public/assets/{BugReportButton-ySiZDywe.js → BugReportButton-CRRZnSs2.js} +1 -1
- package/lib/public/assets/{DeviceMosaicView-Chtp0wAI.js → DeviceMosaicView-Dw7dK-Ri.js} +1 -1
- package/lib/public/assets/{EmptyState-CYQYScPo.js → EmptyState-BDSDbxbe.js} +1 -1
- package/lib/public/assets/{FieldGroup-Dea68RfI.js → FieldGroup-DTSy35Hp.js} +1 -1
- package/lib/public/assets/{Modal-BgzTzImP.js → Modal-BC9RPZeO.js} +1 -1
- package/lib/public/assets/{SegmentedControl-DyRq9blY.js → SegmentedControl-DUw7pxfw.js} +1 -1
- package/lib/public/assets/{SettingCard-CardwBu3.js → SettingCard-DwHb-9y7.js} +1 -1
- package/lib/public/assets/{Table-BczCxsDm.js → Table-C167c0iD.js} +1 -1
- package/lib/public/assets/{activity-CS-Op-T6.js → activity-C8ktgelv.js} +1 -1
- package/lib/public/assets/{ai-settings-CIvB7rNM.js → ai-settings-BtH8D-Vk.js} +3 -3
- package/lib/public/assets/{api-keys-peJzllzQ.js → api-keys-D0CPHe_-.js} +1 -1
- package/lib/public/assets/{apps-__WvcJaP.js → apps-f6Z9888a.js} +3 -3
- package/lib/public/assets/{arrow-left-Dx-cXFLT.js → arrow-left-CEnrTC1h.js} +1 -1
- package/lib/public/assets/{arrow-right-Ax_FfBMv.js → arrow-right-DJbja5Vo.js} +1 -1
- package/lib/public/assets/{arrow-up-right-B6uJmGeA.js → arrow-up-right-DvIZquNN.js} +1 -1
- package/lib/public/assets/{auth-shell-BQqcjjC9.js → auth-shell-5XCL86e9.js} +2 -2
- package/lib/public/assets/{builds-page-BA-_iEjx.js → builds-page-DQbsMgZp.js} +1 -1
- package/lib/public/assets/{button-DcbnByKB.js → button-CMj-iXRu.js} +1 -1
- package/lib/public/assets/{calendar-C3pYg1V7.js → calendar-BKb9JzMb.js} +1 -1
- package/lib/public/assets/{check-DKdLfzhJ.js → check-BioFa43z.js} +1 -1
- package/lib/public/assets/{chevron-left-Bb9PBLG5.js → chevron-left-BfiSwNHE.js} +1 -1
- package/lib/public/assets/{chevron-right-DJcpeY_o.js → chevron-right-BLqjv9Fz.js} +1 -1
- package/lib/public/assets/{circle-check-DY6ntqp3.js → circle-check-N7nCeFZH.js} +1 -1
- package/lib/public/assets/{circle-x-DgK9drRH.js → circle-x-DzRW2cW-.js} +1 -1
- package/lib/public/assets/{clock-I9zEVPan.js → clock-Q8bhs7zV.js} +1 -1
- package/lib/public/assets/{copy-Dy3oRuWT.js → copy-Dh1ppPe1.js} +1 -1
- package/lib/public/assets/device-explorer-Cbwojnbb.js +277 -0
- package/lib/public/assets/device-explorer-CcLOID3w.css +1 -0
- package/lib/public/assets/{download-BotTmDty.js → download-Dit5_Lob.js} +1 -1
- package/lib/public/assets/{forgot-password-BaWiD2U2.js → forgot-password-yhK1Eo6h.js} +1 -1
- package/lib/public/assets/{funnel-D2Qw4nTX.js → funnel-DQo9dvhT.js} +1 -1
- package/lib/public/assets/{index-CI9Nz3HY.js → index-kcl0icXA.js} +2 -2
- package/lib/public/assets/{input-cBBGau4X.js → input-DwXEwtQD.js} +1 -1
- package/lib/public/assets/{keycodes-CY4uwulo.js → keycodes-mlL7WkFd.js} +1 -1
- package/lib/public/assets/{layers-MHwJM2Ll.js → layers-DFEJsDA2.js} +1 -1
- package/lib/public/assets/{lock-Bpc8rJFu.js → lock-DVGX1wMR.js} +1 -1
- package/lib/public/assets/{login-BmcyszP5.js → login-BtczO6mT.js} +1 -1
- package/lib/public/assets/{maintenance-settings-DMFVuToe.js → maintenance-settings-BNkCNkdA.js} +2 -2
- package/lib/public/assets/{monitor-irjK6PRV.js → monitor-DXiFh_zm.js} +1 -1
- package/lib/public/assets/mouse-pointer-2-iiFLrBfo.js +6 -0
- package/lib/public/assets/{network-CVZ32MhH.js → network-D-64m0lI.js} +1 -1
- package/lib/public/assets/{overview-DRRSIpnD.js → overview-Bs8fij0f.js} +1 -1
- package/lib/public/assets/{page-header-Bl7uTiQF.js → page-header-2aP5HfMz.js} +1 -1
- package/lib/public/assets/{plus-C3lvaMcL.js → plus-l0nFcN3u.js} +1 -1
- package/lib/public/assets/{profile-page-B3wsnR1n.js → profile-page-DRQxEDPv.js} +1 -1
- package/lib/public/assets/{reset-password-BIGj_ULj.js → reset-password-TeZbTlY3.js} +1 -1
- package/lib/public/assets/{runbook-page-DEznNZhc.js → runbook-page-CfB3Sgqd.js} +1 -1
- package/lib/public/assets/{select-BpuZWZuE.js → select-CfLeV0bn.js} +1 -1
- package/lib/public/assets/{selector-detail-page-ZCvmtQ5Y.js → selector-detail-page-sjSLgf2y.js} +1 -1
- package/lib/public/assets/{selector-health-D-hvfY2E.js → selector-health-DobHOezq.js} +1 -1
- package/lib/public/assets/{selector-health-page-C0ZqZ_VT.js → selector-health-page-BeGTmjeJ.js} +1 -1
- package/lib/public/assets/{session-detail-page-Bv7IwFTQ.js → session-detail-page-B7Be2Uxw.js} +1 -1
- package/lib/public/assets/settings-DWlkn05y.js +6 -0
- package/lib/public/assets/{status-pill-outline-B5dWsaer.js → status-pill-outline-DqZaavRm.js} +1 -1
- package/lib/public/assets/{tablet-DxwkBlhd.js → tablet-D2ApmdVm.js} +1 -1
- package/lib/public/assets/{teams-D3s8GhkG.js → teams-DVm0mUGI.js} +1 -1
- package/lib/public/assets/{trash-2-Dyf4Jcyk.js → trash-2-BklI15pS.js} +1 -1
- package/lib/public/assets/{upload-B6ZJ1_f1.js → upload-BMYoLWMh.js} +1 -1
- package/lib/public/assets/{use-password-reset-mode-B-oOrt1d.js → use-password-reset-mode-Dx_zeU5K.js} +1 -1
- package/lib/public/assets/{users-QfiFclLn.js → users-CnVdUoqL.js} +1 -1
- package/lib/public/assets/{users-BfvPE2wX.js → users-DqVUPDed.js} +1 -1
- package/lib/public/assets/{video-off-C2quR4KF.js → video-off-DEmVhLd9.js} +1 -1
- package/lib/public/assets/{webhook-settings-BjbGi-Pi.js → webhook-settings-CHpCrpob.js} +1 -1
- package/lib/public/assets/{zap-C2lxP7TK.js → zap-ovWf2UbO.js} +1 -1
- package/lib/public/index.html +1 -1
- package/lib/src/app/routers/control.js +5 -0
- package/lib/src/device-managers/AndroidDeviceManager.js +31 -95
- package/lib/src/device-managers/HealthMonitorService.js +10 -6
- package/lib/src/device-managers/android/AndroidH264StreamService.js +6 -1
- package/lib/src/device-managers/android/AndroidStreamService.js +9 -18
- package/lib/src/device-managers/android/clipboardBroadcast.js +24 -0
- package/lib/src/device-managers/android/previewHold.js +72 -0
- package/lib/src/device-managers/clipboardErrors.js +15 -0
- package/lib/test/unit/android-clipboard.spec.js +147 -0
- package/lib/test/unit/android-preview-hold.spec.js +179 -0
- package/lib/test/unit/clipboard-route.spec.js +110 -0
- package/lib/test/unit/health-monitor-stream-lookup.spec.js +107 -0
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/lib/public/assets/device-explorer-BPyGYs0c.js +0 -246
- package/lib/public/assets/device-explorer-C9qg30Jn.css +0 -1
- package/lib/public/assets/mouse-pointer-2-CYkC-Dyq.js +0 -11
- package/lib/public/assets/settings-DCR9vnQ5.js +0 -1
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
45
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
46
|
+
};
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
require("reflect-metadata");
|
|
49
|
+
const chai_1 = require("chai");
|
|
50
|
+
const sinon_1 = __importDefault(require("sinon"));
|
|
51
|
+
const typedi_1 = require("typedi");
|
|
52
|
+
const deviceService = __importStar(require("../../src/data-service/device-service"));
|
|
53
|
+
const device_store_1 = require("../../src/data-service/device-store");
|
|
54
|
+
const recording_store_1 = require("../../src/services/recording/recording-store");
|
|
55
|
+
const AndroidStreamService_1 = __importDefault(require("../../src/device-managers/android/AndroidStreamService"));
|
|
56
|
+
const AndroidH264StreamService_1 = __importDefault(require("../../src/device-managers/android/AndroidH264StreamService"));
|
|
57
|
+
const previewHold_1 = require("../../src/device-managers/android/previewHold");
|
|
58
|
+
const UDID = 'android-1';
|
|
59
|
+
const HOLD = `manual_user-1_${UDID}`;
|
|
60
|
+
describe('Android live-preview hold', () => {
|
|
61
|
+
let unblock;
|
|
62
|
+
let device;
|
|
63
|
+
let use;
|
|
64
|
+
beforeEach(() => {
|
|
65
|
+
device = { udid: UDID, host: 'h', session_id: HOLD, busy: true };
|
|
66
|
+
use = { h264Clients: 0, mjpegViewers: 0, recording: false };
|
|
67
|
+
unblock = sinon_1.default.stub(deviceService, 'unblockDevice').resolves();
|
|
68
|
+
sinon_1.default.stub(device_store_1.DeviceStoreFactory, 'getStore').returns({
|
|
69
|
+
findDevice: () => __awaiter(void 0, void 0, void 0, function* () { return device; }),
|
|
70
|
+
});
|
|
71
|
+
const real = typedi_1.Container.get.bind(typedi_1.Container);
|
|
72
|
+
sinon_1.default.stub(typedi_1.Container, 'get').callsFake((token) => {
|
|
73
|
+
// By class: TypeDI 0.10 ignores @Service({ name }), so a lookup by name
|
|
74
|
+
// throws in the running server even though a name stub here would pass.
|
|
75
|
+
if (token === AndroidH264StreamService_1.default) {
|
|
76
|
+
return {
|
|
77
|
+
getMultiplexer: () => (use.h264Clients ? { clientCount: use.h264Clients } : undefined),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
if (token === AndroidStreamService_1.default) {
|
|
81
|
+
return { getStreamStatus: () => ({ viewerCount: use.mjpegViewers }) };
|
|
82
|
+
}
|
|
83
|
+
if (token === recording_store_1.RecordingStore)
|
|
84
|
+
return { isRecording: () => __awaiter(void 0, void 0, void 0, function* () { return use.recording; }) };
|
|
85
|
+
return real(token);
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
afterEach(() => sinon_1.default.restore());
|
|
89
|
+
describe('mayReleasePreviewHold', () => {
|
|
90
|
+
const idle = { sessionId: HOLD, h264Clients: 0, mjpegViewers: 0, recording: false };
|
|
91
|
+
it('allows a preview hold that nothing uses', () => {
|
|
92
|
+
(0, chai_1.expect)((0, previewHold_1.mayReleasePreviewHold)(idle)).to.equal(true);
|
|
93
|
+
});
|
|
94
|
+
it('keeps it while anyone watches, over either transport, or a recording runs', () => {
|
|
95
|
+
(0, chai_1.expect)((0, previewHold_1.mayReleasePreviewHold)(Object.assign(Object.assign({}, idle), { h264Clients: 1 }))).to.equal(false);
|
|
96
|
+
(0, chai_1.expect)((0, previewHold_1.mayReleasePreviewHold)(Object.assign(Object.assign({}, idle), { mjpegViewers: 1 }))).to.equal(false);
|
|
97
|
+
(0, chai_1.expect)((0, previewHold_1.mayReleasePreviewHold)(Object.assign(Object.assign({}, idle), { recording: true }))).to.equal(false);
|
|
98
|
+
});
|
|
99
|
+
it('never touches an Appium session, or a device nobody holds', () => {
|
|
100
|
+
(0, chai_1.expect)((0, previewHold_1.mayReleasePreviewHold)(Object.assign(Object.assign({}, idle), { sessionId: 'd4098122-appium' }))).to.equal(false);
|
|
101
|
+
(0, chai_1.expect)((0, previewHold_1.mayReleasePreviewHold)(Object.assign(Object.assign({}, idle), { sessionId: null }))).to.equal(false);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
describe('releaseIdlePreviewHold', () => {
|
|
105
|
+
it('releases the hold when nothing uses the device', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
106
|
+
(0, chai_1.expect)(yield (0, previewHold_1.releaseIdlePreviewHold)(UDID)).to.equal(true);
|
|
107
|
+
(0, chai_1.expect)(unblock.calledOnceWith(UDID, 'h')).to.equal(true);
|
|
108
|
+
}));
|
|
109
|
+
it('keeps the hold while an H.264 viewer, an MJPEG viewer or a recording remains', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
110
|
+
for (const busy of [{ h264Clients: 1 }, { mjpegViewers: 1 }, { recording: true }]) {
|
|
111
|
+
Object.assign(use, { h264Clients: 0, mjpegViewers: 0, recording: false }, busy);
|
|
112
|
+
(0, chai_1.expect)(yield (0, previewHold_1.releaseIdlePreviewHold)(UDID), JSON.stringify(busy)).to.equal(false);
|
|
113
|
+
}
|
|
114
|
+
(0, chai_1.expect)(unblock.called).to.equal(false);
|
|
115
|
+
}));
|
|
116
|
+
});
|
|
117
|
+
// Before: the H.264 service stopped an unwatched stream after 10 minutes
|
|
118
|
+
// but left the hold, so with H.264 preview on, a closed tab's hold was
|
|
119
|
+
// never released by the server.
|
|
120
|
+
describe('H.264 idle stop', () => {
|
|
121
|
+
let clock;
|
|
122
|
+
beforeEach(() => {
|
|
123
|
+
clock = sinon_1.default.useFakeTimers({ now: Date.now(), toFake: ['setInterval', 'Date'] });
|
|
124
|
+
});
|
|
125
|
+
afterEach(() => clock.restore());
|
|
126
|
+
it('releases the hold once nobody has watched for 10 minutes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
127
|
+
const svc = new AndroidH264StreamService_1.default();
|
|
128
|
+
const kill = sinon_1.default.spy();
|
|
129
|
+
svc.sessions.set(UDID, { status: 'running', mux: { clientCount: 0 }, capture: { kill } });
|
|
130
|
+
yield clock.tickAsync(60000); // first sweep notes it is empty
|
|
131
|
+
yield clock.tickAsync(11 * 60000);
|
|
132
|
+
(0, chai_1.expect)(kill.called, 'capture stopped').to.equal(true);
|
|
133
|
+
(0, chai_1.expect)(unblock.calledOnceWith(UDID, 'h'), 'hold released').to.equal(true);
|
|
134
|
+
}));
|
|
135
|
+
it('keeps the hold if a recording holds the device', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
136
|
+
use.recording = true;
|
|
137
|
+
const svc = new AndroidH264StreamService_1.default();
|
|
138
|
+
svc.sessions.set(UDID, {
|
|
139
|
+
status: 'running',
|
|
140
|
+
mux: { clientCount: 0 },
|
|
141
|
+
capture: { kill() { } },
|
|
142
|
+
});
|
|
143
|
+
yield clock.tickAsync(12 * 60000);
|
|
144
|
+
(0, chai_1.expect)(unblock.called).to.equal(false);
|
|
145
|
+
}));
|
|
146
|
+
});
|
|
147
|
+
describe('MJPEG stream', () => {
|
|
148
|
+
// Before: checked once an hour, so an abandoned hold lasted up to 70 minutes.
|
|
149
|
+
it('checks for an idle stream every minute', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
150
|
+
const clock = sinon_1.default.useFakeTimers({ now: Date.now(), toFake: ['setInterval', 'Date'] });
|
|
151
|
+
try {
|
|
152
|
+
const svc = new AndroidStreamService_1.default();
|
|
153
|
+
const stop = sinon_1.default.stub(svc, 'stopStream').resolves();
|
|
154
|
+
svc.sessions.set(UDID, {
|
|
155
|
+
udid: UDID,
|
|
156
|
+
status: 'running',
|
|
157
|
+
viewerCount: 0,
|
|
158
|
+
lastViewerAt: Date.now() - 11 * 60000,
|
|
159
|
+
});
|
|
160
|
+
yield clock.tickAsync(60000);
|
|
161
|
+
(0, chai_1.expect)(stop.calledOnceWith(UDID)).to.equal(true);
|
|
162
|
+
}
|
|
163
|
+
finally {
|
|
164
|
+
clock.restore();
|
|
165
|
+
}
|
|
166
|
+
}));
|
|
167
|
+
// One hold covers both transports: stopping an idle MJPEG stream must not
|
|
168
|
+
// drop it under someone watching over H.264.
|
|
169
|
+
it('does not drop the hold on stop while an H.264 viewer remains', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
170
|
+
use.h264Clients = 1;
|
|
171
|
+
const svc = Object.create(AndroidStreamService_1.default.prototype);
|
|
172
|
+
svc.sessions = new Map([
|
|
173
|
+
[UDID, { udid: UDID, status: 'running', server: null, viewerCount: 0, lastViewerAt: 0 }],
|
|
174
|
+
]);
|
|
175
|
+
yield svc.stopStream(UDID);
|
|
176
|
+
(0, chai_1.expect)(unblock.called).to.equal(false);
|
|
177
|
+
}));
|
|
178
|
+
});
|
|
179
|
+
});
|
|
@@ -0,0 +1,110 @@
|
|
|
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 express_1 = __importDefault(require("express"));
|
|
19
|
+
const supertest_1 = __importDefault(require("supertest"));
|
|
20
|
+
const typedi_1 = require("typedi");
|
|
21
|
+
const control_1 = __importDefault(require("../../src/app/routers/control"));
|
|
22
|
+
const device_store_1 = require("../../src/data-service/device-store");
|
|
23
|
+
const ApiKeyService_1 = require("../../src/services/ApiKeyService");
|
|
24
|
+
const device_managers_1 = require("../../src/device-managers");
|
|
25
|
+
const clipboardErrors_1 = require("../../src/device-managers/clipboardErrors");
|
|
26
|
+
const authMiddleware_1 = require("../../src/middleware/authMiddleware");
|
|
27
|
+
/**
|
|
28
|
+
* GET/POST /control/:udid/clipboard answered 200 whatever happened on the
|
|
29
|
+
* device: the Android manager swallowed its errors, and its "set" had no
|
|
30
|
+
* effect at all. The dashboard's toast can only be as honest as the status.
|
|
31
|
+
*/
|
|
32
|
+
const UDID = 'DEV-CLIP';
|
|
33
|
+
// The route finds the manager by constructor name.
|
|
34
|
+
class AndroidDeviceManager {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.getClipboard = sinon_1.default.stub();
|
|
37
|
+
this.setClipboard = sinon_1.default.stub();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function buildApp() {
|
|
41
|
+
const app = (0, express_1.default)();
|
|
42
|
+
app.use(express_1.default.json());
|
|
43
|
+
const apiRouter = express_1.default.Router();
|
|
44
|
+
apiRouter.use((req, _res, next) => {
|
|
45
|
+
req.auth = {
|
|
46
|
+
kind: 'user-session',
|
|
47
|
+
userId: 'usr_me',
|
|
48
|
+
role: 'MEMBER',
|
|
49
|
+
scopes: (0, authMiddleware_1.scopesForRole)('MEMBER'),
|
|
50
|
+
rateLimit: 100,
|
|
51
|
+
};
|
|
52
|
+
next();
|
|
53
|
+
});
|
|
54
|
+
control_1.default.register(apiRouter);
|
|
55
|
+
app.use('/xenon/api', apiRouter);
|
|
56
|
+
return app;
|
|
57
|
+
}
|
|
58
|
+
describe('GET/POST /control/:udid/clipboard', () => {
|
|
59
|
+
let manager;
|
|
60
|
+
beforeEach(() => {
|
|
61
|
+
manager = new AndroidDeviceManager();
|
|
62
|
+
sinon_1.default.stub(device_store_1.DeviceStoreFactory, 'getStore').returns({
|
|
63
|
+
findDevice: () => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
+
return ({
|
|
65
|
+
udid: UDID,
|
|
66
|
+
host: '127.0.0.1',
|
|
67
|
+
platform: 'android',
|
|
68
|
+
busy: false,
|
|
69
|
+
session_id: null,
|
|
70
|
+
});
|
|
71
|
+
}),
|
|
72
|
+
});
|
|
73
|
+
typedi_1.Container.set(ApiKeyService_1.ApiKeyService, new ApiKeyService_1.ApiKeyService());
|
|
74
|
+
typedi_1.Container.set(device_managers_1.XenonManager, { deviceInstances: () => __awaiter(void 0, void 0, void 0, function* () { return [manager]; }) });
|
|
75
|
+
});
|
|
76
|
+
afterEach(() => {
|
|
77
|
+
sinon_1.default.restore();
|
|
78
|
+
typedi_1.Container.reset();
|
|
79
|
+
});
|
|
80
|
+
it('returns the clipboard text', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
81
|
+
manager.getClipboard.resolves('xenonread');
|
|
82
|
+
const res = yield (0, supertest_1.default)(buildApp()).get(`/xenon/api/control/${UDID}/clipboard`);
|
|
83
|
+
(0, chai_1.expect)(res.status).to.equal(200);
|
|
84
|
+
(0, chai_1.expect)(res.body).to.deep.equal({ content: 'xenonread' });
|
|
85
|
+
}));
|
|
86
|
+
it('says why a read failed, with a 500', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
87
|
+
manager.getClipboard.rejects(new Error('Appium Settings didn’t return the clipboard.'));
|
|
88
|
+
const res = yield (0, supertest_1.default)(buildApp()).get(`/xenon/api/control/${UDID}/clipboard`);
|
|
89
|
+
(0, chai_1.expect)(res.status).to.equal(500);
|
|
90
|
+
(0, chai_1.expect)(res.body.error).to.match(/Appium Settings/);
|
|
91
|
+
}));
|
|
92
|
+
// Not a failure of this attempt: the platform can't do it, so retrying
|
|
93
|
+
// won't help. 501 says exactly that.
|
|
94
|
+
it('answers 501 when the device cannot set its clipboard', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
manager.setClipboard.rejects(new clipboardErrors_1.ClipboardUnsupportedError('Appium Settings can only read it.'));
|
|
96
|
+
const res = yield (0, supertest_1.default)(buildApp())
|
|
97
|
+
.post(`/xenon/api/control/${UDID}/clipboard`)
|
|
98
|
+
.send({ content: 'x' });
|
|
99
|
+
(0, chai_1.expect)(res.status).to.equal(501);
|
|
100
|
+
(0, chai_1.expect)(res.body).to.deep.equal({ error: 'Appium Settings can only read it.' });
|
|
101
|
+
}));
|
|
102
|
+
it('still answers 500 for any other write failure', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
103
|
+
manager.setClipboard.rejects(new Error('WDA is not running'));
|
|
104
|
+
const res = yield (0, supertest_1.default)(buildApp())
|
|
105
|
+
.post(`/xenon/api/control/${UDID}/clipboard`)
|
|
106
|
+
.send({ content: 'x' });
|
|
107
|
+
(0, chai_1.expect)(res.status).to.equal(500);
|
|
108
|
+
(0, chai_1.expect)(res.body.error).to.equal('WDA is not running');
|
|
109
|
+
}));
|
|
110
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
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 typedi_1 = require("typedi");
|
|
19
|
+
const HealthMonitorService_1 = require("../../src/device-managers/HealthMonitorService");
|
|
20
|
+
const device_managers_1 = require("../../src/device-managers");
|
|
21
|
+
const device_store_1 = require("../../src/data-service/device-store");
|
|
22
|
+
const SessionManager_1 = require("../../src/sessions/SessionManager");
|
|
23
|
+
const AndroidStreamService_1 = __importDefault(require("../../src/device-managers/android/AndroidStreamService"));
|
|
24
|
+
const IOSStreamService_1 = __importDefault(require("../../src/device-managers/ios/IOSStreamService"));
|
|
25
|
+
// Named like the real managers: the monitor picks one by constructor.name.
|
|
26
|
+
class AndroidDeviceManager {
|
|
27
|
+
constructor() {
|
|
28
|
+
this.checkHealth = () => __awaiter(this, void 0, void 0, function* () { return ({ healthStatus: 'Healthy' }); });
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
class IOSDeviceManager {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.checkHealth = () => __awaiter(this, void 0, void 0, function* () { return ({ healthStatus: 'Healthy' }); });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// A device busy with an Appium session this process no longer knows about,
|
|
37
|
+
// which is the case the monitor reclaims, unless a stream is still running.
|
|
38
|
+
function lostSessionDevice(platform) {
|
|
39
|
+
return {
|
|
40
|
+
udid: `${platform}-1`,
|
|
41
|
+
host: 'http://127.0.0.1:4723',
|
|
42
|
+
platform,
|
|
43
|
+
busy: true,
|
|
44
|
+
session_id: 'appium-session-not-in-memory',
|
|
45
|
+
cloud: false,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
describe('HealthMonitorService — stream lookups', () => {
|
|
49
|
+
let updateDevice;
|
|
50
|
+
let device;
|
|
51
|
+
let androidStatus;
|
|
52
|
+
let iosStatus;
|
|
53
|
+
const reclaimed = () => updateDevice.getCalls().some((c) => { var _a, _b; return ((_a = c.args[2]) === null || _a === void 0 ? void 0 : _a.busy) === false && !((_b = c.args[2]) === null || _b === void 0 ? void 0 : _b.session_id); });
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
sinon_1.default.stub(process, 'kill');
|
|
56
|
+
updateDevice = sinon_1.default.spy(() => __awaiter(void 0, void 0, void 0, function* () { return undefined; }));
|
|
57
|
+
sinon_1.default.stub(device_store_1.DeviceStoreFactory, 'getStore').returns({
|
|
58
|
+
getAllDevices: () => __awaiter(void 0, void 0, void 0, function* () { return [device]; }),
|
|
59
|
+
updateDevice,
|
|
60
|
+
});
|
|
61
|
+
sinon_1.default.stub(SessionManager_1.SESSION_MANAGER, 'isValidSession').returns(false);
|
|
62
|
+
androidStatus = sinon_1.default.stub().returns({ status: 'running' });
|
|
63
|
+
iosStatus = sinon_1.default.stub().returns({ status: 'running' });
|
|
64
|
+
const real = typedi_1.Container.get.bind(typedi_1.Container);
|
|
65
|
+
// Only the class tokens answer. TypeDI 0.10 ignores @Service({ name }), so
|
|
66
|
+
// a lookup by name falls through to the real container and throws, as it
|
|
67
|
+
// does in the server.
|
|
68
|
+
sinon_1.default.stub(typedi_1.Container, 'get').callsFake((token) => {
|
|
69
|
+
if (token === device_managers_1.XenonManager) {
|
|
70
|
+
return {
|
|
71
|
+
deviceInstances: () => __awaiter(void 0, void 0, void 0, function* () { return [new AndroidDeviceManager(), new IOSDeviceManager()]; }),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (token === AndroidStreamService_1.default)
|
|
75
|
+
return { getStreamStatus: androidStatus };
|
|
76
|
+
if (token === IOSStreamService_1.default)
|
|
77
|
+
return { getStreamStatus: iosStatus };
|
|
78
|
+
return real(token);
|
|
79
|
+
});
|
|
80
|
+
});
|
|
81
|
+
afterEach(() => sinon_1.default.restore());
|
|
82
|
+
const run = () => new HealthMonitorService_1.HealthMonitorService({}).checkAllDevices();
|
|
83
|
+
it('leaves an Android device with a running stream alone', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
84
|
+
device = lostSessionDevice('android');
|
|
85
|
+
yield run();
|
|
86
|
+
(0, chai_1.expect)(reclaimed(), 'reclaimed a device with a live stream').to.equal(false);
|
|
87
|
+
(0, chai_1.expect)(androidStatus.called, 'asked the stream service').to.equal(true);
|
|
88
|
+
}));
|
|
89
|
+
it('leaves an iOS device with a running stream alone', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
90
|
+
device = lostSessionDevice('ios');
|
|
91
|
+
yield run();
|
|
92
|
+
(0, chai_1.expect)(reclaimed(), 'reclaimed a device with a live stream').to.equal(false);
|
|
93
|
+
(0, chai_1.expect)(iosStatus.called, 'asked the stream service').to.equal(true);
|
|
94
|
+
}));
|
|
95
|
+
it('cancels a reclaim when the stream appears before the final re-check', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
96
|
+
device = lostSessionDevice('android');
|
|
97
|
+
androidStatus.onFirstCall().returns(undefined);
|
|
98
|
+
yield run();
|
|
99
|
+
(0, chai_1.expect)(reclaimed()).to.equal(false);
|
|
100
|
+
}));
|
|
101
|
+
it('still reclaims a device with no stream', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
|
+
device = lostSessionDevice('android');
|
|
103
|
+
androidStatus.returns(undefined);
|
|
104
|
+
yield run();
|
|
105
|
+
(0, chai_1.expect)(reclaimed()).to.equal(true);
|
|
106
|
+
}));
|
|
107
|
+
});
|
package/lib/tsconfig.tsbuildinfo
CHANGED
|
@@ -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/index.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/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/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/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/deviceColumns.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/deviceIdentity.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.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/displayState.ts","../src/device-managers/android/h264NalParser.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/WDAClient.ts","../src/device-managers/ios/appleIdentity.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/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/csrfMiddleware.ts","../src/middleware/deviceAccessGuard.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.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/SessionOwnerResolver.ts","../src/services/device-access/actor.ts","../src/services/device-access/deviceAccessPolicy.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/leaseToken.ts","../src/services/logcat/PackageResolver.ts","../src/services/logcat/logSource.ts","../src/services/logcat/logcatParse.ts","../src/services/logcat/ostraceParse.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/probeDuration.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/recording/recordingCleanup.ts","../src/services/recording/recordingTiming.ts","../src/services/session/sessionIdentity.ts","../src/services/telemetry/attributes.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.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/artifact-store.ts","../test/helpers/seedUser.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/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-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-recordings.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/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.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-tuple-key.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-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/auth-disabled-resolution.spec.ts","../test/unit/auth-me-auth-disabled.test.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/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.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/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-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/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/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-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/helpers.spec.ts","../test/unit/inspector-hierarchy.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.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/manualLock.test.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.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-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/rateLimitMiddleware.test.ts","../test/unit/recording-cleanup.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-timing.spec.ts","../test/unit/remux-to-standard-mp4.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/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/session-attribution-wiring.spec.ts","../test/unit/session-identity.spec.ts","../test/unit/session-owner-resolver.spec.ts","../test/unit/shutdown-sync-nets.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socketServer.bearer.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/sync-dir.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.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/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/buildCapabilityBag.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.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/index.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/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/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/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/deviceColumns.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/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/WDAClient.ts","../src/device-managers/ios/appleIdentity.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/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/csrfMiddleware.ts","../src/middleware/deviceAccessGuard.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.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/SessionOwnerResolver.ts","../src/services/device-access/actor.ts","../src/services/device-access/deviceAccessPolicy.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/leaseToken.ts","../src/services/logcat/PackageResolver.ts","../src/services/logcat/logSource.ts","../src/services/logcat/logcatParse.ts","../src/services/logcat/ostraceParse.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/probeDuration.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/recording/recordingCleanup.ts","../src/services/recording/recordingTiming.ts","../src/services/session/sessionIdentity.ts","../src/services/telemetry/attributes.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.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/artifact-store.ts","../test/helpers/seedUser.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/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-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-recordings.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/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.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-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/auth-disabled-resolution.spec.ts","../test/unit/auth-me-auth-disabled.test.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/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/clipboard-route.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/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-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/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/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-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/health-monitor-stream-lookup.spec.ts","../test/unit/helpers.spec.ts","../test/unit/inspector-hierarchy.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.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/manualLock.test.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.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-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/rateLimitMiddleware.test.ts","../test/unit/recording-cleanup.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-timing.spec.ts","../test/unit/remux-to-standard-mp4.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/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/session-attribution-wiring.spec.ts","../test/unit/session-identity.spec.ts","../test/unit/session-owner-resolver.spec.ts","../test/unit/shutdown-sync-nets.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socketServer.bearer.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/sync-dir.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.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/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/buildCapabilityBag.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED