appium-xcuitest-driver 7.21.0 → 7.21.1
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/commands/log.d.ts +0 -8
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +4 -13
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/commands/types.d.ts +5 -0
- package/build/lib/commands/types.d.ts.map +1 -1
- package/build/lib/device-log/helpers.d.ts +3 -0
- package/build/lib/device-log/helpers.d.ts.map +1 -0
- package/build/lib/device-log/helpers.js +11 -0
- package/build/lib/device-log/helpers.js.map +1 -0
- package/build/lib/device-log/ios-crash-log.d.ts +6 -17
- package/build/lib/device-log/ios-crash-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-crash-log.js +4 -10
- package/build/lib/device-log/ios-crash-log.js.map +1 -1
- package/build/lib/device-log/ios-device-log.d.ts +5 -2
- package/build/lib/device-log/ios-device-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-device-log.js +3 -0
- package/build/lib/device-log/ios-device-log.js.map +1 -1
- package/build/lib/device-log/ios-log.d.ts +36 -7
- package/build/lib/device-log/ios-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-log.js +73 -25
- package/build/lib/device-log/ios-log.js.map +1 -1
- package/build/lib/device-log/ios-performance-log.d.ts +25 -8
- package/build/lib/device-log/ios-performance-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-performance-log.js +40 -23
- package/build/lib/device-log/ios-performance-log.js.map +1 -1
- package/build/lib/device-log/ios-simulator-log.d.ts +11 -4
- package/build/lib/device-log/ios-simulator-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-simulator-log.js +41 -47
- package/build/lib/device-log/ios-simulator-log.js.map +1 -1
- package/lib/commands/log.js +6 -14
- package/lib/commands/types.ts +6 -0
- package/lib/device-log/helpers.ts +9 -0
- package/lib/device-log/ios-crash-log.js +4 -11
- package/lib/device-log/ios-device-log.js +4 -2
- package/lib/device-log/ios-log.js +78 -27
- package/lib/device-log/ios-performance-log.js +40 -29
- package/lib/device-log/ios-simulator-log.js +45 -49
- package/npm-shrinkwrap.json +52 -27
- package/package.json +2 -2
|
@@ -6,43 +6,60 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.IOSPerformanceLog = void 0;
|
|
7
7
|
const support_1 = require("appium/support");
|
|
8
8
|
const lodash_1 = __importDefault(require("lodash"));
|
|
9
|
+
const ios_log_1 = require("./ios-log");
|
|
9
10
|
const log = support_1.logger.getLogger('IOSPerformanceLog');
|
|
10
11
|
const MAX_EVENTS = 5000;
|
|
11
|
-
class IOSPerformanceLog {
|
|
12
|
+
class IOSPerformanceLog extends ios_log_1.IOSLog {
|
|
12
13
|
constructor(remoteDebugger, maxEvents = MAX_EVENTS) {
|
|
14
|
+
super(maxEvents);
|
|
13
15
|
this.remoteDebugger = remoteDebugger;
|
|
14
16
|
this.maxEvents = parseInt(String(maxEvents), 10);
|
|
15
|
-
this.
|
|
17
|
+
this._started = false;
|
|
16
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* @override
|
|
21
|
+
*/
|
|
17
22
|
async startCapture() {
|
|
18
23
|
log.debug('Starting performance (Timeline) log capture');
|
|
19
|
-
this.
|
|
20
|
-
|
|
24
|
+
this._clearEntries();
|
|
25
|
+
const result = await this.remoteDebugger.startTimeline(this.onTimelineEvent.bind(this));
|
|
26
|
+
this._started = true;
|
|
27
|
+
return result;
|
|
21
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* @override
|
|
31
|
+
*/
|
|
22
32
|
async stopCapture() {
|
|
23
33
|
log.debug('Stopping performance (Timeline) log capture');
|
|
24
|
-
|
|
34
|
+
const result = await this.remoteDebugger.stopTimeline();
|
|
35
|
+
this._started = false;
|
|
36
|
+
return result;
|
|
25
37
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
38
|
+
/**
|
|
39
|
+
* @override
|
|
40
|
+
*/
|
|
41
|
+
get isCapturing() {
|
|
42
|
+
return this._started;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* @override
|
|
46
|
+
*/
|
|
47
|
+
_serializeEntry(value) {
|
|
48
|
+
return value;
|
|
34
49
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
this.timelineEvents = [];
|
|
41
|
-
return events;
|
|
50
|
+
/**
|
|
51
|
+
* @override
|
|
52
|
+
*/
|
|
53
|
+
_deserializeEntry(value) {
|
|
54
|
+
return value;
|
|
42
55
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param {import('../commands/types').LogEntry} event
|
|
59
|
+
*/
|
|
60
|
+
onTimelineEvent(event) {
|
|
61
|
+
log.debug(`Received Timeline event: ${lodash_1.default.truncate(JSON.stringify(event))}`);
|
|
62
|
+
this.broadcast(event);
|
|
46
63
|
}
|
|
47
64
|
}
|
|
48
65
|
exports.IOSPerformanceLog = IOSPerformanceLog;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios-performance-log.js","sourceRoot":"","sources":["../../../lib/device-log/ios-performance-log.js"],"names":[],"mappings":";;;;;;AAAA,4CAAsC;AACtC,oDAAuB;
|
|
1
|
+
{"version":3,"file":"ios-performance-log.js","sourceRoot":"","sources":["../../../lib/device-log/ios-performance-log.js"],"names":[],"mappings":";;;;;;AAAA,4CAAsC;AACtC,oDAAuB;AACvB,uCAAmC;AAEnC,MAAM,GAAG,GAAG,gBAAM,CAAC,SAAS,CAAC,mBAAmB,CAAC,CAAC;AAClD,MAAM,UAAU,GAAG,IAAI,CAAC;AAExB,MAAa,iBAAkB,SAAQ,gBAAM;IAC3C,YAAY,cAAc,EAAE,SAAS,GAAG,UAAU;QAChD,KAAK,CAAC,SAAS,CAAC,CAAC;QACjB,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;IACxB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,GAAG,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACzD,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACxF,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,GAAG,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QACzD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QACxD,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,IAAI,WAAW;QACb,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,eAAe,CAAC,KAAK;QACnB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,KAAK;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,eAAe,CAAC,KAAK;QACnB,GAAG,CAAC,KAAK,CAAC,4BAA4B,gBAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3E,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACxB,CAAC;CACF;AA1DD,8CA0DC;AAED,kBAAe,iBAAiB,CAAC"}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export default IOSSimulatorLog;
|
|
2
1
|
export class IOSSimulatorLog extends IOSLog {
|
|
3
2
|
constructor({ sim, showLogs, xcodeVersion, iosSimulatorLogsPredicate }: {
|
|
4
3
|
sim: any;
|
|
@@ -11,10 +10,18 @@ export class IOSSimulatorLog extends IOSLog {
|
|
|
11
10
|
xcodeVersion: any;
|
|
12
11
|
predicate: any;
|
|
13
12
|
proc: any;
|
|
14
|
-
|
|
13
|
+
/**
|
|
14
|
+
* @override
|
|
15
|
+
*/
|
|
16
|
+
override get isCapturing(): any;
|
|
17
|
+
/**
|
|
18
|
+
* @param {string} logRow
|
|
19
|
+
* @param {string} [prefix='']
|
|
20
|
+
*/
|
|
21
|
+
onOutput(logRow: string, prefix?: string | undefined): void;
|
|
15
22
|
killLogSubProcess(): Promise<void>;
|
|
16
|
-
|
|
17
|
-
onOutput(logRow: any, prefix?: string): void;
|
|
23
|
+
finishStartingLogCapture(): Promise<void>;
|
|
18
24
|
}
|
|
25
|
+
export default IOSSimulatorLog;
|
|
19
26
|
import { IOSLog } from './ios-log';
|
|
20
27
|
//# sourceMappingURL=ios-simulator-log.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios-simulator-log.d.ts","sourceRoot":"","sources":["../../../lib/device-log/ios-simulator-log.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"ios-simulator-log.d.ts","sourceRoot":"","sources":["../../../lib/device-log/ios-simulator-log.js"],"names":[],"mappings":"AAUA;IACE;;;;;OAOC;IALC,SAAc;IACd,kBAA0B;IAC1B,kBAAgC;IAChC,eAA0C;IAC1C,UAAgB;IA4ClB;;OAEG;IACH,gCAEC;IAED;;;OAGG;IACH,iBAHW,MAAM,qCAShB;IAED,mCAcC;IAED,0CAoBC;CACF;;uBApHoB,WAAW"}
|
|
@@ -9,6 +9,7 @@ const ios_log_1 = require("./ios-log");
|
|
|
9
9
|
const support_1 = require("appium/support");
|
|
10
10
|
const teen_process_1 = require("teen_process");
|
|
11
11
|
const log = support_1.logger.getLogger('IOSSimulatorLog');
|
|
12
|
+
const EXECVP_ERROR_PATTERN = /execvp\(\)/;
|
|
12
13
|
const START_TIMEOUT = 10000;
|
|
13
14
|
class IOSSimulatorLog extends ios_log_1.IOSLog {
|
|
14
15
|
constructor({ sim, showLogs, xcodeVersion, iosSimulatorLogsPredicate }) {
|
|
@@ -19,6 +20,9 @@ class IOSSimulatorLog extends ios_log_1.IOSLog {
|
|
|
19
20
|
this.predicate = iosSimulatorLogsPredicate;
|
|
20
21
|
this.proc = null;
|
|
21
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* @override
|
|
25
|
+
*/
|
|
22
26
|
async startCapture() {
|
|
23
27
|
if (lodash_1.default.isUndefined(this.sim.udid)) {
|
|
24
28
|
throw new Error(`Log capture requires a sim udid`);
|
|
@@ -44,40 +48,9 @@ class IOSSimulatorLog extends ios_log_1.IOSLog {
|
|
|
44
48
|
throw new Error(`Simulator log capture failed. Original error: ${e.message}`);
|
|
45
49
|
}
|
|
46
50
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
let firstLine = true;
|
|
52
|
-
let logRow = '';
|
|
53
|
-
this.proc.on('output', (stdout, stderr) => {
|
|
54
|
-
if (stdout) {
|
|
55
|
-
if (firstLine) {
|
|
56
|
-
if (stdout.endsWith('\n')) {
|
|
57
|
-
// don't store the first line of the log because it came before the sim was launched
|
|
58
|
-
firstLine = false;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
logRow += stdout;
|
|
63
|
-
if (stdout.endsWith('\n')) {
|
|
64
|
-
this.onOutput(logRow);
|
|
65
|
-
logRow = '';
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (stderr) {
|
|
70
|
-
this.onOutput(logRow, 'STDERR');
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
let sd = (stdout, stderr) => {
|
|
74
|
-
if (/execvp\(\)/.test(stderr)) {
|
|
75
|
-
throw new Error('iOS log capture process failed to start');
|
|
76
|
-
}
|
|
77
|
-
return stdout || stderr;
|
|
78
|
-
};
|
|
79
|
-
await this.proc.start(sd, START_TIMEOUT);
|
|
80
|
-
}
|
|
51
|
+
/**
|
|
52
|
+
* @override
|
|
53
|
+
*/
|
|
81
54
|
async stopCapture() {
|
|
82
55
|
if (!this.proc) {
|
|
83
56
|
return;
|
|
@@ -85,6 +58,23 @@ class IOSSimulatorLog extends ios_log_1.IOSLog {
|
|
|
85
58
|
await this.killLogSubProcess();
|
|
86
59
|
this.proc = null;
|
|
87
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* @override
|
|
63
|
+
*/
|
|
64
|
+
get isCapturing() {
|
|
65
|
+
return this.proc && this.proc.isRunning;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* @param {string} logRow
|
|
69
|
+
* @param {string} [prefix='']
|
|
70
|
+
*/
|
|
71
|
+
onOutput(logRow, prefix = '') {
|
|
72
|
+
this.broadcast(logRow);
|
|
73
|
+
if (this.showLogs) {
|
|
74
|
+
const space = prefix.length > 0 ? ' ' : '';
|
|
75
|
+
log.info(`[IOS_SYSLOG_ROW${space}${prefix}] ${logRow}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
88
78
|
async killLogSubProcess() {
|
|
89
79
|
if (!this.proc.isRunning) {
|
|
90
80
|
return;
|
|
@@ -101,20 +91,24 @@ class IOSSimulatorLog extends ios_log_1.IOSLog {
|
|
|
101
91
|
await this.proc.stop('SIGKILL');
|
|
102
92
|
}
|
|
103
93
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const space = prefix.length > 0 ? ' ' : '';
|
|
115
|
-
log.info(`[IOS_SYSLOG_ROW${space}${prefix}] ${logLine}`);
|
|
116
|
-
}
|
|
94
|
+
async finishStartingLogCapture() {
|
|
95
|
+
if (!this.proc) {
|
|
96
|
+
log.errorAndThrow('Could not capture simulator log');
|
|
97
|
+
}
|
|
98
|
+
for (const streamName of ['stdout', 'stderr']) {
|
|
99
|
+
this.proc.on(`lines-${streamName}`, (/** @type {string[]} */ lines) => {
|
|
100
|
+
for (const line of lines) {
|
|
101
|
+
this.onOutput(line, ...(streamName === 'stderr' ? ['STDERR'] : []));
|
|
102
|
+
}
|
|
103
|
+
});
|
|
117
104
|
}
|
|
105
|
+
const startDetector = (/** @type {string} */ stdout, /** @type {string} */ stderr) => {
|
|
106
|
+
if (EXECVP_ERROR_PATTERN.test(stderr)) {
|
|
107
|
+
throw new Error('iOS log capture process failed to start');
|
|
108
|
+
}
|
|
109
|
+
return stdout || stderr;
|
|
110
|
+
};
|
|
111
|
+
await this.proc.start(startDetector, START_TIMEOUT);
|
|
118
112
|
}
|
|
119
113
|
}
|
|
120
114
|
exports.IOSSimulatorLog = IOSSimulatorLog;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ios-simulator-log.js","sourceRoot":"","sources":["../../../lib/device-log/ios-simulator-log.js"],"names":[],"mappings":";;;;;;AAAA,oDAAuB;AACvB,uCAAiC;AACjC,4CAAsC;AACtC,+CAAkC;AAElC,MAAM,GAAG,GAAG,gBAAM,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"ios-simulator-log.js","sourceRoot":"","sources":["../../../lib/device-log/ios-simulator-log.js"],"names":[],"mappings":"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"}
|
package/lib/commands/log.js
CHANGED
|
@@ -8,6 +8,7 @@ import log from '../logger';
|
|
|
8
8
|
import WebSocket from 'ws';
|
|
9
9
|
import SafariConsoleLog from '../device-log/safari-console-log';
|
|
10
10
|
import SafariNetworkLog from '../device-log/safari-network-log';
|
|
11
|
+
import { toLogEntry } from '../device-log/helpers';
|
|
11
12
|
|
|
12
13
|
/**
|
|
13
14
|
* Determines the websocket endpoint based on the `sessionId`
|
|
@@ -47,27 +48,18 @@ const SUPPORTED_LOG_TYPES = {
|
|
|
47
48
|
server: {
|
|
48
49
|
description: 'Appium server logs',
|
|
49
50
|
/**
|
|
50
|
-
* @returns {
|
|
51
|
+
* @returns {import('./types').LogEntry[]}
|
|
51
52
|
*/
|
|
52
53
|
getter: (self) => {
|
|
53
54
|
self.assertFeatureEnabled(GET_SERVER_LOGS_FEATURE);
|
|
54
|
-
return log.unwrap().record.map((x) => (
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
}));
|
|
55
|
+
return log.unwrap().record.map((x) => toLogEntry(
|
|
56
|
+
_.isEmpty(x.prefix) ? x.message : `[${x.prefix}] ${x.message}`,
|
|
57
|
+
/** @type {any} */ (x).timestamp ?? Date.now()
|
|
58
|
+
));
|
|
59
59
|
},
|
|
60
60
|
},
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
/**
|
|
64
|
-
* Log entry in the array returned by `getLogs('server')`
|
|
65
|
-
* @typedef AppiumServerLogEntry
|
|
66
|
-
* @property {number} timestamp
|
|
67
|
-
* @property {'ALL'} level
|
|
68
|
-
* @property {string} message
|
|
69
|
-
*/
|
|
70
|
-
|
|
71
63
|
export default {
|
|
72
64
|
supportedLogTypes: SUPPORTED_LOG_TYPES,
|
|
73
65
|
/**
|
package/lib/commands/types.ts
CHANGED
|
@@ -11,13 +11,6 @@ const MAGIC_SEP = '/';
|
|
|
11
11
|
// The file format has been changed from '.crash' to '.ips' since Monterey.
|
|
12
12
|
const CRASH_REPORTS_GLOB_PATTERN = '**/*.@(crash|ips)';
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* @typedef {Object} LogRecord
|
|
16
|
-
* @property {number} timestamp
|
|
17
|
-
* @property {string} level
|
|
18
|
-
* @property {string} message
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
14
|
class IOSCrashLog {
|
|
22
15
|
constructor(opts = {}) {
|
|
23
16
|
this.udid = opts.udid;
|
|
@@ -103,7 +96,7 @@ class IOSCrashLog {
|
|
|
103
96
|
}
|
|
104
97
|
|
|
105
98
|
/**
|
|
106
|
-
* @returns {Promise<
|
|
99
|
+
* @returns {Promise<import('../commands/types').LogEntry[]>}
|
|
107
100
|
*/
|
|
108
101
|
async getLogs() {
|
|
109
102
|
let crashFiles = await this.getCrashes();
|
|
@@ -113,7 +106,7 @@ class IOSCrashLog {
|
|
|
113
106
|
}
|
|
114
107
|
|
|
115
108
|
/**
|
|
116
|
-
* @returns {Promise<
|
|
109
|
+
* @returns {Promise<import('../commands/types').LogEntry[]>}
|
|
117
110
|
*/
|
|
118
111
|
async getAllLogs() {
|
|
119
112
|
let crashFiles = await this.getCrashes();
|
|
@@ -123,12 +116,12 @@ class IOSCrashLog {
|
|
|
123
116
|
|
|
124
117
|
/**
|
|
125
118
|
* @param {string[]} paths
|
|
126
|
-
* @returns {Promise<
|
|
119
|
+
* @returns {Promise<import('../commands/types').LogEntry[]>}
|
|
127
120
|
*/
|
|
128
121
|
async filesToJSON(paths) {
|
|
129
122
|
const tmpRoot = await tempDir.openDir();
|
|
130
123
|
try {
|
|
131
|
-
return /** @type {
|
|
124
|
+
return /** @type {import('../commands/types').LogEntry[]} */ ((
|
|
132
125
|
await B.map(paths, async (fullPath) => {
|
|
133
126
|
if (_.includes(fullPath, REAL_DEVICE_MAGIC)) {
|
|
134
127
|
const fileName = /** @type {string} */ (_.last(fullPath.split(MAGIC_SEP)));
|
|
@@ -4,7 +4,7 @@ import {services} from 'appium-ios-device';
|
|
|
4
4
|
|
|
5
5
|
const log = logger.getLogger('IOSDeviceLog');
|
|
6
6
|
|
|
7
|
-
class IOSDeviceLog extends IOSLog {
|
|
7
|
+
export class IOSDeviceLog extends IOSLog {
|
|
8
8
|
constructor(opts) {
|
|
9
9
|
super();
|
|
10
10
|
this.udid = opts.udid;
|
|
@@ -22,6 +22,9 @@ class IOSDeviceLog extends IOSLog {
|
|
|
22
22
|
this.service.start(this.onLog.bind(this));
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* @param {string} logLine
|
|
27
|
+
*/
|
|
25
28
|
onLog(logLine) {
|
|
26
29
|
this.broadcast(logLine);
|
|
27
30
|
if (this.showLogs) {
|
|
@@ -50,5 +53,4 @@ class IOSDeviceLog extends IOSLog {
|
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
|
|
53
|
-
export {IOSDeviceLog};
|
|
54
56
|
export default IOSDeviceLog;
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import {EventEmitter} from 'events';
|
|
2
|
+
import { LRUCache } from 'lru-cache';
|
|
3
|
+
import { toLogEntry } from './helpers';
|
|
2
4
|
|
|
3
5
|
// We keep only the most recent log entries to avoid out of memory error
|
|
4
6
|
const MAX_LOG_ENTRIES_COUNT = 10000;
|
|
5
7
|
|
|
6
|
-
class
|
|
7
|
-
|
|
8
|
+
// TODO: Rewrite this class to typescript for better generic typing
|
|
9
|
+
|
|
10
|
+
export class IOSLog extends EventEmitter {
|
|
11
|
+
constructor(maxBufferSize = MAX_LOG_ENTRIES_COUNT) {
|
|
8
12
|
super();
|
|
9
|
-
this.
|
|
10
|
-
|
|
11
|
-
this.
|
|
13
|
+
this.maxBufferSize = maxBufferSize;
|
|
14
|
+
/** @type {LRUCache<number, any>} */
|
|
15
|
+
this.logs = new LRUCache({
|
|
16
|
+
max: this.maxBufferSize,
|
|
17
|
+
});
|
|
18
|
+
/** @type {number?} */
|
|
19
|
+
this.logIndexSinceLastRequest = null;
|
|
12
20
|
}
|
|
13
21
|
|
|
14
22
|
/** @returns {Promise<void>} */
|
|
@@ -28,38 +36,81 @@ class IOSLog extends EventEmitter {
|
|
|
28
36
|
throw new Error(`Sub-classes need to implement a 'isCapturing' function`);
|
|
29
37
|
}
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
this.
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param {any} entry
|
|
42
|
+
* @returns {void}
|
|
43
|
+
*/
|
|
44
|
+
broadcast(entry) {
|
|
45
|
+
let recentIndex = -1;
|
|
46
|
+
for (const key of this.logs.rkeys()) {
|
|
47
|
+
recentIndex = key;
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
const serializedEntry = this._serializeEntry(entry);
|
|
51
|
+
this.logs.set(++recentIndex, serializedEntry);
|
|
52
|
+
if (this.listenerCount('output')) {
|
|
53
|
+
this.emit('output', this._deserializeEntry(serializedEntry));
|
|
44
54
|
}
|
|
45
55
|
}
|
|
46
56
|
|
|
57
|
+
/**
|
|
58
|
+
*
|
|
59
|
+
* @returns {import('../commands/types').LogEntry[]}
|
|
60
|
+
*/
|
|
47
61
|
getLogs() {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
/** @type {import('../commands/types').LogEntry[]} */
|
|
63
|
+
const result = [];
|
|
64
|
+
/** @type {number?} */
|
|
65
|
+
let recentLogIndex = null;
|
|
66
|
+
for (const [index, value] of this.logs.entries()) {
|
|
67
|
+
if (this.logIndexSinceLastRequest && index > this.logIndexSinceLastRequest
|
|
68
|
+
|| !this.logIndexSinceLastRequest) {
|
|
69
|
+
recentLogIndex = index;
|
|
70
|
+
result.push(this._deserializeEntry(value));
|
|
52
71
|
}
|
|
53
|
-
this.logIdxSinceLastRequest = this.logs.length;
|
|
54
|
-
return result;
|
|
55
72
|
}
|
|
56
|
-
|
|
73
|
+
if (recentLogIndex !== null) {
|
|
74
|
+
this.logIndexSinceLastRequest = recentLogIndex;
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
57
77
|
}
|
|
58
78
|
|
|
79
|
+
/**
|
|
80
|
+
*
|
|
81
|
+
* @returns {import('../commands/types').LogEntry[]}
|
|
82
|
+
*/
|
|
59
83
|
getAllLogs() {
|
|
60
|
-
|
|
84
|
+
/** @type {import('../commands/types').LogEntry[]} */
|
|
85
|
+
const result = [];
|
|
86
|
+
for (const value of this.logs.values()) {
|
|
87
|
+
result.push(this._deserializeEntry(value));
|
|
88
|
+
}
|
|
89
|
+
return result;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
*
|
|
94
|
+
* @param {any} value
|
|
95
|
+
* @returns {any}
|
|
96
|
+
*/
|
|
97
|
+
_serializeEntry(value) {
|
|
98
|
+
return [value, Date.now()];
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
*
|
|
103
|
+
* @param {any} value
|
|
104
|
+
* @returns {any}
|
|
105
|
+
*/
|
|
106
|
+
_deserializeEntry(value) {
|
|
107
|
+
const [message, timestamp] = value;
|
|
108
|
+
return toLogEntry(message, timestamp);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
_clearEntries() {
|
|
112
|
+
this.logs.clear();
|
|
61
113
|
}
|
|
62
114
|
}
|
|
63
115
|
|
|
64
|
-
export {IOSLog};
|
|
65
116
|
export default IOSLog;
|
|
@@ -1,57 +1,68 @@
|
|
|
1
1
|
import {logger} from 'appium/support';
|
|
2
2
|
import _ from 'lodash';
|
|
3
|
+
import { IOSLog } from './ios-log';
|
|
3
4
|
|
|
4
5
|
const log = logger.getLogger('IOSPerformanceLog');
|
|
5
6
|
const MAX_EVENTS = 5000;
|
|
6
7
|
|
|
7
|
-
class IOSPerformanceLog {
|
|
8
|
+
export class IOSPerformanceLog extends IOSLog {
|
|
8
9
|
constructor(remoteDebugger, maxEvents = MAX_EVENTS) {
|
|
10
|
+
super(maxEvents);
|
|
9
11
|
this.remoteDebugger = remoteDebugger;
|
|
10
12
|
this.maxEvents = parseInt(String(maxEvents), 10);
|
|
11
|
-
|
|
12
|
-
this.timelineEvents = [];
|
|
13
|
+
this._started = false;
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
/**
|
|
17
|
+
* @override
|
|
18
|
+
*/
|
|
15
19
|
async startCapture() {
|
|
16
20
|
log.debug('Starting performance (Timeline) log capture');
|
|
17
|
-
this.
|
|
18
|
-
|
|
21
|
+
this._clearEntries();
|
|
22
|
+
const result = await this.remoteDebugger.startTimeline(this.onTimelineEvent.bind(this));
|
|
23
|
+
this._started = true;
|
|
24
|
+
return result;
|
|
19
25
|
}
|
|
20
26
|
|
|
27
|
+
/**
|
|
28
|
+
* @override
|
|
29
|
+
*/
|
|
21
30
|
async stopCapture() {
|
|
22
31
|
log.debug('Stopping performance (Timeline) log capture');
|
|
23
|
-
|
|
32
|
+
const result = await this.remoteDebugger.stopTimeline();
|
|
33
|
+
this._started = false;
|
|
34
|
+
return result;
|
|
24
35
|
}
|
|
25
36
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
if (this.timelineEvents.length > this.maxEvents) {
|
|
32
|
-
let removedEvent = this.timelineEvents.shift();
|
|
33
|
-
log.warn(
|
|
34
|
-
`Too many Timeline events, removing earliest: ${_.truncate(JSON.stringify(removedEvent))}`,
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
+
/**
|
|
38
|
+
* @override
|
|
39
|
+
*/
|
|
40
|
+
get isCapturing() {
|
|
41
|
+
return this._started;
|
|
37
42
|
}
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
this.timelineEvents = [];
|
|
44
|
+
/**
|
|
45
|
+
* @override
|
|
46
|
+
*/
|
|
47
|
+
_serializeEntry(value) {
|
|
48
|
+
return value;
|
|
49
|
+
}
|
|
46
50
|
|
|
47
|
-
|
|
51
|
+
/**
|
|
52
|
+
* @override
|
|
53
|
+
*/
|
|
54
|
+
_deserializeEntry(value) {
|
|
55
|
+
return value;
|
|
48
56
|
}
|
|
49
57
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
58
|
+
/**
|
|
59
|
+
*
|
|
60
|
+
* @param {import('../commands/types').LogEntry} event
|
|
61
|
+
*/
|
|
62
|
+
onTimelineEvent(event) {
|
|
63
|
+
log.debug(`Received Timeline event: ${_.truncate(JSON.stringify(event))}`);
|
|
64
|
+
this.broadcast(event);
|
|
53
65
|
}
|
|
54
66
|
}
|
|
55
67
|
|
|
56
|
-
export {IOSPerformanceLog};
|
|
57
68
|
export default IOSPerformanceLog;
|