appium-remote-debugger 15.7.3 → 15.8.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/CHANGELOG.md +6 -0
- package/build/lib/atoms.d.ts.map +1 -1
- package/build/lib/atoms.js +27 -28
- package/build/lib/atoms.js.map +1 -1
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/index.js +7 -0
- package/build/lib/index.js.map +1 -1
- package/build/lib/mixins/connect.d.ts.map +1 -1
- package/build/lib/mixins/connect.js +21 -25
- package/build/lib/mixins/connect.js.map +1 -1
- package/build/lib/mixins/execute.d.ts.map +1 -1
- package/build/lib/mixins/execute.js +2 -8
- package/build/lib/mixins/execute.js.map +1 -1
- package/build/lib/mixins/message-handlers.d.ts.map +1 -1
- package/build/lib/mixins/message-handlers.js +8 -12
- package/build/lib/mixins/message-handlers.js.map +1 -1
- package/build/lib/mixins/misc.d.ts.map +1 -1
- package/build/lib/mixins/misc.js +5 -39
- package/build/lib/mixins/misc.js.map +1 -1
- package/build/lib/mixins/navigate.d.ts.map +1 -1
- package/build/lib/mixins/navigate.js +20 -55
- package/build/lib/mixins/navigate.js.map +1 -1
- package/build/lib/mixins/property-accessors.d.ts +24 -0
- package/build/lib/mixins/property-accessors.d.ts.map +1 -1
- package/build/lib/mixins/property-accessors.js +24 -0
- package/build/lib/mixins/property-accessors.js.map +1 -1
- package/build/lib/remote-debugger.d.ts +38 -38
- package/build/lib/remote-debugger.d.ts.map +1 -1
- package/build/lib/remote-debugger.js +64 -69
- package/build/lib/remote-debugger.js.map +1 -1
- package/build/lib/rpc/remote-messages.d.ts.map +1 -1
- package/build/lib/rpc/remote-messages.js +7 -8
- package/build/lib/rpc/remote-messages.js.map +1 -1
- package/build/lib/rpc/rpc-client-real-device-shim.d.ts.map +1 -1
- package/build/lib/rpc/rpc-client-real-device-shim.js +3 -6
- package/build/lib/rpc/rpc-client-real-device-shim.js.map +1 -1
- package/build/lib/rpc/rpc-client-simulator.d.ts.map +1 -1
- package/build/lib/rpc/rpc-client-simulator.js +3 -5
- package/build/lib/rpc/rpc-client-simulator.js.map +1 -1
- package/build/lib/rpc/rpc-client.d.ts +27 -27
- package/build/lib/rpc/rpc-client.d.ts.map +1 -1
- package/build/lib/rpc/rpc-client.js +226 -224
- package/build/lib/rpc/rpc-client.js.map +1 -1
- package/build/lib/rpc/rpc-message-handler.js +7 -10
- package/build/lib/rpc/rpc-message-handler.js.map +1 -1
- package/build/lib/types.d.ts +19 -19
- package/build/lib/types.d.ts.map +1 -1
- package/build/lib/utils.d.ts +70 -4
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +171 -23
- package/build/lib/utils.js.map +1 -1
- package/lib/atoms.ts +31 -32
- package/lib/index.ts +7 -0
- package/lib/mixins/connect.ts +22 -23
- package/lib/mixins/execute.ts +3 -5
- package/lib/mixins/message-handlers.ts +9 -10
- package/lib/mixins/misc.ts +8 -7
- package/lib/mixins/navigate.ts +58 -63
- package/lib/mixins/property-accessors.ts +24 -0
- package/lib/remote-debugger.ts +74 -76
- package/lib/rpc/remote-messages.ts +10 -5
- package/lib/rpc/rpc-client-real-device-shim.ts +3 -3
- package/lib/rpc/rpc-client-simulator.ts +3 -5
- package/lib/rpc/rpc-client.ts +259 -247
- package/lib/rpc/rpc-message-handler.ts +7 -7
- package/lib/types.ts +24 -24
- package/lib/utils.ts +181 -23
- package/package.json +3 -7
- package/scripts/common.mjs +42 -37
- package/scripts/web_inspector_proxy.mjs +3 -5
package/build/lib/utils.js
CHANGED
|
@@ -3,18 +3,27 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.TimeoutError = exports.RESPONSE_LOG_LENGTH = exports.WEB_CONTENT_BUNDLE_ID = void 0;
|
|
7
|
+
exports.truncateString = truncateString;
|
|
8
|
+
exports.defaults = defaults;
|
|
9
|
+
exports.isPlainObject = isPlainObject;
|
|
10
|
+
exports.isEmpty = isEmpty;
|
|
11
|
+
exports.uniq = uniq;
|
|
12
|
+
exports.deepEqual = deepEqual;
|
|
13
|
+
exports.delay = delay;
|
|
14
|
+
exports.withTimeout = withTimeout;
|
|
7
15
|
exports.appInfoFromDict = appInfoFromDict;
|
|
8
16
|
exports.pageArrayFromDict = pageArrayFromDict;
|
|
9
17
|
exports.appIdsForBundle = appIdsForBundle;
|
|
10
18
|
exports.checkParams = checkParams;
|
|
11
19
|
exports.simpleStringify = simpleStringify;
|
|
12
20
|
exports.convertJavascriptEvaluationResult = convertJavascriptEvaluationResult;
|
|
21
|
+
exports.getModuleRoot = getModuleRoot;
|
|
13
22
|
exports.getModuleProperties = getModuleProperties;
|
|
14
23
|
exports.canUseWebInspectorShim = canUseWebInspectorShim;
|
|
15
|
-
const lodash_1 = __importDefault(require("lodash"));
|
|
16
24
|
const base_driver_1 = require("@appium/base-driver");
|
|
17
25
|
const support_1 = require("@appium/support");
|
|
26
|
+
const node_util_1 = require("node:util");
|
|
18
27
|
const node_fs_1 = __importDefault(require("node:fs"));
|
|
19
28
|
const node_path_1 = __importDefault(require("node:path"));
|
|
20
29
|
const MODULE_NAME = 'appium-remote-debugger';
|
|
@@ -27,6 +36,132 @@ const ACCEPTED_PAGE_TYPES = [
|
|
|
27
36
|
'WIRTypePage', // iOS 11.4 webview
|
|
28
37
|
];
|
|
29
38
|
exports.RESPONSE_LOG_LENGTH = 100;
|
|
39
|
+
/**
|
|
40
|
+
* Error thrown when an async operation exceeds the configured timeout.
|
|
41
|
+
*/
|
|
42
|
+
class TimeoutError extends Error {
|
|
43
|
+
constructor(message = 'Operation timed out') {
|
|
44
|
+
super(message);
|
|
45
|
+
this.name = 'TimeoutError';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.TimeoutError = TimeoutError;
|
|
49
|
+
/**
|
|
50
|
+
* Truncates a string to the requested length and appends ellipsis when needed.
|
|
51
|
+
*
|
|
52
|
+
* @param value - The input string.
|
|
53
|
+
* @param length - Maximum output length.
|
|
54
|
+
* @returns The original string when short enough, otherwise a truncated variant.
|
|
55
|
+
*/
|
|
56
|
+
function truncateString(value, length) {
|
|
57
|
+
if (value.length <= length) {
|
|
58
|
+
return value;
|
|
59
|
+
}
|
|
60
|
+
return `${value.slice(0, Math.max(0, length - 1))}…`;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Creates a shallow object where undefined keys from `target` are filled
|
|
64
|
+
* from `defaultsObj`.
|
|
65
|
+
*
|
|
66
|
+
* @param target - The object with priority values.
|
|
67
|
+
* @param defaultsObj - The object providing fallback values.
|
|
68
|
+
* @returns A new object containing merged defaulted values.
|
|
69
|
+
*/
|
|
70
|
+
function defaults(target, defaultsObj) {
|
|
71
|
+
const result = { ...target };
|
|
72
|
+
for (const [key, value] of Object.entries(defaultsObj)) {
|
|
73
|
+
if (result[key] === undefined) {
|
|
74
|
+
result[key] = value;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Determines whether a value is a plain object.
|
|
81
|
+
*
|
|
82
|
+
* @param value - The value to check.
|
|
83
|
+
* @returns True when the value is a non-null non-array object.
|
|
84
|
+
*/
|
|
85
|
+
function isPlainObject(value) {
|
|
86
|
+
if (value == null || typeof value !== 'object' || Array.isArray(value)) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
const prototype = Object.getPrototypeOf(value);
|
|
90
|
+
return prototype === Object.prototype || prototype === null;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Checks whether a value should be treated as empty.
|
|
94
|
+
*
|
|
95
|
+
* @param value - The value to evaluate.
|
|
96
|
+
* @returns True for nullish values, empty arrays/strings/maps/sets, or empty objects.
|
|
97
|
+
*/
|
|
98
|
+
function isEmpty(value) {
|
|
99
|
+
if (value == null) {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
if (Array.isArray(value) || typeof value === 'string') {
|
|
103
|
+
return value.length === 0;
|
|
104
|
+
}
|
|
105
|
+
if (value instanceof Map || value instanceof Set) {
|
|
106
|
+
return value.size === 0;
|
|
107
|
+
}
|
|
108
|
+
if (isPlainObject(value)) {
|
|
109
|
+
return Object.keys(value).length === 0;
|
|
110
|
+
}
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Deduplicates array entries while preserving order.
|
|
115
|
+
*
|
|
116
|
+
* @param items - Items to deduplicate.
|
|
117
|
+
* @returns The input items without duplicates.
|
|
118
|
+
*/
|
|
119
|
+
function uniq(items) {
|
|
120
|
+
return [...new Set(items)];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Performs deep strict equality comparison.
|
|
124
|
+
*
|
|
125
|
+
* @param a - First value.
|
|
126
|
+
* @param b - Second value.
|
|
127
|
+
* @returns True when both values are deeply equal.
|
|
128
|
+
*/
|
|
129
|
+
function deepEqual(a, b) {
|
|
130
|
+
return (0, node_util_1.isDeepStrictEqual)(a, b);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Returns a promise that resolves after the specified delay.
|
|
134
|
+
*
|
|
135
|
+
* @param ms - Delay in milliseconds.
|
|
136
|
+
* @returns A promise that resolves when the delay expires.
|
|
137
|
+
*/
|
|
138
|
+
function delay(ms) {
|
|
139
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Wraps a promise with a timeout.
|
|
143
|
+
*
|
|
144
|
+
* @param promise - The promise to resolve.
|
|
145
|
+
* @param timeoutMs - Maximum time to wait in milliseconds.
|
|
146
|
+
* @param message - Optional timeout message.
|
|
147
|
+
* @returns A promise that resolves/rejects with the original promise result, or rejects on timeout.
|
|
148
|
+
*/
|
|
149
|
+
async function withTimeout(promise, timeoutMs, message) {
|
|
150
|
+
let timeoutId;
|
|
151
|
+
try {
|
|
152
|
+
return await Promise.race([
|
|
153
|
+
promise,
|
|
154
|
+
new Promise((_resolve, reject) => {
|
|
155
|
+
timeoutId = setTimeout(() => reject(new TimeoutError(message ?? `Operation timed out after ${timeoutMs}ms`)), timeoutMs);
|
|
156
|
+
}),
|
|
157
|
+
]);
|
|
158
|
+
}
|
|
159
|
+
finally {
|
|
160
|
+
if (timeoutId) {
|
|
161
|
+
clearTimeout(timeoutId);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
30
165
|
/**
|
|
31
166
|
* Takes a dictionary from the remote debugger and converts it into a more
|
|
32
167
|
* manageable AppInfo object with understandable keys.
|
|
@@ -36,15 +171,15 @@ exports.RESPONSE_LOG_LENGTH = 100;
|
|
|
36
171
|
*/
|
|
37
172
|
function appInfoFromDict(dict) {
|
|
38
173
|
const id = dict.WIRApplicationIdentifierKey;
|
|
39
|
-
const isProxy =
|
|
174
|
+
const isProxy = typeof dict.WIRIsApplicationProxyKey === 'string'
|
|
40
175
|
? dict.WIRIsApplicationProxyKey.toLowerCase() === 'true'
|
|
41
176
|
: dict.WIRIsApplicationProxyKey;
|
|
42
177
|
// automation enabled can be either from the keys
|
|
43
178
|
// - WIRRemoteAutomationEnabledKey (boolean)
|
|
44
179
|
// - WIRAutomationAvailabilityKey (string or boolean)
|
|
45
180
|
let isAutomationEnabled = !!dict.WIRRemoteAutomationEnabledKey;
|
|
46
|
-
if (
|
|
47
|
-
if (
|
|
181
|
+
if (Object.hasOwn(dict, 'WIRAutomationAvailabilityKey')) {
|
|
182
|
+
if (typeof dict.WIRAutomationAvailabilityKey === 'string') {
|
|
48
183
|
isAutomationEnabled =
|
|
49
184
|
dict.WIRAutomationAvailabilityKey === 'WIRAutomationAvailabilityUnknown'
|
|
50
185
|
? 'Unknown'
|
|
@@ -73,14 +208,14 @@ function appInfoFromDict(dict) {
|
|
|
73
208
|
* @returns An array of Page objects representing the available pages.
|
|
74
209
|
*/
|
|
75
210
|
function pageArrayFromDict(pageDict) {
|
|
76
|
-
return (
|
|
211
|
+
return (Object.values(pageDict)
|
|
77
212
|
// count only WIRTypeWeb pages and ignore all others (WIRTypeJavaScript etc)
|
|
78
|
-
.filter((dict) =>
|
|
213
|
+
.filter((dict) => dict.WIRTypeKey === undefined || ACCEPTED_PAGE_TYPES.includes(dict.WIRTypeKey))
|
|
79
214
|
.map((dict) => ({
|
|
80
215
|
id: dict.WIRPageIdentifierKey,
|
|
81
216
|
title: dict.WIRTitleKey,
|
|
82
217
|
url: dict.WIRURLKey,
|
|
83
|
-
isKey:
|
|
218
|
+
isKey: dict.WIRConnectionIdentifierKey !== undefined,
|
|
84
219
|
})));
|
|
85
220
|
}
|
|
86
221
|
/**
|
|
@@ -93,14 +228,14 @@ function pageArrayFromDict(pageDict) {
|
|
|
93
228
|
* @returns An array of unique application identifier keys matching the bundle ID.
|
|
94
229
|
*/
|
|
95
230
|
function appIdsForBundle(bundleId, appDict) {
|
|
96
|
-
const appIds =
|
|
231
|
+
const appIds = Object.entries(appDict)
|
|
97
232
|
.filter(([, data]) => data.bundleId === bundleId)
|
|
98
233
|
.map(([key]) => key);
|
|
99
234
|
// if nothing is found, try to get the generic app
|
|
100
235
|
if (appIds.length === 0 && bundleId !== exports.WEB_CONTENT_BUNDLE_ID) {
|
|
101
236
|
return appIdsForBundle(exports.WEB_CONTENT_BUNDLE_ID, appDict);
|
|
102
237
|
}
|
|
103
|
-
return
|
|
238
|
+
return uniq(appIds);
|
|
104
239
|
}
|
|
105
240
|
/**
|
|
106
241
|
* Validates that all parameters in the provided object have non-nil values.
|
|
@@ -113,8 +248,8 @@ function appIdsForBundle(bundleId, appDict) {
|
|
|
113
248
|
*/
|
|
114
249
|
function checkParams(params) {
|
|
115
250
|
// check if all parameters have a value
|
|
116
|
-
const errors =
|
|
117
|
-
.filter(([, value]) =>
|
|
251
|
+
const errors = Object.entries(params)
|
|
252
|
+
.filter(([, value]) => value == null)
|
|
118
253
|
.map(([param]) => param);
|
|
119
254
|
if (errors.length) {
|
|
120
255
|
throw new Error(`Missing ${support_1.util.pluralize('parameter', errors.length)}: ${errors.join(', ')}`);
|
|
@@ -133,7 +268,9 @@ function simpleStringify(value, multiline = false) {
|
|
|
133
268
|
if (!value) {
|
|
134
269
|
return JSON.stringify(value);
|
|
135
270
|
}
|
|
136
|
-
const cleanValue =
|
|
271
|
+
const cleanValue = value && (typeof value === 'object' || typeof value === 'function')
|
|
272
|
+
? removeNoisyProperties(structuredClone(value))
|
|
273
|
+
: value;
|
|
137
274
|
return multiline ? JSON.stringify(cleanValue, null, 2) : JSON.stringify(cleanValue);
|
|
138
275
|
}
|
|
139
276
|
/**
|
|
@@ -147,10 +284,10 @@ function simpleStringify(value, multiline = false) {
|
|
|
147
284
|
* an error status code.
|
|
148
285
|
*/
|
|
149
286
|
function convertJavascriptEvaluationResult(res) {
|
|
150
|
-
if (
|
|
151
|
-
throw new Error(`Did not get OK result from remote debugger. Result was: ${
|
|
287
|
+
if (res === undefined) {
|
|
288
|
+
throw new Error(`Did not get OK result from remote debugger. Result was: ${truncateString(simpleStringify(res), exports.RESPONSE_LOG_LENGTH)}`);
|
|
152
289
|
}
|
|
153
|
-
else if (
|
|
290
|
+
else if (typeof res === 'string') {
|
|
154
291
|
try {
|
|
155
292
|
res = JSON.parse(res);
|
|
156
293
|
}
|
|
@@ -159,16 +296,16 @@ function convertJavascriptEvaluationResult(res) {
|
|
|
159
296
|
// if we get here, it is just a value
|
|
160
297
|
}
|
|
161
298
|
}
|
|
162
|
-
else if (
|
|
299
|
+
else if ((typeof res !== 'object' && typeof res !== 'function') || res === null) {
|
|
163
300
|
throw new Error(`Result has unexpected type: (${typeof res}).`);
|
|
164
301
|
}
|
|
165
|
-
if (res
|
|
302
|
+
if (Object.hasOwn(res, 'status') && res.status !== 0) {
|
|
166
303
|
// we got some form of error.
|
|
167
304
|
throw (0, base_driver_1.errorFromMJSONWPStatusCode)(res.status, res.value.message || res.value);
|
|
168
305
|
}
|
|
169
306
|
// with either have an object with a `value` property (even if `null`),
|
|
170
307
|
// or a plain object
|
|
171
|
-
const value =
|
|
308
|
+
const value = Object.hasOwn(res, 'value') ? res.value : res;
|
|
172
309
|
return removeNoisyProperties(value);
|
|
173
310
|
}
|
|
174
311
|
/**
|
|
@@ -178,20 +315,31 @@ function convertJavascriptEvaluationResult(res) {
|
|
|
178
315
|
* @returns The full path to the module root directory.
|
|
179
316
|
* @throws Error if the module root folder cannot be determined.
|
|
180
317
|
*/
|
|
181
|
-
|
|
318
|
+
let cachedModuleRoot;
|
|
319
|
+
/**
|
|
320
|
+
* Calculates and memoizes the path to the current module root.
|
|
321
|
+
*
|
|
322
|
+
* @returns The full path to the module root directory.
|
|
323
|
+
* @throws Error if the module root folder cannot be determined.
|
|
324
|
+
*/
|
|
325
|
+
function getModuleRoot() {
|
|
326
|
+
if (cachedModuleRoot) {
|
|
327
|
+
return cachedModuleRoot;
|
|
328
|
+
}
|
|
182
329
|
const root = support_1.node.getModuleRootSync(MODULE_NAME, __filename);
|
|
183
330
|
if (!root) {
|
|
184
331
|
throw new Error(`Cannot find the root folder of the ${MODULE_NAME} Node.js module`);
|
|
185
332
|
}
|
|
333
|
+
cachedModuleRoot = root;
|
|
186
334
|
return root;
|
|
187
|
-
}
|
|
335
|
+
}
|
|
188
336
|
/**
|
|
189
337
|
* Reads and parses the package.json file from the module root.
|
|
190
338
|
*
|
|
191
339
|
* @returns The parsed package.json contents as a StringRecord.
|
|
192
340
|
*/
|
|
193
341
|
function getModuleProperties() {
|
|
194
|
-
const fullPath = node_path_1.default.resolve(
|
|
342
|
+
const fullPath = node_path_1.default.resolve(getModuleRoot(), 'package.json');
|
|
195
343
|
return JSON.parse(node_fs_1.default.readFileSync(fullPath, 'utf8'));
|
|
196
344
|
}
|
|
197
345
|
/**
|
|
@@ -210,7 +358,7 @@ function canUseWebInspectorShim(platformVersion) {
|
|
|
210
358
|
* @returns The cleaned object.
|
|
211
359
|
*/
|
|
212
360
|
function removeNoisyProperties(obj) {
|
|
213
|
-
if (
|
|
361
|
+
if (obj && typeof obj === 'object') {
|
|
214
362
|
for (const property of ['ceil', 'clone', 'floor', 'round', 'scale', 'toString']) {
|
|
215
363
|
delete obj[property];
|
|
216
364
|
}
|
package/build/lib/utils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../lib/utils.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../lib/utils.ts"],"names":[],"mappings":"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"}
|
package/lib/atoms.ts
CHANGED
|
@@ -1,24 +1,10 @@
|
|
|
1
1
|
import {fs} from '@appium/support';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import _ from 'lodash';
|
|
4
3
|
import {log} from './logger';
|
|
5
4
|
import {getModuleRoot} from './utils';
|
|
6
5
|
|
|
7
6
|
const ATOMS_CACHE: Record<string, Buffer> = {};
|
|
8
7
|
|
|
9
|
-
/**
|
|
10
|
-
* Converts a value to a JSON string, handling undefined values specially.
|
|
11
|
-
*
|
|
12
|
-
* @param obj - The value to stringify.
|
|
13
|
-
* @returns A JSON string representation of the value, or 'undefined' if the value is undefined.
|
|
14
|
-
*/
|
|
15
|
-
function atomsStringify(obj: any): string {
|
|
16
|
-
if (typeof obj === 'undefined') {
|
|
17
|
-
return 'undefined';
|
|
18
|
-
}
|
|
19
|
-
return JSON.stringify(obj);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
8
|
/**
|
|
23
9
|
* Loads an atom script from the atoms directory and caches it.
|
|
24
10
|
* If the atom has been loaded before, returns the cached version.
|
|
@@ -29,7 +15,7 @@ function atomsStringify(obj: any): string {
|
|
|
29
15
|
*/
|
|
30
16
|
export async function getAtom(atomName: string): Promise<Buffer> {
|
|
31
17
|
// check if we have already loaded and cached this atom
|
|
32
|
-
if (!
|
|
18
|
+
if (!Object.hasOwn(ATOMS_CACHE, atomName)) {
|
|
33
19
|
const atomFileName = path.resolve(getModuleRoot(), 'atoms', `${atomName}.js`);
|
|
34
20
|
try {
|
|
35
21
|
ATOMS_CACHE[atomName] = await fs.readFile(atomFileName);
|
|
@@ -41,23 +27,6 @@ export async function getAtom(atomName: string): Promise<Buffer> {
|
|
|
41
27
|
return ATOMS_CACHE[atomName];
|
|
42
28
|
}
|
|
43
29
|
|
|
44
|
-
/**
|
|
45
|
-
* Wraps a script to execute it within a specific frame context.
|
|
46
|
-
* Uses the get_element_from_cache atom to access the frame element.
|
|
47
|
-
*
|
|
48
|
-
* @param script - The script to wrap.
|
|
49
|
-
* @param frame - The frame identifier to execute the script in.
|
|
50
|
-
* @returns A promise that resolves to the wrapped script string.
|
|
51
|
-
*/
|
|
52
|
-
async function wrapScriptForFrame(script: string, frame: string): Promise<string> {
|
|
53
|
-
log.debug(`Wrapping script for frame '${frame}'`);
|
|
54
|
-
const elFromCache = await getAtom('get_element_from_cache');
|
|
55
|
-
return (
|
|
56
|
-
`(function (window) { var document = window.document; ` +
|
|
57
|
-
`return (${script}); })((${elFromCache.toString('utf8')})(${atomsStringify(frame)}))`
|
|
58
|
-
);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
30
|
/**
|
|
62
31
|
* Generates a complete script string for executing a Selenium atom.
|
|
63
32
|
* Handles frame contexts and optional async callbacks.
|
|
@@ -98,3 +67,33 @@ export async function getScriptForAtom(
|
|
|
98
67
|
|
|
99
68
|
return script;
|
|
100
69
|
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Converts a value to a JSON string, handling undefined values specially.
|
|
73
|
+
*
|
|
74
|
+
* @param obj - The value to stringify.
|
|
75
|
+
* @returns A JSON string representation of the value, or 'undefined' if the value is undefined.
|
|
76
|
+
*/
|
|
77
|
+
function atomsStringify(obj: any): string {
|
|
78
|
+
if (typeof obj === 'undefined') {
|
|
79
|
+
return 'undefined';
|
|
80
|
+
}
|
|
81
|
+
return JSON.stringify(obj);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Wraps a script to execute it within a specific frame context.
|
|
86
|
+
* Uses the get_element_from_cache atom to access the frame element.
|
|
87
|
+
*
|
|
88
|
+
* @param script - The script to wrap.
|
|
89
|
+
* @param frame - The frame identifier to execute the script in.
|
|
90
|
+
* @returns A promise that resolves to the wrapped script string.
|
|
91
|
+
*/
|
|
92
|
+
async function wrapScriptForFrame(script: string, frame: string): Promise<string> {
|
|
93
|
+
log.debug(`Wrapping script for frame '${frame}'`);
|
|
94
|
+
const elFromCache = await getAtom('get_element_from_cache');
|
|
95
|
+
return (
|
|
96
|
+
`(function (window) { var document = window.document; ` +
|
|
97
|
+
`return (${script}); })((${elFromCache.toString('utf8')})(${atomsStringify(frame)}))`
|
|
98
|
+
);
|
|
99
|
+
}
|
package/lib/index.ts
CHANGED
|
@@ -10,6 +10,13 @@ export function createRemoteDebugger(
|
|
|
10
10
|
opts: RemoteDebuggerOptions,
|
|
11
11
|
realDevice: false,
|
|
12
12
|
): RemoteDebugger;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a remote debugger instance for either simulator or real device flows.
|
|
15
|
+
*
|
|
16
|
+
* @param opts - Configuration options for the selected debugger type.
|
|
17
|
+
* @param realDevice - Whether to create the real-device debugger implementation.
|
|
18
|
+
* @returns The initialized debugger instance for the selected target type.
|
|
19
|
+
*/
|
|
13
20
|
export function createRemoteDebugger(
|
|
14
21
|
opts: RemoteDebuggerRealDeviceOptions | RemoteDebuggerOptions,
|
|
15
22
|
realDevice: boolean,
|
package/lib/mixins/connect.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {pageArrayFromDict, WEB_CONTENT_BUNDLE_ID, appIdsForBundle} from '../utils';
|
|
1
|
+
import {isEmpty, pageArrayFromDict, uniq, WEB_CONTENT_BUNDLE_ID, appIdsForBundle} from '../utils';
|
|
2
2
|
import {events} from './events';
|
|
3
3
|
import {timing, util} from '@appium/support';
|
|
4
4
|
import {retryInterval, waitForCondition} from 'asyncbox';
|
|
5
|
-
import _ from 'lodash';
|
|
6
5
|
import {
|
|
7
6
|
setAppIdKey,
|
|
8
7
|
getAppDict,
|
|
@@ -66,7 +65,7 @@ export async function connect(
|
|
|
66
65
|
const rpcClient = this.requireRpcClient();
|
|
67
66
|
|
|
68
67
|
// listen for basic debugger-level events
|
|
69
|
-
rpcClient.on('_rpc_reportSetup:',
|
|
68
|
+
rpcClient.on('_rpc_reportSetup:', () => {});
|
|
70
69
|
rpcClient.on('_rpc_forwardGetListing:', this.onPageChange.bind(this));
|
|
71
70
|
rpcClient.on('_rpc_reportConnectedApplicationList:', this.onConnectedApplicationList.bind(this));
|
|
72
71
|
rpcClient.on('_rpc_applicationConnected:', this.onAppConnect.bind(this));
|
|
@@ -85,12 +84,12 @@ export async function connect(
|
|
|
85
84
|
const timer = new timing.Timer().start();
|
|
86
85
|
this.log.debug(`Waiting up to ${timeout}ms for applications to be reported`);
|
|
87
86
|
try {
|
|
88
|
-
await waitForCondition(() => !
|
|
87
|
+
await waitForCondition(() => !isEmpty(getAppDict(this)), {
|
|
89
88
|
waitMs: timeout,
|
|
90
89
|
intervalMs: APP_CONNECT_INTERVAL_MS,
|
|
91
90
|
});
|
|
92
91
|
this.log.debug(
|
|
93
|
-
`Retrieved ${util.pluralize('application',
|
|
92
|
+
`Retrieved ${util.pluralize('application', Object.keys(getAppDict(this)).length, true)} ` +
|
|
94
93
|
`within ${timer.getDuration().asMilliSeconds.toFixed(0)}ms`,
|
|
95
94
|
);
|
|
96
95
|
} catch {
|
|
@@ -139,7 +138,7 @@ export async function selectApp(
|
|
|
139
138
|
this.log.debug('Selecting application');
|
|
140
139
|
|
|
141
140
|
const timer = new timing.Timer().start();
|
|
142
|
-
if (
|
|
141
|
+
if (isEmpty(getAppDict(this))) {
|
|
143
142
|
this.log.debug('No applications currently connected.');
|
|
144
143
|
return [];
|
|
145
144
|
}
|
|
@@ -160,14 +159,14 @@ export async function selectApp(
|
|
|
160
159
|
this.log.debug(`Finally selecting app ${getAppIdKey(this)}`);
|
|
161
160
|
|
|
162
161
|
const fullPageArray: Page[] = [];
|
|
163
|
-
for (const [app, info] of
|
|
164
|
-
if (!
|
|
162
|
+
for (const [app, info] of Object.entries(getAppDict(this))) {
|
|
163
|
+
if (!Array.isArray(info.pageArray) || !info.isActive) {
|
|
165
164
|
continue;
|
|
166
165
|
}
|
|
167
166
|
const id = app.replace('PID:', '');
|
|
168
167
|
for (const page of info.pageArray) {
|
|
169
168
|
if (!(ignoreAboutBlankUrl && page.url === BLANK_PAGE_URL)) {
|
|
170
|
-
const pageDict =
|
|
169
|
+
const pageDict = {...page};
|
|
171
170
|
pageDict.id = `${id}.${pageDict.id}`;
|
|
172
171
|
pageDict.bundleId = info.bundleId;
|
|
173
172
|
fullPageArray.push(pageDict);
|
|
@@ -196,7 +195,7 @@ export async function selectPage(
|
|
|
196
195
|
pageIdKey: PageIdKey,
|
|
197
196
|
skipReadyCheck: boolean = false,
|
|
198
197
|
): Promise<void> {
|
|
199
|
-
const fullAppIdKey =
|
|
198
|
+
const fullAppIdKey = `${appIdKey}`.startsWith('PID:') ? `${appIdKey}` : `PID:${appIdKey}`;
|
|
200
199
|
setAppIdKey(this, fullAppIdKey);
|
|
201
200
|
setPageIdKey(this, pageIdKey);
|
|
202
201
|
|
|
@@ -233,11 +232,11 @@ export function getPossibleDebuggerAppKeys(this: RemoteDebugger, bundleIds: stri
|
|
|
233
232
|
this.log.info(
|
|
234
233
|
'Returning all apps because the list of matching bundle identifiers includes a wildcard',
|
|
235
234
|
);
|
|
236
|
-
return
|
|
235
|
+
return Object.keys(appDict);
|
|
237
236
|
}
|
|
238
237
|
|
|
239
238
|
// go through the possible bundle identifiers
|
|
240
|
-
const possibleBundleIds =
|
|
239
|
+
const possibleBundleIds = uniq([
|
|
241
240
|
WEB_CONTENT_BUNDLE_ID,
|
|
242
241
|
WEB_CONTENT_PROCESS_BUNDLE_ID,
|
|
243
242
|
SAFARI_VIEW_PROCESS_BUNDLE_ID,
|
|
@@ -257,7 +256,7 @@ export function getPossibleDebuggerAppKeys(this: RemoteDebugger, bundleIds: stri
|
|
|
257
256
|
|
|
258
257
|
proxiedAppIds.push(appId);
|
|
259
258
|
this.log.debug(`Found app id key '${appId}' for bundle '${bundleId}'`);
|
|
260
|
-
for (const [key, data] of
|
|
259
|
+
for (const [key, data] of Object.entries(appDict)) {
|
|
261
260
|
if (data.isProxy && data.hostId === appId && !proxiedAppIds.includes(key)) {
|
|
262
261
|
this.log.debug(
|
|
263
262
|
`Found separate bundleId '${data.bundleId}' ` +
|
|
@@ -274,7 +273,7 @@ export function getPossibleDebuggerAppKeys(this: RemoteDebugger, bundleIds: stri
|
|
|
274
273
|
`capability to match other applications. Add a wildcard ('*') to match all apps.`,
|
|
275
274
|
);
|
|
276
275
|
|
|
277
|
-
return
|
|
276
|
+
return uniq(proxiedAppIds);
|
|
278
277
|
}
|
|
279
278
|
|
|
280
279
|
/**
|
|
@@ -298,11 +297,11 @@ async function searchForApp(
|
|
|
298
297
|
maxTries: number,
|
|
299
298
|
ignoreAboutBlankUrl: boolean,
|
|
300
299
|
): Promise<AppPage> {
|
|
301
|
-
const bundleIds: string[] =
|
|
300
|
+
const bundleIds: string[] = [
|
|
302
301
|
getBundleId(this),
|
|
303
302
|
...(getAdditionalBundleIds(this) ?? []),
|
|
304
303
|
...(getIncludeSafari(this) && !getIsSafari(this) ? [SAFARI_BUNDLE_ID] : []),
|
|
305
|
-
]);
|
|
304
|
+
].filter((bundleId): bundleId is string => !!bundleId);
|
|
306
305
|
let retryCount = 0;
|
|
307
306
|
return (await retryInterval(maxTries, SELECT_APP_RETRY_SLEEP_MS, async () => {
|
|
308
307
|
logApplicationDictionary.bind(this)();
|
|
@@ -381,8 +380,8 @@ function searchForPage(
|
|
|
381
380
|
currentUrl: string | null = null,
|
|
382
381
|
ignoreAboutBlankUrl: boolean = false,
|
|
383
382
|
): AppPage | null {
|
|
384
|
-
for (const appDict of
|
|
385
|
-
if (!appDict || !appDict.isActive || !appDict.pageArray ||
|
|
383
|
+
for (const appDict of Object.values(appsDict)) {
|
|
384
|
+
if (!appDict || !appDict.isActive || !appDict.pageArray || appDict.pageArray.length === 0) {
|
|
386
385
|
continue;
|
|
387
386
|
}
|
|
388
387
|
|
|
@@ -418,7 +417,7 @@ function isAppIgnored(instance: RemoteDebugger): boolean {
|
|
|
418
417
|
return false;
|
|
419
418
|
}
|
|
420
419
|
const ignoredSet = new Set(ignoredBundleIds);
|
|
421
|
-
const appBundleIds = new Set(
|
|
420
|
+
const appBundleIds = new Set(Object.values(getAppDict(instance)).map((app) => app.bundleId));
|
|
422
421
|
if (appBundleIds.size === 0) {
|
|
423
422
|
return false;
|
|
424
423
|
}
|
|
@@ -447,20 +446,20 @@ function isAppIgnored(instance: RemoteDebugger): boolean {
|
|
|
447
446
|
*/
|
|
448
447
|
function logApplicationDictionary(this: RemoteDebugger): void {
|
|
449
448
|
this.log.debug('Current applications available:');
|
|
450
|
-
for (const [app, info] of
|
|
449
|
+
for (const [app, info] of Object.entries(getAppDict(this))) {
|
|
451
450
|
this.log.debug(` Application: "${app}"`);
|
|
452
|
-
for (const [key, value] of
|
|
451
|
+
for (const [key, value] of Object.entries(info)) {
|
|
453
452
|
if (key === 'pageArray' && Array.isArray(value) && value.length) {
|
|
454
453
|
this.log.debug(` ${key}:`);
|
|
455
454
|
for (const page of value) {
|
|
456
455
|
let prefix = '- ';
|
|
457
|
-
for (const [k, v] of
|
|
456
|
+
for (const [k, v] of Object.entries(page)) {
|
|
458
457
|
this.log.debug(` ${prefix}${k}: ${JSON.stringify(v)}`);
|
|
459
458
|
prefix = ' ';
|
|
460
459
|
}
|
|
461
460
|
}
|
|
462
461
|
} else {
|
|
463
|
-
const valueString =
|
|
462
|
+
const valueString = typeof value === 'function' ? '[Function]' : JSON.stringify(value);
|
|
464
463
|
this.log.debug(` ${key}: ${valueString}`);
|
|
465
464
|
}
|
|
466
465
|
}
|
package/lib/mixins/execute.ts
CHANGED
|
@@ -4,11 +4,11 @@ import {
|
|
|
4
4
|
simpleStringify,
|
|
5
5
|
convertJavascriptEvaluationResult,
|
|
6
6
|
RESPONSE_LOG_LENGTH,
|
|
7
|
+
truncateString,
|
|
7
8
|
} from '../utils';
|
|
8
9
|
import {getScriptForAtom} from '../atoms';
|
|
9
10
|
import {util, timing} from '@appium/support';
|
|
10
11
|
import {retryInterval} from 'asyncbox';
|
|
11
|
-
import _ from 'lodash';
|
|
12
12
|
import {getAppIdKey, getPageIdKey, getGarbageCollectOnExecute} from './property-accessors';
|
|
13
13
|
import type {RemoteDebugger} from '../remote-debugger';
|
|
14
14
|
import type {AppIdKey, PageIdKey} from '../types';
|
|
@@ -35,9 +35,7 @@ export async function executeAtom(
|
|
|
35
35
|
const script = await getScriptForAtom(atom, args, frames);
|
|
36
36
|
const value = await this.execute(script);
|
|
37
37
|
this.log.debug(
|
|
38
|
-
`Received result for atom '${atom}' execution: ${
|
|
39
|
-
length: RESPONSE_LOG_LENGTH,
|
|
40
|
-
})}`,
|
|
38
|
+
`Received result for atom '${atom}' execution: ${truncateString(simpleStringify(value), RESPONSE_LOG_LENGTH)}`,
|
|
41
39
|
);
|
|
42
40
|
return value;
|
|
43
41
|
}
|
|
@@ -177,7 +175,7 @@ export async function execute(
|
|
|
177
175
|
|
|
178
176
|
const rpcClient = this.requireRpcClient(true);
|
|
179
177
|
await rpcClient.waitForPage(appIdKey as AppIdKey, pageIdKey as PageIdKey);
|
|
180
|
-
this.log.debug(`Sending javascript command: '${
|
|
178
|
+
this.log.debug(`Sending javascript command: '${truncateString(command, 50)}'`);
|
|
181
179
|
const res = await rpcClient.send('Runtime.evaluate', {
|
|
182
180
|
expression: command,
|
|
183
181
|
returnByValue: true,
|