appium-xcuitest-driver 7.21.0 → 7.21.2

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/build/lib/commands/context.d.ts.map +1 -1
  3. package/build/lib/commands/context.js +4 -1
  4. package/build/lib/commands/context.js.map +1 -1
  5. package/build/lib/commands/log.d.ts +0 -8
  6. package/build/lib/commands/log.d.ts.map +1 -1
  7. package/build/lib/commands/log.js +7 -15
  8. package/build/lib/commands/log.js.map +1 -1
  9. package/build/lib/commands/types.d.ts +5 -0
  10. package/build/lib/commands/types.d.ts.map +1 -1
  11. package/build/lib/device-log/helpers.d.ts +3 -0
  12. package/build/lib/device-log/helpers.d.ts.map +1 -0
  13. package/build/lib/device-log/helpers.js +11 -0
  14. package/build/lib/device-log/helpers.js.map +1 -0
  15. package/build/lib/device-log/ios-crash-log.d.ts +6 -17
  16. package/build/lib/device-log/ios-crash-log.d.ts.map +1 -1
  17. package/build/lib/device-log/ios-crash-log.js +4 -10
  18. package/build/lib/device-log/ios-crash-log.js.map +1 -1
  19. package/build/lib/device-log/ios-device-log.d.ts +17 -8
  20. package/build/lib/device-log/ios-device-log.d.ts.map +1 -1
  21. package/build/lib/device-log/ios-device-log.js +9 -21
  22. package/build/lib/device-log/ios-device-log.js.map +1 -1
  23. package/build/lib/device-log/ios-log.d.ts +24 -16
  24. package/build/lib/device-log/ios-log.d.ts.map +1 -1
  25. package/build/lib/device-log/ios-log.js +40 -38
  26. package/build/lib/device-log/ios-log.js.map +1 -1
  27. package/build/lib/device-log/ios-performance-log.d.ts +19 -10
  28. package/build/lib/device-log/ios-performance-log.d.ts.map +1 -1
  29. package/build/lib/device-log/ios-performance-log.js +28 -30
  30. package/build/lib/device-log/ios-performance-log.js.map +1 -1
  31. package/build/lib/device-log/ios-simulator-log.d.ts +22 -18
  32. package/build/lib/device-log/ios-simulator-log.d.ts.map +1 -1
  33. package/build/lib/device-log/ios-simulator-log.js +39 -61
  34. package/build/lib/device-log/ios-simulator-log.js.map +1 -1
  35. package/build/lib/device-log/line-consuming-log.d.ts +9 -0
  36. package/build/lib/device-log/line-consuming-log.d.ts.map +1 -0
  37. package/build/lib/device-log/line-consuming-log.js +16 -0
  38. package/build/lib/device-log/line-consuming-log.js.map +1 -0
  39. package/lib/commands/context.js +4 -1
  40. package/lib/commands/log.js +9 -16
  41. package/lib/commands/types.ts +6 -0
  42. package/lib/device-log/helpers.ts +9 -0
  43. package/lib/device-log/ios-crash-log.js +4 -11
  44. package/lib/device-log/ios-device-log.ts +52 -0
  45. package/lib/device-log/ios-log.ts +87 -0
  46. package/lib/device-log/ios-performance-log.ts +61 -0
  47. package/lib/device-log/ios-simulator-log.ts +119 -0
  48. package/lib/device-log/line-consuming-log.ts +16 -0
  49. package/npm-shrinkwrap.json +52 -27
  50. package/package.json +2 -2
  51. package/lib/device-log/ios-device-log.js +0 -54
  52. package/lib/device-log/ios-log.js +0 -65
  53. package/lib/device-log/ios-performance-log.js +0 -57
  54. package/lib/device-log/ios-simulator-log.js +0 -124
@@ -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<LogRecord[]>}
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<LogRecord[]>}
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<LogRecord[]>}
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 {LogRecord[]} */ ((
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)));
@@ -0,0 +1,52 @@
1
+ import {services} from 'appium-ios-device';
2
+ import { LineConsumingLog } from './line-consuming-log';
3
+ import type { AppiumLogger } from '@appium/types';
4
+
5
+ export interface IOSDeviceLogOpts {
6
+ udid: string;
7
+ showLogs?: boolean;
8
+ log?: AppiumLogger;
9
+ }
10
+
11
+ export class IOSDeviceLog extends LineConsumingLog {
12
+ private udid: string;
13
+ private showLogs: boolean;
14
+ private service: any | null;
15
+
16
+ constructor(opts: IOSDeviceLogOpts) {
17
+ super({log: opts.log});
18
+ this.udid = opts.udid;
19
+ this.showLogs = !!opts.showLogs;
20
+ this.service = null;
21
+ }
22
+
23
+ override async startCapture(): Promise<void> {
24
+ if (this.service) {
25
+ return;
26
+ }
27
+ this.service = await services.startSyslogService(this.udid);
28
+ this.service.start(this.onLog.bind(this));
29
+ }
30
+
31
+ override get isCapturing(): boolean {
32
+ return !!this.service;
33
+ }
34
+
35
+ // eslint-disable-next-line require-await
36
+ override async stopCapture(): Promise<void> {
37
+ if (!this.service) {
38
+ return;
39
+ }
40
+ this.service.close();
41
+ this.service = null;
42
+ }
43
+
44
+ private onLog(logLine: string): void {
45
+ this.broadcast(logLine);
46
+ if (this.showLogs) {
47
+ this.log.info(`[IOS_SYSLOG_ROW] ${logLine}`);
48
+ }
49
+ }
50
+ }
51
+
52
+ export default IOSDeviceLog;
@@ -0,0 +1,87 @@
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 logIndexSinceLastRequest: number | null;
22
+ private _log: AppiumLogger;
23
+
24
+ constructor(opts: IOSLogOptions = {}) {
25
+ super();
26
+ this.maxBufferSize = opts.maxBufferSize ?? MAX_LOG_ENTRIES_COUNT;
27
+ this.logs = new LRUCache({
28
+ max: this.maxBufferSize,
29
+ });
30
+ this.logIndexSinceLastRequest = null;
31
+ this._log = opts.log ?? logger.getLogger(this.constructor.name);
32
+ }
33
+
34
+ abstract startCapture(): Promise<void>;
35
+ abstract stopCapture(): Promise<void>;
36
+ abstract get isCapturing(): boolean;
37
+
38
+ get log(): AppiumLogger {
39
+ return this._log;
40
+ }
41
+
42
+ broadcast(entry: TRawEntry): void {
43
+ let recentIndex = -1;
44
+ for (const key of this.logs.rkeys()) {
45
+ recentIndex = key;
46
+ break;
47
+ }
48
+ const serializedEntry = this._serializeEntry(entry);
49
+ this.logs.set(++recentIndex, serializedEntry);
50
+ if (this.listenerCount('output')) {
51
+ this.emit('output', this._deserializeEntry(serializedEntry));
52
+ }
53
+ }
54
+
55
+ getLogs(): LogEntry[] {
56
+ const result: LogEntry[] = [];
57
+ let recentLogIndex: number | null = null;
58
+ for (const [index, value] of this.logs.entries()) {
59
+ if (this.logIndexSinceLastRequest && index > this.logIndexSinceLastRequest
60
+ || !this.logIndexSinceLastRequest) {
61
+ recentLogIndex = index;
62
+ result.push(this._deserializeEntry(value));
63
+ }
64
+ }
65
+ if (recentLogIndex !== null) {
66
+ this.logIndexSinceLastRequest = recentLogIndex;
67
+ }
68
+ return result;
69
+ }
70
+
71
+ getAllLogs(): LogEntry[] {
72
+ const result: LogEntry[] = [];
73
+ for (const value of this.logs.values()) {
74
+ result.push(this._deserializeEntry(value));
75
+ }
76
+ return result;
77
+ }
78
+
79
+ protected abstract _serializeEntry(value: TRawEntry): TSerializedEntry;
80
+ protected abstract _deserializeEntry(value: TSerializedEntry): LogEntry;
81
+
82
+ protected _clearEntries() {
83
+ this.logs.clear();
84
+ }
85
+ }
86
+
87
+ export default IOSLog;
@@ -0,0 +1,61 @@
1
+ import _ from 'lodash';
2
+ import { IOSLog } from './ios-log';
3
+ import type { LogEntry } from '../commands/types';
4
+ import type { AppiumLogger } from '@appium/types';
5
+
6
+ const MAX_EVENTS = 5000;
7
+
8
+ type PerformanceLogEntry = object;
9
+ export interface IOSPerformanceLogOptions {
10
+ remoteDebugger: any;
11
+ maxEvents?: number;
12
+ log?: AppiumLogger;
13
+ }
14
+
15
+ export class IOSPerformanceLog extends IOSLog<PerformanceLogEntry, PerformanceLogEntry> {
16
+ private remoteDebugger: any;
17
+ private _started: boolean;
18
+
19
+ constructor(opts: IOSPerformanceLogOptions) {
20
+ super({
21
+ maxBufferSize: opts.maxEvents ?? MAX_EVENTS,
22
+ log: opts.log,
23
+ });
24
+ this.remoteDebugger = opts.remoteDebugger;
25
+ this._started = false;
26
+ }
27
+
28
+ override async startCapture(): Promise<void> {
29
+ this.log.debug('Starting performance (Timeline) log capture');
30
+ this._clearEntries();
31
+ const result = await this.remoteDebugger.startTimeline(this.onTimelineEvent.bind(this));
32
+ this._started = true;
33
+ return result;
34
+ }
35
+
36
+ override async stopCapture(): Promise<void> {
37
+ this.log.debug('Stopping performance (Timeline) log capture');
38
+ const result = await this.remoteDebugger.stopTimeline();
39
+ this._started = false;
40
+ return result;
41
+ }
42
+
43
+ override get isCapturing(): boolean {
44
+ return this._started;
45
+ }
46
+
47
+ protected override _serializeEntry(value: PerformanceLogEntry): PerformanceLogEntry {
48
+ return value;
49
+ }
50
+
51
+ protected override _deserializeEntry(value: PerformanceLogEntry): LogEntry {
52
+ return value as LogEntry;
53
+ }
54
+
55
+ private onTimelineEvent(event: PerformanceLogEntry): void {
56
+ this.log.debug(`Received Timeline event: ${_.truncate(JSON.stringify(event))}`);
57
+ this.broadcast(event);
58
+ }
59
+ }
60
+
61
+ export default IOSPerformanceLog;
@@ -0,0 +1,119 @@
1
+ import _ from 'lodash';
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';
6
+
7
+ const EXECVP_ERROR_PATTERN = /execvp\(\)/;
8
+
9
+ const START_TIMEOUT = 10000;
10
+
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 sim: Simulator;
20
+ private showLogs: boolean;
21
+ private 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;
29
+ this.proc = null;
30
+ }
31
+
32
+ override async startCapture(): Promise<void> {
33
+ if (_.isUndefined(this.sim.udid)) {
34
+ throw new Error(`Log capture requires a sim udid`);
35
+ }
36
+
37
+ if (!(await this.sim.isRunning())) {
38
+ throw new Error(`iOS Simulator with udid '${this.sim.udid}' is not running`);
39
+ }
40
+ const spawnArgs = ['log', 'stream', '--style', 'compact'];
41
+ if (this.predicate) {
42
+ spawnArgs.push('--predicate', this.predicate);
43
+ }
44
+ this.log.debug(
45
+ `Starting log capture for iOS Simulator with udid '${this.sim.udid}' ` + `using simctl`,
46
+ );
47
+ try {
48
+ // cleanup existing listeners if the previous session has not been terminated properly
49
+ await exec('pkill', ['-f', [this.sim.udid, ...spawnArgs].join(' ')]);
50
+ } catch (ign) {}
51
+ try {
52
+ this.proc = await this.sim.simctl.spawnSubProcess(spawnArgs);
53
+ await this.finishStartingLogCapture();
54
+ } catch (e) {
55
+ throw new Error(`Simulator log capture failed. Original error: ${e.message}`);
56
+ }
57
+ }
58
+
59
+ override async stopCapture(): Promise<void> {
60
+ if (!this.proc) {
61
+ return;
62
+ }
63
+ await this.killLogSubProcess();
64
+ this.proc = null;
65
+ }
66
+
67
+ override get isCapturing(): boolean {
68
+ return Boolean(this.proc && this.proc.isRunning);
69
+ }
70
+
71
+ private onOutput(logRow: string, prefix: string = ''): void {
72
+ this.broadcast(logRow);
73
+ if (this.showLogs) {
74
+ const space = prefix.length > 0 ? ' ' : '';
75
+ this.log.info(`[IOS_SYSLOG_ROW${space}${prefix}] ${logRow}`);
76
+ }
77
+ }
78
+
79
+ private async killLogSubProcess(): Promise<void> {
80
+ if (!this.proc?.isRunning) {
81
+ return;
82
+ }
83
+
84
+ this.log.debug('Stopping iOS log capture');
85
+ try {
86
+ await this.proc.stop('SIGTERM', 1000);
87
+ } catch (e) {
88
+ if (!this.proc.isRunning) {
89
+ return;
90
+ }
91
+ this.log.warn('Cannot stop log capture process. Sending SIGKILL');
92
+ await this.proc.stop('SIGKILL');
93
+ }
94
+ }
95
+
96
+ private async finishStartingLogCapture() {
97
+ if (!this.proc) {
98
+ throw this.log.errorWithException('Could not capture simulator log');
99
+ }
100
+
101
+ for (const streamName of ['stdout', 'stderr']) {
102
+ this.proc.on(`lines-${streamName}`, (/** @type {string[]} */ lines) => {
103
+ for (const line of lines) {
104
+ this.onOutput(line, ...(streamName === 'stderr' ? ['STDERR'] : []));
105
+ }
106
+ });
107
+ }
108
+
109
+ const startDetector = (/** @type {string} */ stdout, /** @type {string} */ stderr) => {
110
+ if (EXECVP_ERROR_PATTERN.test(stderr)) {
111
+ throw new Error('iOS log capture process failed to start');
112
+ }
113
+ return stdout || stderr;
114
+ };
115
+ await this.proc.start(startDetector, START_TIMEOUT);
116
+ }
117
+ }
118
+
119
+ export default IOSSimulatorLog;
@@ -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
+ }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "appium-xcuitest-driver",
3
- "version": "7.21.0",
3
+ "version": "7.21.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appium-xcuitest-driver",
9
- "version": "7.21.0",
9
+ "version": "7.21.2",
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.0.60",
33
+ "teen_process": "^2.1.10",
34
34
  "ws": "^8.13.0"
35
35
  },
36
36
  "devDependencies": {
@@ -75,17 +75,17 @@
75
75
  }
76
76
  },
77
77
  "node_modules/@appium/base-driver": {
78
- "version": "9.11.0",
79
- "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-9.11.0.tgz",
80
- "integrity": "sha512-DU6HVQL9Ys6R55c1BeSBZ8eBmQ4QjRG2vNjSJNaj4IXSfx4e9XVlVm4RbTqMbE7Tc2zsoGfqqPQFP4sxJCGsCg==",
78
+ "version": "9.11.1",
79
+ "resolved": "https://registry.npmjs.org/@appium/base-driver/-/base-driver-9.11.1.tgz",
80
+ "integrity": "sha512-gil/4mE/I9SusprGkCgePSkqnvLhv+D2CZ3xS2GkOPmCv07M0Gpsf9y9IuN9LmgyNUDalDtnXjErSn+LDjZd9g==",
81
81
  "dependencies": {
82
- "@appium/support": "^5.1.0",
82
+ "@appium/support": "^5.1.1",
83
83
  "@appium/types": "^0.21.0",
84
84
  "@colors/colors": "1.6.0",
85
85
  "@types/async-lock": "1.4.2",
86
86
  "@types/bluebird": "3.5.42",
87
87
  "@types/express": "4.17.21",
88
- "@types/lodash": "4.17.5",
88
+ "@types/lodash": "4.17.6",
89
89
  "@types/method-override": "0.0.35",
90
90
  "@types/serve-favicon": "2.5.7",
91
91
  "async-lock": "1.4.1",
@@ -96,7 +96,7 @@
96
96
  "express": "4.19.2",
97
97
  "http-status-codes": "2.3.0",
98
98
  "lodash": "4.17.21",
99
- "lru-cache": "10.2.2",
99
+ "lru-cache": "10.3.0",
100
100
  "method-override": "3.0.0",
101
101
  "morgan": "1.10.0",
102
102
  "path-to-regexp": "7.0.0",
@@ -113,17 +113,12 @@
113
113
  "spdy": "4.0.2"
114
114
  }
115
115
  },
116
- "node_modules/@appium/base-driver/node_modules/@types/lodash": {
117
- "version": "4.17.5",
118
- "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.5.tgz",
119
- "integrity": "sha512-MBIOHVZqVqgfro1euRDWX7OO0fBVUUMrN6Pwm8LQsz8cWhEpihlvR70ENj3f40j58TNxZaWv2ndSkInykNBBJw=="
120
- },
121
116
  "node_modules/@appium/docutils": {
122
- "version": "1.0.16",
123
- "resolved": "https://registry.npmjs.org/@appium/docutils/-/docutils-1.0.16.tgz",
124
- "integrity": "sha512-EjBN/Y3HW4cugjJcGBu8KEnqYZVr99TqnioVF5yOUmN7b/1j/tsvcsaRP+7w8h/cVAVSk+v4oDcLp8sU6dHl6A==",
117
+ "version": "1.0.17",
118
+ "resolved": "https://registry.npmjs.org/@appium/docutils/-/docutils-1.0.17.tgz",
119
+ "integrity": "sha512-SXJftkyY2YRvPouPFuYAUrv9Yw8tkKHUUoBFQrOH5yvMOxt4RIx6G9TktHcisZ8p0y66fa+pr8ic87jnDPlCvA==",
125
120
  "dependencies": {
126
- "@appium/support": "^5.1.0",
121
+ "@appium/support": "^5.1.1",
127
122
  "@appium/tsconfig": "^0.3.3",
128
123
  "@sliphua/lilconfig-ts-loader": "3.2.2",
129
124
  "@types/which": "3.0.4",
@@ -152,6 +147,21 @@
152
147
  "npm": ">=8"
153
148
  }
154
149
  },
150
+ "node_modules/@appium/docutils/node_modules/teen_process": {
151
+ "version": "2.1.6",
152
+ "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.1.6.tgz",
153
+ "integrity": "sha512-VCbxLX0EMjnq3kYS+UJBlqAIJJeNfAxDExLLX0jvWa8KyRPbVLzc+CHFwigwR8fTWIdsVOXR2f7owrSq1xtYrw==",
154
+ "dependencies": {
155
+ "bluebird": "^3.7.2",
156
+ "lodash": "^4.17.21",
157
+ "shell-quote": "^1.8.1",
158
+ "source-map-support": "^0.x"
159
+ },
160
+ "engines": {
161
+ "node": "^16.13.0 || >=18.0.0",
162
+ "npm": ">=8"
163
+ }
164
+ },
155
165
  "node_modules/@appium/logger": {
156
166
  "version": "1.5.0",
157
167
  "resolved": "https://registry.npmjs.org/@appium/logger/-/logger-1.5.0.tgz",
@@ -194,9 +204,9 @@
194
204
  }
195
205
  },
196
206
  "node_modules/@appium/support": {
197
- "version": "5.1.0",
198
- "resolved": "https://registry.npmjs.org/@appium/support/-/support-5.1.0.tgz",
199
- "integrity": "sha512-i3h5b811wSjshSPZzf+vRWvXMJ0cCnevpxcnNGYSu2HVxZtGRGx2wxkXiJnrojadQHCtA0wVwm0wHqudMb6kwA==",
207
+ "version": "5.1.1",
208
+ "resolved": "https://registry.npmjs.org/@appium/support/-/support-5.1.1.tgz",
209
+ "integrity": "sha512-YwludQ+V5mgGYJQjkuDJ29X0LSJehBeC5IwvaZxKdv/VKLKAbOl3QZqv3RKIGJqQInP6ZOD+doG3OVP64Y/txQ==",
200
210
  "dependencies": {
201
211
  "@appium/logger": "^1.5.0",
202
212
  "@appium/tsconfig": "^0.3.3",
@@ -259,6 +269,21 @@
259
269
  "sharp": "0.33.4"
260
270
  }
261
271
  },
272
+ "node_modules/@appium/support/node_modules/teen_process": {
273
+ "version": "2.1.6",
274
+ "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.1.6.tgz",
275
+ "integrity": "sha512-VCbxLX0EMjnq3kYS+UJBlqAIJJeNfAxDExLLX0jvWa8KyRPbVLzc+CHFwigwR8fTWIdsVOXR2f7owrSq1xtYrw==",
276
+ "dependencies": {
277
+ "bluebird": "^3.7.2",
278
+ "lodash": "^4.17.21",
279
+ "shell-quote": "^1.8.1",
280
+ "source-map-support": "^0.x"
281
+ },
282
+ "engines": {
283
+ "node": "^16.13.0 || >=18.0.0",
284
+ "npm": ">=8"
285
+ }
286
+ },
262
287
  "node_modules/@appium/tsconfig": {
263
288
  "version": "0.3.3",
264
289
  "resolved": "https://registry.npmjs.org/@appium/tsconfig/-/tsconfig-0.3.3.tgz",
@@ -2420,9 +2445,9 @@
2420
2445
  }
2421
2446
  },
2422
2447
  "node_modules/lru-cache": {
2423
- "version": "10.2.2",
2424
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz",
2425
- "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==",
2448
+ "version": "10.3.0",
2449
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz",
2450
+ "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==",
2426
2451
  "engines": {
2427
2452
  "node": "14 || >=16.14"
2428
2453
  }
@@ -3717,9 +3742,9 @@
3717
3742
  }
3718
3743
  },
3719
3744
  "node_modules/teen_process": {
3720
- "version": "2.1.6",
3721
- "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.1.6.tgz",
3722
- "integrity": "sha512-VCbxLX0EMjnq3kYS+UJBlqAIJJeNfAxDExLLX0jvWa8KyRPbVLzc+CHFwigwR8fTWIdsVOXR2f7owrSq1xtYrw==",
3745
+ "version": "2.1.10",
3746
+ "resolved": "https://registry.npmjs.org/teen_process/-/teen_process-2.1.10.tgz",
3747
+ "integrity": "sha512-zEXJ+qOij5Kiov7X5rvWexo3yV9EJiVdjM53XTD0E7v8QxEOHoGBeIy4J/iKDD2sCO60sIaSIRS4Y50Tya5/PA==",
3723
3748
  "dependencies": {
3724
3749
  "bluebird": "^3.7.2",
3725
3750
  "lodash": "^4.17.21",
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "xcuitest",
9
9
  "xctest"
10
10
  ],
11
- "version": "7.21.0",
11
+ "version": "7.21.2",
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.0.60",
100
+ "teen_process": "^2.1.10",
101
101
  "ws": "^8.13.0"
102
102
  },
103
103
  "scripts": {
@@ -1,54 +0,0 @@
1
- import {logger} from 'appium/support';
2
- import {IOSLog} from './ios-log';
3
- import {services} from 'appium-ios-device';
4
-
5
- const log = logger.getLogger('IOSDeviceLog');
6
-
7
- class IOSDeviceLog extends IOSLog {
8
- constructor(opts) {
9
- super();
10
- this.udid = opts.udid;
11
- this.showLogs = !!opts.showLogs;
12
- this.service = null;
13
- }
14
- /**
15
- * @override
16
- */
17
- async startCapture() {
18
- if (this.service) {
19
- return;
20
- }
21
- this.service = await services.startSyslogService(this.udid);
22
- this.service.start(this.onLog.bind(this));
23
- }
24
-
25
- onLog(logLine) {
26
- this.broadcast(logLine);
27
- if (this.showLogs) {
28
- log.info(logLine);
29
- }
30
- }
31
-
32
- /**
33
- * @override
34
- */
35
- get isCapturing() {
36
- return !!this.service;
37
- }
38
-
39
- /**
40
- * @override
41
- */
42
- // XXX: superclass is async, but this is not
43
- // eslint-disable-next-line require-await
44
- async stopCapture() {
45
- if (!this.service) {
46
- return;
47
- }
48
- this.service.close();
49
- this.service = null;
50
- }
51
- }
52
-
53
- export {IOSDeviceLog};
54
- export default IOSDeviceLog;
@@ -1,65 +0,0 @@
1
- import {EventEmitter} from 'events';
2
-
3
- // We keep only the most recent log entries to avoid out of memory error
4
- const MAX_LOG_ENTRIES_COUNT = 10000;
5
-
6
- class IOSLog extends EventEmitter {
7
- constructor() {
8
- super();
9
- this.logs = [];
10
- this.logIdxSinceLastRequest = -1;
11
- this.maxBufferSize = MAX_LOG_ENTRIES_COUNT;
12
- }
13
-
14
- /** @returns {Promise<void>} */
15
- // eslint-disable-next-line require-await
16
- async startCapture() {
17
- throw new Error(`Sub-classes need to implement a 'startCapture' function`);
18
- }
19
-
20
- /** @returns {Promise<void>} */
21
- // eslint-disable-next-line require-await
22
- async stopCapture() {
23
- throw new Error(`Sub-classes need to implement a 'stopCapture' function`);
24
- }
25
-
26
- /** @returns {boolean} */
27
- get isCapturing() {
28
- throw new Error(`Sub-classes need to implement a 'isCapturing' function`);
29
- }
30
-
31
- broadcast(logLine) {
32
- const logObj = {
33
- timestamp: Date.now(),
34
- level: 'ALL',
35
- message: logLine,
36
- };
37
- this.logs.push(logObj);
38
- this.emit('output', logObj);
39
- if (this.logs.length > this.maxBufferSize) {
40
- this.logs.shift();
41
- if (this.logIdxSinceLastRequest > 0) {
42
- --this.logIdxSinceLastRequest;
43
- }
44
- }
45
- }
46
-
47
- getLogs() {
48
- if (this.logs.length && this.logIdxSinceLastRequest < this.logs.length) {
49
- let result = this.logs;
50
- if (this.logIdxSinceLastRequest > 0) {
51
- result = result.slice(this.logIdxSinceLastRequest);
52
- }
53
- this.logIdxSinceLastRequest = this.logs.length;
54
- return result;
55
- }
56
- return [];
57
- }
58
-
59
- getAllLogs() {
60
- return this.logs;
61
- }
62
- }
63
-
64
- export {IOSLog};
65
- export default IOSLog;