@xenon-device-management/xenon 1.26.2 → 1.27.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-CdwAz8U0.js} +1 -1
- package/lib/public/assets/{BugReportButton-ySiZDywe.js → BugReportButton-BRpZbizS.js} +1 -1
- package/lib/public/assets/{DeviceMosaicView-Chtp0wAI.js → DeviceMosaicView-DIliYF7k.js} +1 -1
- package/lib/public/assets/{EmptyState-CYQYScPo.js → EmptyState-DdGslmm0.js} +1 -1
- package/lib/public/assets/{FieldGroup-Dea68RfI.js → FieldGroup-Bb3NBVy1.js} +1 -1
- package/lib/public/assets/{Modal-BgzTzImP.js → Modal-B1wiaZoC.js} +1 -1
- package/lib/public/assets/{SegmentedControl-DyRq9blY.js → SegmentedControl-CSSdDwVG.js} +1 -1
- package/lib/public/assets/{SettingCard-CardwBu3.js → SettingCard-B5QGLufn.js} +1 -1
- package/lib/public/assets/{Table-BczCxsDm.js → Table-CaLvNt65.js} +1 -1
- package/lib/public/assets/{activity-CS-Op-T6.js → activity-BKpt4jQ5.js} +1 -1
- package/lib/public/assets/{ai-settings-CIvB7rNM.js → ai-settings-DXab66Uw.js} +3 -3
- package/lib/public/assets/{api-keys-peJzllzQ.js → api-keys-BKOBEq40.js} +1 -1
- package/lib/public/assets/{apps-__WvcJaP.js → apps-h1-WF2M3.js} +3 -3
- package/lib/public/assets/{arrow-left-Dx-cXFLT.js → arrow-left-CsL4cGlx.js} +1 -1
- package/lib/public/assets/{arrow-right-Ax_FfBMv.js → arrow-right-ms3VXPTM.js} +1 -1
- package/lib/public/assets/{arrow-up-right-B6uJmGeA.js → arrow-up-right-DsPkHtnY.js} +1 -1
- package/lib/public/assets/{auth-shell-BQqcjjC9.js → auth-shell-Di20xJer.js} +2 -2
- package/lib/public/assets/{builds-page-BA-_iEjx.js → builds-page-B7Ykr6Y7.js} +1 -1
- package/lib/public/assets/{button-DcbnByKB.js → button-B4yBI9rz.js} +1 -1
- package/lib/public/assets/{calendar-C3pYg1V7.js → calendar-CDhdbn6g.js} +1 -1
- package/lib/public/assets/{check-DKdLfzhJ.js → check-CQ6W-pr3.js} +1 -1
- package/lib/public/assets/{chevron-left-Bb9PBLG5.js → chevron-left-Brw18ZbJ.js} +1 -1
- package/lib/public/assets/{chevron-right-DJcpeY_o.js → chevron-right-_5hhohkO.js} +1 -1
- package/lib/public/assets/{circle-check-DY6ntqp3.js → circle-check-DFS84uuw.js} +1 -1
- package/lib/public/assets/{circle-x-DgK9drRH.js → circle-x--eZQbJ-L.js} +1 -1
- package/lib/public/assets/{clock-I9zEVPan.js → clock-BKQop8v4.js} +1 -1
- package/lib/public/assets/{copy-Dy3oRuWT.js → copy-C6MtTTlz.js} +1 -1
- package/lib/public/assets/device-explorer-DTHiUDlu.js +246 -0
- package/lib/public/assets/device-explorer-ISQgiqG9.css +1 -0
- package/lib/public/assets/{download-BotTmDty.js → download-CJQADlfa.js} +1 -1
- package/lib/public/assets/{forgot-password-BaWiD2U2.js → forgot-password-BDwj629H.js} +1 -1
- package/lib/public/assets/{funnel-D2Qw4nTX.js → funnel-DZ7jzsbh.js} +1 -1
- package/lib/public/assets/{index-CI9Nz3HY.js → index-BpueX0rJ.js} +2 -2
- package/lib/public/assets/{input-cBBGau4X.js → input-CjSO5fIy.js} +1 -1
- package/lib/public/assets/{keycodes-CY4uwulo.js → keycodes-DX_YyhNk.js} +1 -1
- package/lib/public/assets/{layers-MHwJM2Ll.js → layers-DeJ98GnJ.js} +1 -1
- package/lib/public/assets/{lock-Bpc8rJFu.js → lock-D7AfKT4W.js} +1 -1
- package/lib/public/assets/{login-BmcyszP5.js → login-DzvYxcU2.js} +1 -1
- package/lib/public/assets/{maintenance-settings-DMFVuToe.js → maintenance-settings-CI8PjeAD.js} +2 -2
- package/lib/public/assets/{monitor-irjK6PRV.js → monitor-COjPL4Nw.js} +1 -1
- package/lib/public/assets/mouse-pointer-2-JHGsHIlv.js +6 -0
- package/lib/public/assets/{network-CVZ32MhH.js → network-CHdKReD2.js} +1 -1
- package/lib/public/assets/{overview-DRRSIpnD.js → overview-BFi5MYtk.js} +1 -1
- package/lib/public/assets/{page-header-Bl7uTiQF.js → page-header-Dlf-n7I6.js} +1 -1
- package/lib/public/assets/{plus-C3lvaMcL.js → plus-BO31f8er.js} +1 -1
- package/lib/public/assets/{profile-page-B3wsnR1n.js → profile-page-C2mhKOSp.js} +1 -1
- package/lib/public/assets/{reset-password-BIGj_ULj.js → reset-password-D2-nKd2R.js} +1 -1
- package/lib/public/assets/{runbook-page-DEznNZhc.js → runbook-page-Dua237ld.js} +1 -1
- package/lib/public/assets/{select-BpuZWZuE.js → select-r2t6ViSf.js} +1 -1
- package/lib/public/assets/{selector-detail-page-ZCvmtQ5Y.js → selector-detail-page-BADJhfZc.js} +1 -1
- package/lib/public/assets/{selector-health-D-hvfY2E.js → selector-health-3LaUwIOS.js} +1 -1
- package/lib/public/assets/{selector-health-page-C0ZqZ_VT.js → selector-health-page-hCruYbXz.js} +1 -1
- package/lib/public/assets/{session-detail-page-Bv7IwFTQ.js → session-detail-page-ovBT1YRs.js} +1 -1
- package/lib/public/assets/settings-CIK56OMn.js +6 -0
- package/lib/public/assets/{status-pill-outline-B5dWsaer.js → status-pill-outline-CG_1PTcd.js} +1 -1
- package/lib/public/assets/{tablet-DxwkBlhd.js → tablet-mcews5C3.js} +1 -1
- package/lib/public/assets/{teams-D3s8GhkG.js → teams-Cf8a8-Uo.js} +1 -1
- package/lib/public/assets/{trash-2-Dyf4Jcyk.js → trash-2-CsJaXAJF.js} +1 -1
- package/lib/public/assets/{upload-B6ZJ1_f1.js → upload-CL1XK43J.js} +1 -1
- package/lib/public/assets/{use-password-reset-mode-B-oOrt1d.js → use-password-reset-mode-gRcAFXVy.js} +1 -1
- package/lib/public/assets/{users-QfiFclLn.js → users-24eVEQFo.js} +1 -1
- package/lib/public/assets/{users-BfvPE2wX.js → users-CgxBmVs9.js} +1 -1
- package/lib/public/assets/{video-off-C2quR4KF.js → video-off-LUd5fEht.js} +1 -1
- package/lib/public/assets/{webhook-settings-BjbGi-Pi.js → webhook-settings-KzrG-pNv.js} +1 -1
- package/lib/public/assets/{zap-C2lxP7TK.js → zap-BA1OUWAL.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/android/clipboardBroadcast.js +24 -0
- package/lib/src/device-managers/clipboardErrors.js +15 -0
- package/lib/test/unit/android-clipboard.spec.js +147 -0
- package/lib/test/unit/clipboard-route.spec.js +110 -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
|
@@ -70,6 +70,7 @@ const streamType_1 = require("./streamType");
|
|
|
70
70
|
const iosStreamPort_1 = require("./iosStreamPort");
|
|
71
71
|
const androidH264Config_1 = require("./androidH264Config");
|
|
72
72
|
const recording_store_1 = require("../../services/recording/recording-store");
|
|
73
|
+
const clipboardErrors_1 = require("../../device-managers/clipboardErrors");
|
|
73
74
|
const scopeGuard_1 = require("../../middleware/scopeGuard");
|
|
74
75
|
const roleGuard_1 = require("../../middleware/roleGuard");
|
|
75
76
|
const deviceAccessGuard_1 = require("../../middleware/deviceAccessGuard");
|
|
@@ -360,6 +361,10 @@ router.post('/:udid/clipboard', (req, res) => __awaiter(void 0, void 0, void 0,
|
|
|
360
361
|
return res.status(200).send({ success: true });
|
|
361
362
|
}
|
|
362
363
|
catch (err) {
|
|
364
|
+
// The device can't do it at all (Android): 501, not a failure to retry.
|
|
365
|
+
if (err instanceof clipboardErrors_1.ClipboardUnsupportedError) {
|
|
366
|
+
return res.status(501).send({ error: err.message });
|
|
367
|
+
}
|
|
363
368
|
logger_1.default.error(`Manual control setClipboard failed: ${err.message}`);
|
|
364
369
|
return res.status(500).send({ error: err.message });
|
|
365
370
|
}
|
|
@@ -58,6 +58,8 @@ const displayState_1 = require("./android/displayState");
|
|
|
58
58
|
const networkAddresses_1 = require("../helpers/networkAddresses");
|
|
59
59
|
const appium_adb_1 = require("appium-adb");
|
|
60
60
|
const logger_1 = __importDefault(require("../logger"));
|
|
61
|
+
const clipboardBroadcast_1 = require("./android/clipboardBroadcast");
|
|
62
|
+
const clipboardErrors_1 = require("./clipboardErrors");
|
|
61
63
|
const lodash_1 = __importDefault(require("lodash"));
|
|
62
64
|
const support_1 = require("@appium/support");
|
|
63
65
|
const ChromeDriverManager_1 = __importDefault(require("./ChromeDriverManager"));
|
|
@@ -837,108 +839,42 @@ let AndroidDeviceManager = class AndroidDeviceManager {
|
|
|
837
839
|
}
|
|
838
840
|
});
|
|
839
841
|
}
|
|
842
|
+
/**
|
|
843
|
+
* Reads the clipboard through Appium Settings. Android 10+ lets only the
|
|
844
|
+
* default input method read it, so Appium Settings is the IME for the length
|
|
845
|
+
* of one broadcast (see withAppiumIME). Failures are thrown, not swallowed:
|
|
846
|
+
* an empty string used to stand for both "empty" and "couldn't read".
|
|
847
|
+
*/
|
|
840
848
|
getClipboard(udid) {
|
|
841
849
|
return __awaiter(this, void 0, void 0, function* () {
|
|
842
850
|
const { adbInstance } = yield this.getAdb();
|
|
843
851
|
if (!adbInstance)
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
'-n',
|
|
858
|
-
'io.appium.settings/.receivers.ClipboardReceiver',
|
|
859
|
-
]);
|
|
860
|
-
// Parse result like: Broadcast completed: result=-1, data="BASE64_DATA"
|
|
861
|
-
const dataMatch = /data="([^"]*)"/.exec(result);
|
|
862
|
-
if (dataMatch) {
|
|
863
|
-
const rawData = dataMatch[1];
|
|
864
|
-
if (!rawData)
|
|
865
|
-
return '';
|
|
866
|
-
// Appium Settings returns Base64 for robustness
|
|
867
|
-
try {
|
|
868
|
-
const decoded = Buffer.from(rawData, 'base64').toString('utf8');
|
|
869
|
-
// If it looks like printable text after decoding, use it
|
|
870
|
-
if (/^[\x20-\x7E\s\u00A0-\uFFFF]*$/.test(decoded))
|
|
871
|
-
return decoded;
|
|
872
|
-
return rawData;
|
|
873
|
-
}
|
|
874
|
-
catch (e) {
|
|
875
|
-
return rawData;
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
// 2. Fallback: Query the content provider (Legacy/Alternative)
|
|
879
|
-
const queryResult = yield adbInstance.adbExec([
|
|
880
|
-
'-s',
|
|
881
|
-
udid,
|
|
882
|
-
'shell',
|
|
883
|
-
'content',
|
|
884
|
-
'query',
|
|
885
|
-
'--uri',
|
|
886
|
-
'content://io.appium.settings.clipboard/clipboard',
|
|
887
|
-
]);
|
|
888
|
-
// Extract value using a more flexible regex that handles different formats
|
|
889
|
-
const valMatch = /value=([^\s,]*)/i.exec(queryResult);
|
|
890
|
-
if (valMatch) {
|
|
891
|
-
const val = valMatch[1];
|
|
892
|
-
// Most content providers return base64 for safety
|
|
893
|
-
try {
|
|
894
|
-
const decoded = Buffer.from(val, 'base64').toString('utf8');
|
|
895
|
-
// Basic sanity check: if it contains non-printable characters, it might not have been base64
|
|
896
|
-
if (/^[\x20-\x7E\s]*$/.test(decoded))
|
|
897
|
-
return decoded;
|
|
898
|
-
return val;
|
|
899
|
-
}
|
|
900
|
-
catch (e) {
|
|
901
|
-
return val;
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
|
-
return '';
|
|
905
|
-
}));
|
|
906
|
-
}
|
|
907
|
-
catch (err) {
|
|
908
|
-
logger_1.default.warn(`Failed to fetch Android clipboard for ${udid}: ${err instanceof Error ? err.message : err}`);
|
|
909
|
-
}
|
|
910
|
-
return '';
|
|
852
|
+
throw new Error('ADB is not available');
|
|
853
|
+
const output = yield this.withAppiumIME(adbInstance, udid, () => adbInstance.adbExec([
|
|
854
|
+
'-s',
|
|
855
|
+
udid,
|
|
856
|
+
'shell',
|
|
857
|
+
'am',
|
|
858
|
+
'broadcast',
|
|
859
|
+
'-n',
|
|
860
|
+
clipboardBroadcast_1.CLIPBOARD_RECEIVER,
|
|
861
|
+
'-a',
|
|
862
|
+
clipboardBroadcast_1.CLIPBOARD_GET_ACTION,
|
|
863
|
+
]));
|
|
864
|
+
return (0, clipboardBroadcast_1.parseClipboardBroadcast)(output);
|
|
911
865
|
});
|
|
912
866
|
}
|
|
913
|
-
|
|
867
|
+
/**
|
|
868
|
+
* Not possible on Android outside a test session. Appium Settings, the only
|
|
869
|
+
* helper Xenon can use here, has no clipboard-set action (8.0.5 holds just
|
|
870
|
+
* io.appium.settings.clipboard.get), and Appium itself sets the clipboard
|
|
871
|
+
* through a running UiAutomator2 session. The old broadcast reached the
|
|
872
|
+
* *read* receiver, which answered OK, so writes reported success and changed
|
|
873
|
+
* nothing.
|
|
874
|
+
*/
|
|
875
|
+
setClipboard() {
|
|
914
876
|
return __awaiter(this, void 0, void 0, function* () {
|
|
915
|
-
|
|
916
|
-
if (!adbInstance)
|
|
917
|
-
return;
|
|
918
|
-
try {
|
|
919
|
-
yield this.withAppiumIME(adbInstance, udid, () => __awaiter(this, void 0, void 0, function* () {
|
|
920
|
-
yield adbInstance.adbExec([
|
|
921
|
-
'-s',
|
|
922
|
-
udid,
|
|
923
|
-
'shell',
|
|
924
|
-
'am',
|
|
925
|
-
'broadcast',
|
|
926
|
-
'-a',
|
|
927
|
-
'com.appium.settings.clipboard.set',
|
|
928
|
-
'-n',
|
|
929
|
-
'io.appium.settings/.receivers.ClipboardReceiver',
|
|
930
|
-
'--es',
|
|
931
|
-
'label',
|
|
932
|
-
'clipboard',
|
|
933
|
-
'--es',
|
|
934
|
-
'content',
|
|
935
|
-
Buffer.from(content).toString('base64'), // Send as Base64 for safety
|
|
936
|
-
]);
|
|
937
|
-
}));
|
|
938
|
-
}
|
|
939
|
-
catch (err) {
|
|
940
|
-
logger_1.default.warn(`Failed to set Android clipboard for ${udid}: ${err instanceof Error ? err.message : err}`);
|
|
941
|
-
}
|
|
877
|
+
throw new clipboardErrors_1.ClipboardUnsupportedError('Android doesn’t allow setting the clipboard from here: Appium Settings can only read it.');
|
|
942
878
|
});
|
|
943
879
|
}
|
|
944
880
|
touchAndHold(udid, x, y, duration) {
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLIPBOARD_GET_ACTION = exports.CLIPBOARD_RECEIVER = void 0;
|
|
4
|
+
exports.parseClipboardBroadcast = parseClipboardBroadcast;
|
|
5
|
+
/** Appium Settings' clipboard receiver and its only clipboard action (read). */
|
|
6
|
+
exports.CLIPBOARD_RECEIVER = 'io.appium.settings/.receivers.ClipboardReceiver';
|
|
7
|
+
exports.CLIPBOARD_GET_ACTION = 'io.appium.settings.clipboard.get';
|
|
8
|
+
/**
|
|
9
|
+
* The clipboard text from `am broadcast … io.appium.settings.clipboard.get`.
|
|
10
|
+
*
|
|
11
|
+
* Appium Settings answers `result=-1, data="<base64>"`, with an empty data for
|
|
12
|
+
* an empty clipboard. Anything else means the broadcast reached no receiver,
|
|
13
|
+
* or the wrong one (a missing app answers `result=0`), so it is an error, not
|
|
14
|
+
* an empty clipboard.
|
|
15
|
+
*/
|
|
16
|
+
function parseClipboardBroadcast(output) {
|
|
17
|
+
const answered = /\bresult=-1\b/.test(output);
|
|
18
|
+
const data = /data="([^"]*)"/.exec(output);
|
|
19
|
+
if (!answered || !data) {
|
|
20
|
+
const last = output.trim().split('\n').pop() || 'no output';
|
|
21
|
+
throw new Error(`Appium Settings didn’t return the clipboard. Check that it is installed and up to date (${last}).`);
|
|
22
|
+
}
|
|
23
|
+
return data[1] ? Buffer.from(data[1], 'base64').toString('utf8') : '';
|
|
24
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ClipboardUnsupportedError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* A clipboard operation this device can't do at all, as opposed to one that
|
|
6
|
+
* failed this time. The control route answers 501 for it: retrying won't help.
|
|
7
|
+
*/
|
|
8
|
+
class ClipboardUnsupportedError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.code = 'clipboard_unsupported';
|
|
12
|
+
this.name = 'ClipboardUnsupportedError';
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
exports.ClipboardUnsupportedError = ClipboardUnsupportedError;
|
|
@@ -0,0 +1,147 @@
|
|
|
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 AndroidDeviceManager_1 = __importDefault(require("../../src/device-managers/AndroidDeviceManager"));
|
|
19
|
+
const clipboardBroadcast_1 = require("../../src/device-managers/android/clipboardBroadcast");
|
|
20
|
+
const clipboardErrors_1 = require("../../src/device-managers/clipboardErrors");
|
|
21
|
+
/**
|
|
22
|
+
* Device control's clipboard on Android, measured 2026-09-26 on a Galaxy S9+
|
|
23
|
+
* (Android 10, Appium Settings 8.0.5):
|
|
24
|
+
*
|
|
25
|
+
* - Appium Settings can only *read* the clipboard. Its code holds one
|
|
26
|
+
* clipboard action, io.appium.settings.clipboard.get. Our "set" broadcast
|
|
27
|
+
* reached that same receiver, which read the clipboard, answered result=-1,
|
|
28
|
+
* and the server reported success while nothing changed.
|
|
29
|
+
* - The read works, but only while Appium Settings is the default input
|
|
30
|
+
* method (Android 10+ restricts clipboard reads to the IME). After an
|
|
31
|
+
* on-device Copy of "xenonread" it returned data="eGVub25yZWFk".
|
|
32
|
+
* - Both methods swallowed every error, so the route always answered 200.
|
|
33
|
+
*/
|
|
34
|
+
const UDID = '381103b720057ece';
|
|
35
|
+
const ORIGINAL_IME = 'com.samsung.android.honeyboard/.service.HoneyBoardService';
|
|
36
|
+
const APPIUM_IME = 'io.appium.settings/.AppiumIME';
|
|
37
|
+
function fakeAdb(broadcast) {
|
|
38
|
+
const calls = [];
|
|
39
|
+
const adbExec = sinon_1.default.stub().callsFake((args) => __awaiter(this, void 0, void 0, function* () {
|
|
40
|
+
calls.push(args);
|
|
41
|
+
const cmd = args.slice(2).join(' ');
|
|
42
|
+
if (cmd === 'shell settings get secure default_input_method')
|
|
43
|
+
return `${ORIGINAL_IME}\n`;
|
|
44
|
+
if (cmd.startsWith('shell am broadcast')) {
|
|
45
|
+
if (broadcast instanceof Error)
|
|
46
|
+
throw broadcast;
|
|
47
|
+
return broadcast;
|
|
48
|
+
}
|
|
49
|
+
return '';
|
|
50
|
+
}));
|
|
51
|
+
return { adbInstance: { adbExec }, calls };
|
|
52
|
+
}
|
|
53
|
+
function managerWith(adb) {
|
|
54
|
+
// The constructor starts device tracking; these tests need only the methods.
|
|
55
|
+
const manager = Object.create(AndroidDeviceManager_1.default.prototype);
|
|
56
|
+
manager.getAdb = () => __awaiter(this, void 0, void 0, function* () { return adb; });
|
|
57
|
+
return manager;
|
|
58
|
+
}
|
|
59
|
+
const imeSets = (calls) => calls.filter((c) => c.slice(2, 5).join(' ') === 'shell ime set').map((c) => c[5]);
|
|
60
|
+
describe('Android clipboard', () => {
|
|
61
|
+
afterEach(() => sinon_1.default.restore());
|
|
62
|
+
describe('parseClipboardBroadcast', () => {
|
|
63
|
+
it('decodes the base64 text Appium Settings returns', () => {
|
|
64
|
+
(0, chai_1.expect)((0, clipboardBroadcast_1.parseClipboardBroadcast)('Broadcasting: Intent { … }\nBroadcast completed: result=-1, data="eGVub25yZWFk"')).to.equal('xenonread');
|
|
65
|
+
});
|
|
66
|
+
it('keeps non-ASCII text', () => {
|
|
67
|
+
const data = Buffer.from('héllo · 世界').toString('base64');
|
|
68
|
+
(0, chai_1.expect)((0, clipboardBroadcast_1.parseClipboardBroadcast)(`Broadcast completed: result=-1, data="${data}"`)).to.equal('héllo · 世界');
|
|
69
|
+
});
|
|
70
|
+
it('treats an empty answer as an empty clipboard', () => {
|
|
71
|
+
(0, chai_1.expect)((0, clipboardBroadcast_1.parseClipboardBroadcast)('Broadcast completed: result=-1, data=""')).to.equal('');
|
|
72
|
+
});
|
|
73
|
+
// A missing receiver answers result=0 with no data; that used to read as
|
|
74
|
+
// an empty clipboard.
|
|
75
|
+
it('refuses an answer that is not a clipboard', () => {
|
|
76
|
+
(0, chai_1.expect)(() => (0, clipboardBroadcast_1.parseClipboardBroadcast)('Broadcast completed: result=0')).to.throw(/Appium Settings didn’t return the clipboard/);
|
|
77
|
+
(0, chai_1.expect)(() => (0, clipboardBroadcast_1.parseClipboardBroadcast)('Broadcast completed: result=0, data="eA=="')).to.throw(/Appium Settings/);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe('getClipboard', () => {
|
|
81
|
+
it('reads it with the documented broadcast, as the Appium IME', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
82
|
+
var _a;
|
|
83
|
+
const adb = fakeAdb('Broadcast completed: result=-1, data="eGVub25yZWFk"');
|
|
84
|
+
(0, chai_1.expect)(yield managerWith(adb).getClipboard(UDID)).to.equal('xenonread');
|
|
85
|
+
const broadcast = (_a = adb.calls.find((c) => c.includes('broadcast'))) !== null && _a !== void 0 ? _a : [];
|
|
86
|
+
(0, chai_1.expect)(broadcast).to.include.members([
|
|
87
|
+
'-n',
|
|
88
|
+
'io.appium.settings/.receivers.ClipboardReceiver',
|
|
89
|
+
'-a',
|
|
90
|
+
'io.appium.settings.clipboard.get',
|
|
91
|
+
]);
|
|
92
|
+
(0, chai_1.expect)(imeSets(adb.calls)).to.deep.equal([APPIUM_IME, ORIGINAL_IME]);
|
|
93
|
+
}));
|
|
94
|
+
it('says why when Appium Settings does not answer, and restores the keyboard', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
95
|
+
const adb = fakeAdb('Broadcast completed: result=0');
|
|
96
|
+
let error;
|
|
97
|
+
try {
|
|
98
|
+
yield managerWith(adb).getClipboard(UDID);
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
error = e;
|
|
102
|
+
}
|
|
103
|
+
(0, chai_1.expect)(error === null || error === void 0 ? void 0 : error.message).to.match(/Appium Settings didn’t return the clipboard/);
|
|
104
|
+
(0, chai_1.expect)(imeSets(adb.calls)).to.deep.equal([APPIUM_IME, ORIGINAL_IME]);
|
|
105
|
+
}));
|
|
106
|
+
it('does not swallow an adb failure', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
107
|
+
const adb = fakeAdb(new Error('device offline'));
|
|
108
|
+
let error;
|
|
109
|
+
try {
|
|
110
|
+
yield managerWith(adb).getClipboard(UDID);
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
error = e;
|
|
114
|
+
}
|
|
115
|
+
(0, chai_1.expect)(error === null || error === void 0 ? void 0 : error.message).to.equal('device offline');
|
|
116
|
+
(0, chai_1.expect)(imeSets(adb.calls)).to.deep.equal([APPIUM_IME, ORIGINAL_IME]);
|
|
117
|
+
}));
|
|
118
|
+
it('fails when adb is unavailable, instead of returning nothing', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
119
|
+
let error;
|
|
120
|
+
try {
|
|
121
|
+
yield managerWith({ adbInstance: null }).getClipboard(UDID);
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
error = e;
|
|
125
|
+
}
|
|
126
|
+
(0, chai_1.expect)(error === null || error === void 0 ? void 0 : error.message).to.equal('ADB is not available');
|
|
127
|
+
}));
|
|
128
|
+
});
|
|
129
|
+
describe('setClipboard', () => {
|
|
130
|
+
it('refuses, since Appium Settings can only read the clipboard, and touches nothing', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
131
|
+
var _a;
|
|
132
|
+
const adb = fakeAdb('Broadcast completed: result=-1, data=""');
|
|
133
|
+
let error;
|
|
134
|
+
try {
|
|
135
|
+
// Through the interface, as the control route calls it.
|
|
136
|
+
const manager = managerWith(adb);
|
|
137
|
+
yield ((_a = manager.setClipboard) === null || _a === void 0 ? void 0 : _a.call(manager, UDID, 'xenon-clip-test'));
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
error = e;
|
|
141
|
+
}
|
|
142
|
+
(0, chai_1.expect)(error).to.be.instanceOf(clipboardErrors_1.ClipboardUnsupportedError);
|
|
143
|
+
(0, chai_1.expect)(error === null || error === void 0 ? void 0 : error.message).to.match(/can only read/);
|
|
144
|
+
(0, chai_1.expect)(adb.calls).to.deep.equal([]);
|
|
145
|
+
}));
|
|
146
|
+
});
|
|
147
|
+
});
|
|
@@ -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
|
+
});
|
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/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-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/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