appium-xcuitest-driver 7.21.1 → 7.22.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 +12 -0
- package/build/lib/commands/context.d.ts.map +1 -1
- package/build/lib/commands/context.js +6 -3
- package/build/lib/commands/context.js.map +1 -1
- package/build/lib/commands/log.d.ts.map +1 -1
- package/build/lib/commands/log.js +30 -16
- package/build/lib/commands/log.js.map +1 -1
- package/build/lib/device-log/helpers.d.ts +4 -1
- package/build/lib/device-log/helpers.d.ts.map +1 -1
- package/build/lib/device-log/helpers.js +6 -2
- package/build/lib/device-log/helpers.js.map +1 -1
- package/build/lib/device-log/ios-crash-log.d.ts +0 -4
- package/build/lib/device-log/ios-crash-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-crash-log.js +0 -8
- package/build/lib/device-log/ios-crash-log.js.map +1 -1
- package/build/lib/device-log/ios-device-log.d.ts +16 -10
- package/build/lib/device-log/ios-device-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-device-log.js +9 -24
- package/build/lib/device-log/ios-device-log.js.map +1 -1
- package/build/lib/device-log/ios-log.d.ts +21 -44
- package/build/lib/device-log/ios-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-log.js +16 -77
- package/build/lib/device-log/ios-log.js.map +1 -1
- package/build/lib/device-log/ios-performance-log.d.ts +14 -26
- package/build/lib/device-log/ios-performance-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-performance-log.js +16 -42
- package/build/lib/device-log/ios-performance-log.js.map +1 -1
- package/build/lib/device-log/ios-simulator-log.d.ts +21 -24
- package/build/lib/device-log/ios-simulator-log.d.ts.map +1 -1
- package/build/lib/device-log/ios-simulator-log.js +18 -36
- package/build/lib/device-log/ios-simulator-log.js.map +1 -1
- package/build/lib/device-log/line-consuming-log.d.ts +9 -0
- package/build/lib/device-log/line-consuming-log.d.ts.map +1 -0
- package/build/lib/device-log/line-consuming-log.js +16 -0
- package/build/lib/device-log/line-consuming-log.js.map +1 -0
- package/build/lib/device-log/safari-console-log.d.ts +65 -6
- package/build/lib/device-log/safari-console-log.d.ts.map +1 -1
- package/build/lib/device-log/safari-console-log.js +61 -81
- package/build/lib/device-log/safari-console-log.js.map +1 -1
- package/build/lib/device-log/safari-network-log.d.ts +36 -8
- package/build/lib/device-log/safari-network-log.d.ts.map +1 -1
- package/build/lib/device-log/safari-network-log.js +28 -151
- package/build/lib/device-log/safari-network-log.js.map +1 -1
- package/lib/commands/context.js +6 -3
- package/lib/commands/log.js +35 -16
- package/lib/device-log/helpers.ts +6 -2
- package/lib/device-log/ios-crash-log.js +0 -9
- package/lib/device-log/ios-device-log.ts +52 -0
- package/lib/device-log/ios-log.ts +70 -0
- package/lib/device-log/ios-performance-log.ts +50 -0
- package/lib/device-log/{ios-simulator-log.js → ios-simulator-log.ts} +40 -43
- package/lib/device-log/line-consuming-log.ts +16 -0
- package/lib/device-log/safari-console-log.ts +112 -0
- package/lib/device-log/safari-network-log.ts +80 -0
- package/npm-shrinkwrap.json +69 -24
- package/package.json +2 -2
- package/build/lib/device-log/rotating-log.d.ts +0 -21
- package/build/lib/device-log/rotating-log.d.ts.map +0 -1
- package/build/lib/device-log/rotating-log.js +0 -61
- package/build/lib/device-log/rotating-log.js.map +0 -1
- package/lib/device-log/ios-device-log.js +0 -56
- package/lib/device-log/ios-log.js +0 -116
- package/lib/device-log/ios-performance-log.js +0 -68
- package/lib/device-log/rotating-log.js +0 -65
- package/lib/device-log/safari-console-log.js +0 -96
- package/lib/device-log/safari-network-log.js +0 -193
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import {EventEmitter} from 'events';
|
|
2
|
+
import { LRUCache } from 'lru-cache';
|
|
3
|
+
import type { LogEntry } from '../commands/types';
|
|
4
|
+
import type { AppiumLogger } from '@appium/types';
|
|
5
|
+
import {logger} from 'appium/support';
|
|
6
|
+
|
|
7
|
+
// We keep only the most recent log entries to avoid out of memory error
|
|
8
|
+
const MAX_LOG_ENTRIES_COUNT = 10000;
|
|
9
|
+
|
|
10
|
+
export interface IOSLogOptions {
|
|
11
|
+
maxBufferSize?: number;
|
|
12
|
+
log?: AppiumLogger;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export abstract class IOSLog<
|
|
16
|
+
TRawEntry,
|
|
17
|
+
TSerializedEntry extends object
|
|
18
|
+
> extends EventEmitter {
|
|
19
|
+
private maxBufferSize: number;
|
|
20
|
+
private logs: LRUCache<number, TSerializedEntry>;
|
|
21
|
+
private _log: AppiumLogger;
|
|
22
|
+
|
|
23
|
+
constructor(opts: IOSLogOptions = {}) {
|
|
24
|
+
super();
|
|
25
|
+
this.maxBufferSize = opts.maxBufferSize ?? MAX_LOG_ENTRIES_COUNT;
|
|
26
|
+
this.logs = new LRUCache({
|
|
27
|
+
max: this.maxBufferSize,
|
|
28
|
+
});
|
|
29
|
+
this._log = opts.log ?? logger.getLogger(this.constructor.name);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
abstract startCapture(): Promise<void>;
|
|
33
|
+
abstract stopCapture(): Promise<void>;
|
|
34
|
+
abstract get isCapturing(): boolean;
|
|
35
|
+
|
|
36
|
+
get log(): AppiumLogger {
|
|
37
|
+
return this._log;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
getLogs(): LogEntry[] {
|
|
41
|
+
const result: LogEntry[] = [];
|
|
42
|
+
for (const value of this.logs.rvalues()) {
|
|
43
|
+
result.push(this._deserializeEntry(value as TSerializedEntry));
|
|
44
|
+
}
|
|
45
|
+
this._clearEntries();
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
protected abstract _serializeEntry(value: TRawEntry): TSerializedEntry;
|
|
50
|
+
protected abstract _deserializeEntry(value: TSerializedEntry): LogEntry;
|
|
51
|
+
|
|
52
|
+
protected _clearEntries() {
|
|
53
|
+
this.logs.clear();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
protected broadcast(entry: TRawEntry): void {
|
|
57
|
+
let recentIndex = -1;
|
|
58
|
+
for (const key of this.logs.keys()) {
|
|
59
|
+
recentIndex = key;
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
const serializedEntry = this._serializeEntry(entry);
|
|
63
|
+
this.logs.set(++recentIndex, serializedEntry);
|
|
64
|
+
if (this.listenerCount('output')) {
|
|
65
|
+
this.emit('output', this._deserializeEntry(serializedEntry));
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export default IOSLog;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import type { AppiumLogger } from '@appium/types';
|
|
3
|
+
import { MAX_JSON_LOG_LENGTH, MAX_BUFFERED_EVENTS_COUNT } from './helpers';
|
|
4
|
+
import { LineConsumingLog } from './line-consuming-log';
|
|
5
|
+
|
|
6
|
+
type PerformanceLogEntry = object;
|
|
7
|
+
export interface IOSPerformanceLogOptions {
|
|
8
|
+
remoteDebugger: any;
|
|
9
|
+
maxEvents?: number;
|
|
10
|
+
log: AppiumLogger;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class IOSPerformanceLog extends LineConsumingLog {
|
|
14
|
+
private readonly remoteDebugger: any;
|
|
15
|
+
private _started: boolean;
|
|
16
|
+
|
|
17
|
+
constructor(opts: IOSPerformanceLogOptions) {
|
|
18
|
+
super({
|
|
19
|
+
maxBufferSize: opts.maxEvents ?? MAX_BUFFERED_EVENTS_COUNT,
|
|
20
|
+
log: opts.log,
|
|
21
|
+
});
|
|
22
|
+
this.remoteDebugger = opts.remoteDebugger;
|
|
23
|
+
this._started = false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
override async startCapture(): Promise<void> {
|
|
27
|
+
this.log.debug('Starting performance (Timeline) log capture');
|
|
28
|
+
this._clearEntries();
|
|
29
|
+
await this.remoteDebugger.startTimeline(this.onTimelineEvent.bind(this));
|
|
30
|
+
this._started = true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
override async stopCapture(): Promise<void> {
|
|
34
|
+
this.log.debug('Stopping performance (Timeline) log capture');
|
|
35
|
+
await this.remoteDebugger.stopTimeline();
|
|
36
|
+
this._started = false;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
override get isCapturing(): boolean {
|
|
40
|
+
return this._started;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private onTimelineEvent(event: PerformanceLogEntry): void {
|
|
44
|
+
const serializedEntry = JSON.stringify(event);
|
|
45
|
+
this.broadcast(serializedEntry);
|
|
46
|
+
this.log.debug(`Received Timeline event: ${_.truncate(serializedEntry, {length: MAX_JSON_LOG_LENGTH})}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export default IOSPerformanceLog;
|
|
@@ -1,27 +1,35 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import {SubProcess, exec} from 'teen_process';
|
|
3
|
+
import { LineConsumingLog } from './line-consuming-log';
|
|
4
|
+
import type { Simulator } from 'appium-ios-simulator';
|
|
5
|
+
import type { AppiumLogger } from '@appium/types';
|
|
5
6
|
|
|
6
|
-
const log = logger.getLogger('IOSSimulatorLog');
|
|
7
7
|
const EXECVP_ERROR_PATTERN = /execvp\(\)/;
|
|
8
8
|
|
|
9
9
|
const START_TIMEOUT = 10000;
|
|
10
10
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
export interface IOSSimulatorLogOptions {
|
|
12
|
+
sim: Simulator;
|
|
13
|
+
showLogs?: boolean;
|
|
14
|
+
iosSimulatorLogsPredicate?: string;
|
|
15
|
+
log: AppiumLogger;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export class IOSSimulatorLog extends LineConsumingLog {
|
|
19
|
+
private readonly sim: Simulator;
|
|
20
|
+
private readonly showLogs: boolean;
|
|
21
|
+
private readonly predicate?: string;
|
|
22
|
+
private proc: SubProcess | null;
|
|
23
|
+
|
|
24
|
+
constructor(opts: IOSSimulatorLogOptions) {
|
|
25
|
+
super({log: opts.log});
|
|
26
|
+
this.sim = opts.sim;
|
|
27
|
+
this.showLogs = !!opts.showLogs;
|
|
28
|
+
this.predicate = opts.iosSimulatorLogsPredicate;
|
|
18
29
|
this.proc = null;
|
|
19
30
|
}
|
|
20
31
|
|
|
21
|
-
|
|
22
|
-
* @override
|
|
23
|
-
*/
|
|
24
|
-
async startCapture() {
|
|
32
|
+
override async startCapture(): Promise<void> {
|
|
25
33
|
if (_.isUndefined(this.sim.udid)) {
|
|
26
34
|
throw new Error(`Log capture requires a sim udid`);
|
|
27
35
|
}
|
|
@@ -33,7 +41,7 @@ export class IOSSimulatorLog extends IOSLog {
|
|
|
33
41
|
if (this.predicate) {
|
|
34
42
|
spawnArgs.push('--predicate', this.predicate);
|
|
35
43
|
}
|
|
36
|
-
log.debug(
|
|
44
|
+
this.log.debug(
|
|
37
45
|
`Starting log capture for iOS Simulator with udid '${this.sim.udid}' ` + `using simctl`,
|
|
38
46
|
);
|
|
39
47
|
try {
|
|
@@ -48,10 +56,7 @@ export class IOSSimulatorLog extends IOSLog {
|
|
|
48
56
|
}
|
|
49
57
|
}
|
|
50
58
|
|
|
51
|
-
|
|
52
|
-
* @override
|
|
53
|
-
*/
|
|
54
|
-
async stopCapture() {
|
|
59
|
+
override async stopCapture(): Promise<void> {
|
|
55
60
|
if (!this.proc) {
|
|
56
61
|
return;
|
|
57
62
|
}
|
|
@@ -59,59 +64,51 @@ export class IOSSimulatorLog extends IOSLog {
|
|
|
59
64
|
this.proc = null;
|
|
60
65
|
}
|
|
61
66
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
*/
|
|
65
|
-
get isCapturing() {
|
|
66
|
-
return this.proc && this.proc.isRunning;
|
|
67
|
+
override get isCapturing(): boolean {
|
|
68
|
+
return Boolean(this.proc && this.proc.isRunning);
|
|
67
69
|
}
|
|
68
70
|
|
|
69
|
-
|
|
70
|
-
* @param {string} logRow
|
|
71
|
-
* @param {string} [prefix='']
|
|
72
|
-
*/
|
|
73
|
-
onOutput(logRow, prefix = '') {
|
|
71
|
+
private onOutput(logRow: string, prefix: string = ''): void {
|
|
74
72
|
this.broadcast(logRow);
|
|
75
73
|
if (this.showLogs) {
|
|
76
74
|
const space = prefix.length > 0 ? ' ' : '';
|
|
77
|
-
log.info(`[IOS_SYSLOG_ROW${space}${prefix}] ${logRow}`);
|
|
75
|
+
this.log.info(`[IOS_SYSLOG_ROW${space}${prefix}] ${logRow}`);
|
|
78
76
|
}
|
|
79
77
|
}
|
|
80
78
|
|
|
81
|
-
async killLogSubProcess() {
|
|
82
|
-
if (!this.proc
|
|
79
|
+
private async killLogSubProcess(): Promise<void> {
|
|
80
|
+
if (!this.proc?.isRunning) {
|
|
83
81
|
return;
|
|
84
82
|
}
|
|
85
|
-
|
|
83
|
+
|
|
84
|
+
this.log.debug('Stopping iOS log capture');
|
|
86
85
|
try {
|
|
87
86
|
await this.proc.stop('SIGTERM', 1000);
|
|
88
87
|
} catch (e) {
|
|
89
88
|
if (!this.proc.isRunning) {
|
|
90
89
|
return;
|
|
91
90
|
}
|
|
92
|
-
log.warn('Cannot stop log capture process. Sending SIGKILL');
|
|
91
|
+
this.log.warn('Cannot stop log capture process. Sending SIGKILL');
|
|
93
92
|
await this.proc.stop('SIGKILL');
|
|
94
93
|
}
|
|
95
94
|
}
|
|
96
95
|
|
|
97
|
-
async finishStartingLogCapture() {
|
|
96
|
+
private async finishStartingLogCapture(): Promise<void> {
|
|
98
97
|
if (!this.proc) {
|
|
99
|
-
log.
|
|
98
|
+
throw this.log.errorWithException('Could not capture simulator log');
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
for (const streamName of ['stdout', 'stderr']) {
|
|
103
|
-
this.proc.on(`
|
|
104
|
-
|
|
105
|
-
this.onOutput(line, ...(streamName === 'stderr' ? ['STDERR'] : []));
|
|
106
|
-
}
|
|
102
|
+
this.proc.on(`line-${streamName}`, (line: string) => {
|
|
103
|
+
this.onOutput(line, ...(streamName === 'stderr' ? ['STDERR'] : []));
|
|
107
104
|
});
|
|
108
105
|
}
|
|
109
106
|
|
|
110
|
-
const startDetector = (
|
|
107
|
+
const startDetector = (stdout: string, stderr: string) => {
|
|
111
108
|
if (EXECVP_ERROR_PATTERN.test(stderr)) {
|
|
112
109
|
throw new Error('iOS log capture process failed to start');
|
|
113
110
|
}
|
|
114
|
-
return stdout || stderr;
|
|
111
|
+
return Boolean(stdout || stderr);
|
|
115
112
|
};
|
|
116
113
|
await this.proc.start(startDetector, START_TIMEOUT);
|
|
117
114
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {IOSLog} from './ios-log';
|
|
2
|
+
import { toLogEntry } from './helpers';
|
|
3
|
+
import type { LogEntry } from '../commands/types';
|
|
4
|
+
|
|
5
|
+
type TSerializedEntry = [string, number];
|
|
6
|
+
|
|
7
|
+
export abstract class LineConsumingLog extends IOSLog<string, TSerializedEntry> {
|
|
8
|
+
protected override _serializeEntry(value: string): TSerializedEntry {
|
|
9
|
+
return [value, Date.now()];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
protected override _deserializeEntry(value: TSerializedEntry): LogEntry {
|
|
13
|
+
const [message, timestamp] = value;
|
|
14
|
+
return toLogEntry(message, timestamp);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import type { AppiumLogger } from '@appium/types';
|
|
3
|
+
import {
|
|
4
|
+
toLogEntry,
|
|
5
|
+
DEFAULT_LOG_LEVEL,
|
|
6
|
+
MAX_JSON_LOG_LENGTH,
|
|
7
|
+
MAX_BUFFERED_EVENTS_COUNT
|
|
8
|
+
} from './helpers';
|
|
9
|
+
import IOSLog from './ios-log';
|
|
10
|
+
import type { LogEntry } from '../commands/types';
|
|
11
|
+
|
|
12
|
+
const LOG_LEVELS_MAP = {
|
|
13
|
+
error: 'SEVERE',
|
|
14
|
+
warning: 'WARNING',
|
|
15
|
+
log: 'FINE',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export interface SafariConsoleLogOptions {
|
|
19
|
+
showLogs: boolean;
|
|
20
|
+
log: AppiumLogger;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface SafariConsoleStacktraceEntry {
|
|
24
|
+
functionName: string;
|
|
25
|
+
url: string;
|
|
26
|
+
scriptId: number;
|
|
27
|
+
lineNumber: number;
|
|
28
|
+
columnNumber: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface SafariConsoleEntry {
|
|
32
|
+
source: string;
|
|
33
|
+
level: string;
|
|
34
|
+
text: string;
|
|
35
|
+
type: string;
|
|
36
|
+
line: number;
|
|
37
|
+
column: number;
|
|
38
|
+
url?: string;
|
|
39
|
+
repeatCount: number;
|
|
40
|
+
stackTrace: SafariConsoleStacktraceEntry[];
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type TSerializedEntry = [SafariConsoleEntry, number];
|
|
44
|
+
|
|
45
|
+
export class SafariConsoleLog extends IOSLog<SafariConsoleEntry, TSerializedEntry> {
|
|
46
|
+
private readonly _showLogs: boolean;
|
|
47
|
+
|
|
48
|
+
constructor(opts: SafariConsoleLogOptions) {
|
|
49
|
+
super({
|
|
50
|
+
log: opts.log,
|
|
51
|
+
maxBufferSize: MAX_BUFFERED_EVENTS_COUNT,
|
|
52
|
+
});
|
|
53
|
+
this._showLogs = opts.showLogs;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
override async startCapture(): Promise<void> {}
|
|
57
|
+
override async stopCapture(): Promise<void> {}
|
|
58
|
+
override get isCapturing(): boolean {
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
* @param err
|
|
65
|
+
* @param entry The output will be like:
|
|
66
|
+
* {
|
|
67
|
+
* "source": "javascript",
|
|
68
|
+
* "level":"error",
|
|
69
|
+
* "text":"ReferenceError: Can't find variable: s_account",
|
|
70
|
+
* "type":"log",
|
|
71
|
+
* "line":2,
|
|
72
|
+
* "column":21,
|
|
73
|
+
* "url":"https://assets.adobedtm.com/b46e318d845250834eda10c5a20827c045a4d76f/scripts/satellite-57866f8b64746d53a8000104-staging.js",
|
|
74
|
+
* "repeatCount":1,
|
|
75
|
+
* "stackTrace":[{
|
|
76
|
+
* "functionName":"global code",
|
|
77
|
+
* "url":"https://assets.adobedtm.com/b46e318d845250834eda10c5a20827c045a4d76f/scripts/satellite-57866f8b64746d53a8000104-staging.js",
|
|
78
|
+
* "scriptId":"6",
|
|
79
|
+
* "lineNumber":2,
|
|
80
|
+
* "columnNumber":21
|
|
81
|
+
* }]
|
|
82
|
+
* }
|
|
83
|
+
*
|
|
84
|
+
* we need, at least, `level` (in accordance with Java levels
|
|
85
|
+
* (https://docs.oracle.com/javase/7/docs/api/java/util/logging/Level.html)),
|
|
86
|
+
* `timestamp`, and `message` to satisfy the java client. In order to
|
|
87
|
+
* provide all the information to the client, `message` is the full
|
|
88
|
+
* object, stringified.
|
|
89
|
+
*
|
|
90
|
+
*/
|
|
91
|
+
onConsoleLogEvent(err: object | null, entry: SafariConsoleEntry): void {
|
|
92
|
+
this.broadcast(entry);
|
|
93
|
+
if (this._showLogs) {
|
|
94
|
+
this.log.info(`[SafariConsole] ${_.truncate(JSON.stringify(entry), {length: MAX_JSON_LOG_LENGTH})}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
protected override _serializeEntry(value: SafariConsoleEntry): TSerializedEntry {
|
|
99
|
+
return [value, Date.now()];
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected override _deserializeEntry(value: TSerializedEntry): LogEntry {
|
|
103
|
+
const [entry, timestamp] = value;
|
|
104
|
+
return toLogEntry(JSON.stringify(entry), timestamp, mapLogLevel(entry.level));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function mapLogLevel(originalLevel: string): string {
|
|
109
|
+
return LOG_LEVELS_MAP[originalLevel] ?? DEFAULT_LOG_LEVEL;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export default SafariConsoleLog;
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import _ from 'lodash';
|
|
2
|
+
import { LineConsumingLog } from './line-consuming-log';
|
|
3
|
+
import { MAX_JSON_LOG_LENGTH, MAX_BUFFERED_EVENTS_COUNT } from './helpers';
|
|
4
|
+
import type { AppiumLogger } from '@appium/types';
|
|
5
|
+
|
|
6
|
+
const EVENTS_TO_LOG = [
|
|
7
|
+
'Network.loadingFinished',
|
|
8
|
+
'Network.loadingFailed',
|
|
9
|
+
];
|
|
10
|
+
const MONITORED_EVENTS = [
|
|
11
|
+
'Network.requestWillBeSent',
|
|
12
|
+
'Network.responseReceived',
|
|
13
|
+
...EVENTS_TO_LOG,
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
export interface SafariConsoleLogOptions {
|
|
17
|
+
showLogs: boolean;
|
|
18
|
+
log: AppiumLogger;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SafariNetworkResponseTiming {
|
|
22
|
+
responseStart: number;
|
|
23
|
+
receiveHeadersEnd: number;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface SafariNetworkResponse {
|
|
27
|
+
url: string;
|
|
28
|
+
status: number;
|
|
29
|
+
timing: SafariNetworkResponseTiming;
|
|
30
|
+
source: string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface SafariNetworkLogEntryMetrics {
|
|
34
|
+
responseBodyBytesReceived: number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface SafariNetworkLogEntry {
|
|
38
|
+
requestId: string;
|
|
39
|
+
response?: SafariNetworkResponse;
|
|
40
|
+
type?: string;
|
|
41
|
+
initiator?: string;
|
|
42
|
+
// Safari has a `metrics` object on it's `Network.loadingFinished` event
|
|
43
|
+
metrics?: SafariNetworkLogEntryMetrics;
|
|
44
|
+
errorText?: string;
|
|
45
|
+
// When a network call is cancelled, Safari returns `cancelled` as error text
|
|
46
|
+
// but has a boolean `canceled`.
|
|
47
|
+
canceled?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export class SafariNetworkLog extends LineConsumingLog {
|
|
51
|
+
private readonly _showLogs: boolean;
|
|
52
|
+
|
|
53
|
+
constructor(opts: SafariConsoleLogOptions) {
|
|
54
|
+
super({
|
|
55
|
+
log: opts.log,
|
|
56
|
+
maxBufferSize: MAX_BUFFERED_EVENTS_COUNT,
|
|
57
|
+
});
|
|
58
|
+
this._showLogs = opts.showLogs;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
override async startCapture(): Promise<void> {}
|
|
62
|
+
override async stopCapture(): Promise<void> {}
|
|
63
|
+
override get isCapturing(): boolean {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
onNetworkEvent(method: string, entry: SafariNetworkLogEntry): void {
|
|
68
|
+
if (!MONITORED_EVENTS.includes(method)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const serializedEntry = JSON.stringify(entry);
|
|
73
|
+
this.broadcast(serializedEntry);
|
|
74
|
+
if (this._showLogs && EVENTS_TO_LOG.includes(method)) {
|
|
75
|
+
this.log.info(`[SafariNetwork] ${_.truncate(serializedEntry, {length: MAX_JSON_LOG_LENGTH})}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export default SafariNetworkLog;
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium-xcuitest-driver",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.22.0",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "appium-xcuitest-driver",
|
|
9
|
-
"version": "7.
|
|
9
|
+
"version": "7.22.0",
|
|
10
10
|
"license": "Apache-2.0",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@colors/colors": "^1.6.0",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"portscanner": "^2.2.0",
|
|
31
31
|
"semver": "^7.5.4",
|
|
32
32
|
"source-map-support": "^0.x",
|
|
33
|
-
"teen_process": "^2.
|
|
33
|
+
"teen_process": "^2.2.0",
|
|
34
34
|
"ws": "^8.13.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
@@ -113,6 +113,17 @@
|
|
|
113
113
|
"spdy": "4.0.2"
|
|
114
114
|
}
|
|
115
115
|
},
|
|
116
|
+
"node_modules/@appium/base-driver/node_modules/type-fest": {
|
|
117
|
+
"version": "4.20.1",
|
|
118
|
+
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.1.tgz",
|
|
119
|
+
"integrity": "sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==",
|
|
120
|
+
"engines": {
|
|
121
|
+
"node": ">=16"
|
|
122
|
+
},
|
|
123
|
+
"funding": {
|
|
124
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
116
127
|
"node_modules/@appium/docutils": {
|
|
117
128
|
"version": "1.0.17",
|
|
118
129
|
"resolved": "https://registry.npmjs.org/@appium/docutils/-/docutils-1.0.17.tgz",
|
|
@@ -162,6 +173,29 @@
|
|
|
162
173
|
"npm": ">=8"
|
|
163
174
|
}
|
|
164
175
|
},
|
|
176
|
+
"node_modules/@appium/docutils/node_modules/type-fest": {
|
|
177
|
+
"version": "4.20.1",
|
|
178
|
+
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.1.tgz",
|
|
179
|
+
"integrity": "sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==",
|
|
180
|
+
"engines": {
|
|
181
|
+
"node": ">=16"
|
|
182
|
+
},
|
|
183
|
+
"funding": {
|
|
184
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
"node_modules/@appium/docutils/node_modules/typescript": {
|
|
188
|
+
"version": "5.5.2",
|
|
189
|
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz",
|
|
190
|
+
"integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==",
|
|
191
|
+
"bin": {
|
|
192
|
+
"tsc": "bin/tsc",
|
|
193
|
+
"tsserver": "bin/tsserver"
|
|
194
|
+
},
|
|
195
|
+
"engines": {
|
|
196
|
+
"node": ">=14.17"
|
|
197
|
+
}
|
|
198
|
+
},
|
|
165
199
|
"node_modules/@appium/logger": {
|
|
166
200
|
"version": "1.5.0",
|
|
167
201
|
"resolved": "https://registry.npmjs.org/@appium/logger/-/logger-1.5.0.tgz",
|
|
@@ -284,6 +318,17 @@
|
|
|
284
318
|
"npm": ">=8"
|
|
285
319
|
}
|
|
286
320
|
},
|
|
321
|
+
"node_modules/@appium/support/node_modules/type-fest": {
|
|
322
|
+
"version": "4.20.1",
|
|
323
|
+
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.1.tgz",
|
|
324
|
+
"integrity": "sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==",
|
|
325
|
+
"engines": {
|
|
326
|
+
"node": ">=16"
|
|
327
|
+
},
|
|
328
|
+
"funding": {
|
|
329
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
330
|
+
}
|
|
331
|
+
},
|
|
287
332
|
"node_modules/@appium/tsconfig": {
|
|
288
333
|
"version": "0.3.3",
|
|
289
334
|
"resolved": "https://registry.npmjs.org/@appium/tsconfig/-/tsconfig-0.3.3.tgz",
|
|
@@ -313,6 +358,17 @@
|
|
|
313
358
|
"npm": ">=8"
|
|
314
359
|
}
|
|
315
360
|
},
|
|
361
|
+
"node_modules/@appium/types/node_modules/type-fest": {
|
|
362
|
+
"version": "4.20.1",
|
|
363
|
+
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.1.tgz",
|
|
364
|
+
"integrity": "sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==",
|
|
365
|
+
"engines": {
|
|
366
|
+
"node": ">=16"
|
|
367
|
+
},
|
|
368
|
+
"funding": {
|
|
369
|
+
"url": "https://github.com/sponsors/sindresorhus"
|
|
370
|
+
}
|
|
371
|
+
},
|
|
316
372
|
"node_modules/@babel/code-frame": {
|
|
317
373
|
"version": "7.24.7",
|
|
318
374
|
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz",
|
|
@@ -923,9 +979,9 @@
|
|
|
923
979
|
}
|
|
924
980
|
},
|
|
925
981
|
"node_modules/appium-webdriveragent": {
|
|
926
|
-
"version": "8.7.
|
|
927
|
-
"resolved": "https://registry.npmjs.org/appium-webdriveragent/-/appium-webdriveragent-8.7.
|
|
928
|
-
"integrity": "sha512-
|
|
982
|
+
"version": "8.7.6",
|
|
983
|
+
"resolved": "https://registry.npmjs.org/appium-webdriveragent/-/appium-webdriveragent-8.7.6.tgz",
|
|
984
|
+
"integrity": "sha512-TrpMaiDlrtHISpF3J1At/a0Bsd8stR4B0YYXYqe8pfmsG9F9n/c2X+o44vnm6+Kt7imcxo9fhpIbn76/jI3Tpg==",
|
|
929
985
|
"dependencies": {
|
|
930
986
|
"@appium/base-driver": "^9.0.0",
|
|
931
987
|
"@appium/strongbox": "^0.x",
|
|
@@ -938,7 +994,7 @@
|
|
|
938
994
|
"bluebird": "^3.5.5",
|
|
939
995
|
"lodash": "^4.17.11",
|
|
940
996
|
"source-map-support": "^0.x",
|
|
941
|
-
"teen_process": "^2.
|
|
997
|
+
"teen_process": "^2.2.0"
|
|
942
998
|
},
|
|
943
999
|
"engines": {
|
|
944
1000
|
"node": ">=14",
|
|
@@ -3742,9 +3798,9 @@
|
|
|
3742
3798
|
}
|
|
3743
3799
|
},
|
|
3744
3800
|
"node_modules/teen_process": {
|
|
3745
|
-
"version": "2.
|
|
3746
|
-
"resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.
|
|
3747
|
-
"integrity": "sha512-
|
|
3801
|
+
"version": "2.2.0",
|
|
3802
|
+
"resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.2.0.tgz",
|
|
3803
|
+
"integrity": "sha512-YYHdMnRGAMXrP+KmUH3/WBelsR+OZUfdqCZEXHfhN/2Bn2eTVP11NyB4FeMOjlmtZB/Y5CiZnRKQqu2lJzzlVw==",
|
|
3748
3804
|
"dependencies": {
|
|
3749
3805
|
"bluebird": "^3.7.2",
|
|
3750
3806
|
"lodash": "^4.17.21",
|
|
@@ -3790,17 +3846,6 @@
|
|
|
3790
3846
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz",
|
|
3791
3847
|
"integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ=="
|
|
3792
3848
|
},
|
|
3793
|
-
"node_modules/type-fest": {
|
|
3794
|
-
"version": "4.20.1",
|
|
3795
|
-
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.20.1.tgz",
|
|
3796
|
-
"integrity": "sha512-R6wDsVsoS9xYOpy8vgeBlqpdOyzJ12HNfQhC/aAKWM3YoCV9TtunJzh/QpkMgeDhkoynDcw5f1y+qF9yc/HHyg==",
|
|
3797
|
-
"engines": {
|
|
3798
|
-
"node": ">=16"
|
|
3799
|
-
},
|
|
3800
|
-
"funding": {
|
|
3801
|
-
"url": "https://github.com/sponsors/sindresorhus"
|
|
3802
|
-
}
|
|
3803
|
-
},
|
|
3804
3849
|
"node_modules/type-is": {
|
|
3805
3850
|
"version": "1.6.18",
|
|
3806
3851
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
|
@@ -3814,9 +3859,9 @@
|
|
|
3814
3859
|
}
|
|
3815
3860
|
},
|
|
3816
3861
|
"node_modules/typescript": {
|
|
3817
|
-
"version": "5.5.
|
|
3818
|
-
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.
|
|
3819
|
-
"integrity": "sha512
|
|
3862
|
+
"version": "5.5.3",
|
|
3863
|
+
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz",
|
|
3864
|
+
"integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==",
|
|
3820
3865
|
"bin": {
|
|
3821
3866
|
"tsc": "bin/tsc",
|
|
3822
3867
|
"tsserver": "bin/tsserver"
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"xcuitest",
|
|
9
9
|
"xctest"
|
|
10
10
|
],
|
|
11
|
-
"version": "7.
|
|
11
|
+
"version": "7.22.0",
|
|
12
12
|
"author": "Appium Contributors",
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"repository": {
|
|
@@ -97,7 +97,7 @@
|
|
|
97
97
|
"portscanner": "^2.2.0",
|
|
98
98
|
"semver": "^7.5.4",
|
|
99
99
|
"source-map-support": "^0.x",
|
|
100
|
-
"teen_process": "^2.
|
|
100
|
+
"teen_process": "^2.2.0",
|
|
101
101
|
"ws": "^8.13.0"
|
|
102
102
|
},
|
|
103
103
|
"scripts": {
|