appium-xcuitest-driver 7.25.0 → 7.26.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.
@@ -4,11 +4,12 @@ import {DEFAULT_WS_PATHNAME_PREFIX} from 'appium/driver';
4
4
  import {IOSCrashLog} from '../device-log/ios-crash-log';
5
5
  import {IOSSimulatorLog} from '../device-log/ios-simulator-log';
6
6
  import {IOSDeviceLog} from '../device-log/ios-device-log';
7
- import log from '../logger';
8
7
  import WebSocket from 'ws';
9
8
  import SafariConsoleLog from '../device-log/safari-console-log';
10
9
  import SafariNetworkLog from '../device-log/safari-network-log';
11
10
  import { toLogEntry } from '../device-log/helpers';
11
+ import { NATIVE_WIN, BIDI_EVENT_NAME } from '../utils';
12
+ import { util } from 'appium/support';
12
13
 
13
14
  /**
14
15
  * Determines the websocket endpoint based on the `sessionId`
@@ -20,6 +21,18 @@ const WEBSOCKET_ENDPOINT = (sessionId) =>
20
21
 
21
22
  const GET_SERVER_LOGS_FEATURE = 'get_server_logs';
22
23
 
24
+ /**
25
+ *
26
+ * @param {Object} x
27
+ * @returns {import('./types').LogEntry}
28
+ */
29
+ function nativeLogEntryToSeleniumEntry (x) {
30
+ return toLogEntry(
31
+ _.isEmpty(x.prefix) ? x.message : `[${x.prefix}] ${x.message}`,
32
+ /** @type {any} */ (x).timestamp ?? Date.now()
33
+ );
34
+ }
35
+
23
36
  /**
24
37
  * @type {import('@appium/types').LogDefRecord}
25
38
  * @privateRemarks The return types for these getters should be specified
@@ -52,10 +65,7 @@ const SUPPORTED_LOG_TYPES = {
52
65
  */
53
66
  getter: (self) => {
54
67
  self.assertFeatureEnabled(GET_SERVER_LOGS_FEATURE);
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
- ));
68
+ return self.log.unwrap().record.map(nativeLogEntryToSeleniumEntry);
59
69
  },
60
70
  },
61
71
  };
@@ -97,44 +107,107 @@ export default {
97
107
  );
98
108
  },
99
109
 
110
+ /**
111
+ * https://w3c.github.io/webdriver-bidi/#event-log-entryAdded
112
+ *
113
+ * @template {import('node:events').EventEmitter} EE
114
+ * @this {XCUITestDriver}
115
+ * @param {EE} logEmitter
116
+ * @param {BiDiListenerProperties} properties
117
+ * @returns {[EE, import('./types').LogListener]}
118
+ */
119
+ assignBiDiLogListener (logEmitter, properties) {
120
+ const {
121
+ type,
122
+ context = NATIVE_WIN,
123
+ srcEventName = 'output',
124
+ entryTransformer,
125
+ } = properties;
126
+ const listener = (/** @type {import('./types').LogEntry} */ logEntry) => {
127
+ const finalEntry = entryTransformer ? entryTransformer(logEntry) : logEntry;
128
+ this.eventEmitter.emit(BIDI_EVENT_NAME, {
129
+ context,
130
+ method: 'log.entryAdded',
131
+ params: {
132
+ type,
133
+ level: finalEntry.level,
134
+ source: {
135
+ realm: util.uuidV4(),
136
+ },
137
+ text: finalEntry.message,
138
+ timestamp: finalEntry.timestamp,
139
+ },
140
+ });
141
+ };
142
+ logEmitter.on(srcEventName, listener);
143
+ return [logEmitter, listener];
144
+ },
145
+
100
146
  /**
101
147
  * @this {XCUITestDriver}
102
148
  */
103
149
  async startLogCapture() {
104
150
  this.logs = this.logs || {};
105
151
  if (!_.isUndefined(this.logs.syslog) && this.logs.syslog.isCapturing) {
106
- log.warn('Trying to start iOS log capture but it has already started!');
152
+ this.log.warn('Trying to start iOS log capture but it has already started!');
107
153
  return true;
108
154
  }
155
+
109
156
  if (_.isUndefined(this.logs.syslog)) {
110
- this.logs.crashlog = new IOSCrashLog({
111
- sim: /** @type {import('appium-ios-simulator').Simulator} */ (this.device),
112
- udid: this.isRealDevice() ? this.opts.udid : undefined,
113
- log: this.log,
114
- });
115
- this.logs.syslog = this.isRealDevice()
116
- ? new IOSDeviceLog({
117
- udid: this.opts.udid,
118
- showLogs: this.opts.showIOSLog,
119
- log: this.log,
120
- })
121
- : new IOSSimulatorLog({
157
+ [this.logs.crashlog,] = this.assignBiDiLogListener(
158
+ new IOSCrashLog({
122
159
  sim: /** @type {import('appium-ios-simulator').Simulator} */ (this.device),
123
- showLogs: this.opts.showIOSLog,
124
- iosSimulatorLogsPredicate: this.opts.iosSimulatorLogsPredicate,
160
+ udid: this.isRealDevice() ? this.opts.udid : undefined,
125
161
  log: this.log,
126
- });
162
+ }), {
163
+ type: 'crashlog',
164
+ }
165
+ );
166
+ [this.logs.syslog,] = this.assignBiDiLogListener(
167
+ this.isRealDevice()
168
+ ? new IOSDeviceLog({
169
+ udid: this.opts.udid,
170
+ showLogs: this.opts.showIOSLog,
171
+ log: this.log,
172
+ })
173
+ : new IOSSimulatorLog({
174
+ sim: /** @type {import('appium-ios-simulator').Simulator} */ (this.device),
175
+ showLogs: this.opts.showIOSLog,
176
+ iosSimulatorLogsPredicate: this.opts.iosSimulatorLogsPredicate,
177
+ log: this.log,
178
+ }),
179
+ {
180
+ type: 'syslog',
181
+ }
182
+ );
127
183
  if (_.isBoolean(this.opts.showSafariConsoleLog)) {
128
- this.logs.safariConsole = new SafariConsoleLog({
129
- showLogs: this.opts.showSafariConsoleLog,
130
- log: this.log,
131
- });
184
+ [this.logs.safariConsole,] = this.assignBiDiLogListener(
185
+ new SafariConsoleLog({
186
+ showLogs: this.opts.showSafariConsoleLog,
187
+ log: this.log,
188
+ }), {
189
+ type: 'safariConsole',
190
+ }
191
+ );
132
192
  }
133
193
  if (_.isBoolean(this.opts.showSafariNetworkLog)) {
134
- this.logs.safariNetwork = new SafariNetworkLog({
135
- showLogs: this.opts.showSafariNetworkLog,
136
- log: this.log,
137
- });
194
+ [this.logs.safariNetwork,] = this.assignBiDiLogListener(
195
+ new SafariNetworkLog({
196
+ showLogs: this.opts.showSafariNetworkLog,
197
+ log: this.log,
198
+ }), {
199
+ type: 'safariNetwork',
200
+ }
201
+ );
202
+ }
203
+ if (this.isFeatureEnabled(GET_SERVER_LOGS_FEATURE)) {
204
+ [, this._bidiServerLogListener] = this.assignBiDiLogListener(
205
+ this.log.unwrap(), {
206
+ type: 'server',
207
+ srcEventName: 'log',
208
+ entryTransformer: nativeLogEntryToSeleniumEntry,
209
+ }
210
+ );
138
211
  }
139
212
  }
140
213
 
@@ -143,15 +216,15 @@ export default {
143
216
  const promises = [
144
217
  (async () => {
145
218
  try {
146
- await this.logs.syslog.startCapture();
219
+ await this.logs.syslog?.startCapture();
147
220
  didStartSyslog = true;
148
221
  this.eventEmitter.emit('syslogStarted', this.logs.syslog);
149
222
  } catch (err) {
150
- log.debug(err.stack);
151
- log.warn(`Continuing without capturing device logs: ${err.message}`);
223
+ this.log.debug(err.stack);
224
+ this.log.warn(`Continuing without capturing device logs: ${err.message}`);
152
225
  }
153
226
  })(),
154
- this.logs.crashlog.startCapture(),
227
+ this.logs.crashlog?.startCapture() ?? B.resolve(),
155
228
  ];
156
229
  await B.all(promises);
157
230
 
@@ -179,13 +252,13 @@ export default {
179
252
  ).getWebSocketHandlers(pathname),
180
253
  )
181
254
  ) {
182
- log.debug(
255
+ this.log.debug(
183
256
  `The system logs broadcasting web socket server is already listening at ${pathname}`,
184
257
  );
185
258
  return;
186
259
  }
187
260
 
188
- log.info(`Assigning system logs broadcasting web socket server to ${pathname}`);
261
+ this.log.info(`Assigning system logs broadcasting web socket server to ${pathname}`);
189
262
  // https://github.com/websockets/ws/blob/master/doc/ws.md
190
263
  const wss = new WebSocket.Server({
191
264
  noServer: true,
@@ -195,9 +268,9 @@ export default {
195
268
  const remoteIp = _.isEmpty(req.headers['x-forwarded-for'])
196
269
  ? req.connection?.remoteAddress
197
270
  : req.headers['x-forwarded-for'];
198
- log.debug(`Established a new system logs listener web socket connection from ${remoteIp}`);
271
+ this.log.debug(`Established a new system logs listener web socket connection from ${remoteIp}`);
199
272
  } else {
200
- log.debug('Established a new system logs listener web socket connection');
273
+ this.log.debug('Established a new system logs listener web socket connection');
201
274
  }
202
275
 
203
276
  if (_.isEmpty(this._syslogWebsocketListener)) {
@@ -207,11 +280,11 @@ export default {
207
280
  }
208
281
  };
209
282
  }
210
- this.logs.syslog.on('output', this._syslogWebsocketListener);
283
+ this.logs.syslog?.on('output', this._syslogWebsocketListener);
211
284
 
212
285
  ws.on('close', (code, reason) => {
213
286
  if (!_.isEmpty(this._syslogWebsocketListener)) {
214
- this.logs.syslog.removeListener('output', this._syslogWebsocketListener);
287
+ this.logs.syslog?.removeListener('output', this._syslogWebsocketListener);
215
288
  this._syslogWebsocketListener = null;
216
289
  }
217
290
 
@@ -222,7 +295,7 @@ export default {
222
295
  if (!_.isEmpty(reason)) {
223
296
  closeMsg += ` Reason: ${reason.toString()}.`;
224
297
  }
225
- log.debug(closeMsg);
298
+ this.log.debug(closeMsg);
226
299
  });
227
300
  });
228
301
  await /** @type {AppiumServer} */ (this.server).addWebSocketHandler(
@@ -243,7 +316,7 @@ export default {
243
316
  return;
244
317
  }
245
318
 
246
- log.debug('Stopping the system logs broadcasting web socket server');
319
+ this.log.debug('Stopping the system logs broadcasting web socket server');
247
320
  await /** @type {AppiumServer} */ (this.server).removeWebSocketHandler(pathname);
248
321
  },
249
322
  };
@@ -259,3 +332,11 @@ export default {
259
332
  /**
260
333
  * @typedef {import('@appium/types').AppiumServer} AppiumServer
261
334
  */
335
+
336
+ /**
337
+ * @typedef {Object} BiDiListenerProperties
338
+ * @property {string} type
339
+ * @property {string} [srcEventName='output']
340
+ * @property {string} [context=NATIVE_WIN]
341
+ * @property {(x: Object) => import('./types').LogEntry} [entryTransformer]
342
+ */
@@ -572,3 +572,5 @@ export interface LogEntry {
572
572
  level: string,
573
573
  message: string;
574
574
  }
575
+
576
+ export type LogListener = (logEntry: LogEntry) => any;
package/lib/driver.js CHANGED
@@ -266,6 +266,12 @@ export class XCUITestDriver extends BaseDriver {
266
266
  /** @type {import('appium-remote-debugger').RemoteDebugger|null} */
267
267
  remote;
268
268
 
269
+ /** @type {DriverLogs} */
270
+ logs;
271
+
272
+ /** @type {import('./commands/types').LogListener|undefined} */
273
+ _bidiServerLogListener;
274
+
269
275
  /**
270
276
  *
271
277
  * @param {XCUITestDriverOpts} opts
@@ -315,6 +321,7 @@ export class XCUITestDriver extends BaseDriver {
315
321
  this._audioRecorder = null;
316
322
  this.appInfosCache = new AppInfosCache(this.log);
317
323
  this.remote = null;
324
+ this.doesSupportBidi = true;
318
325
  }
319
326
 
320
327
  async onSettingsUpdate(key, value) {
@@ -977,10 +984,12 @@ export class XCUITestDriver extends BaseDriver {
977
984
  }
978
985
  }
979
986
 
980
- if (!_.isEmpty(this.logs)) {
981
- await this.logs.syslog.stopCapture();
982
- this.logs = {};
987
+ await this.logs.syslog?.stopCapture();
988
+ _.values(this.logs).forEach((x) => x.removeAllListeners());
989
+ if (this._bidiServerLogListener) {
990
+ this.log.unwrap().off('log', this._bidiServerLogListener);
983
991
  }
992
+ this.logs = {};
984
993
 
985
994
  if (this.mjpegStream) {
986
995
  this.log.info('Closing MJPEG stream');
@@ -2008,6 +2017,7 @@ export class XCUITestDriver extends BaseDriver {
2008
2017
  extractLogs = commands.logExtensions.extractLogs;
2009
2018
  supportedLogTypes = commands.logExtensions.supportedLogTypes;
2010
2019
  startLogCapture = commands.logExtensions.startLogCapture;
2020
+ assignBiDiLogListener = commands.logExtensions.assignBiDiLogListener;
2011
2021
  mobileStartLogsBroadcast = commands.logExtensions.mobileStartLogsBroadcast;
2012
2022
  mobileStopLogsBroadcast = commands.logExtensions.mobileStopLogsBroadcast;
2013
2023
 
@@ -2181,3 +2191,12 @@ export default XCUITestDriver;
2181
2191
  * @typedef {import('appium-xcode').XcodeVersion} XcodeVersion
2182
2192
  * @typedef {import('appium-ios-simulator').Simulator} Simulator
2183
2193
  */
2194
+
2195
+ /**
2196
+ * @typedef {Object} DriverLogs
2197
+ * @property {import('./device-log/ios-device-log').IOSDeviceLog|import('./device-log/ios-simulator-log').IOSSimulatorLog} [syslog]
2198
+ * @property {import('./device-log/ios-crash-log').IOSCrashLog} [crashlog]
2199
+ * @property {import('./device-log/safari-console-log').SafariConsoleLog} [safariConsole]
2200
+ * @property {import('./device-log/safari-network-log').SafariNetworkLog} [safariNetwork]
2201
+ * @property {import('./device-log/ios-performance-log').IOSPerformanceLog} [performance]
2202
+ */
@@ -314,18 +314,11 @@ export class RealDevice {
314
314
  * @param {import('./driver').XCUITestDriverOpts} opts
315
315
  * @returns {Promise<void>}
316
316
  */
317
- async reset({bundleId, fullReset, platformVersion}) {
318
- if (!bundleId) {
319
- return;
320
- }
321
-
322
- if (bundleId === SAFARI_BUNDLE_ID) {
323
- this.log.debug('Reset requested. About to terminate Safari');
324
- await this.terminateApp(bundleId, String(platformVersion));
325
- return;
326
- }
327
-
328
- if (!fullReset) {
317
+ async reset({bundleId, fullReset}) {
318
+ if (!bundleId || !fullReset || bundleId === SAFARI_BUNDLE_ID) {
319
+ // Safari cannot be removed as system app.
320
+ // Safari process handling will be managed by WDA
321
+ // with noReset, forceAppLaunch or shouldTerminateApp capabilities.
329
322
  return;
330
323
  }
331
324
 
package/lib/utils.js CHANGED
@@ -20,6 +20,8 @@ const XCTEST_LOG_FILES_PATTERNS = [
20
20
  /^StandardOutputAndStandardError\.txt$/i,
21
21
  ];
22
22
  const XCTEST_LOGS_CACHE_FOLDER_PREFIX = 'com.apple.dt.XCTest';
23
+ export const NATIVE_WIN = 'NATIVE_APP';
24
+ export const BIDI_EVENT_NAME = 'bidiEvent';
23
25
 
24
26
  /**
25
27
  * @privateRemarks Is the minimum version really Xcode 7.3?
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "appium-xcuitest-driver",
3
- "version": "7.25.0",
3
+ "version": "7.26.1",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "appium-xcuitest-driver",
9
- "version": "7.25.0",
9
+ "version": "7.26.1",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@colors/colors": "^1.6.0",
@@ -870,9 +870,9 @@
870
870
  }
871
871
  },
872
872
  "node_modules/@types/node": {
873
- "version": "22.5.1",
874
- "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz",
875
- "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==",
873
+ "version": "22.5.4",
874
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.4.tgz",
875
+ "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
876
876
  "license": "MIT",
877
877
  "dependencies": {
878
878
  "undici-types": "~6.19.2"
@@ -990,12 +990,12 @@
990
990
  }
991
991
  },
992
992
  "node_modules/@xmldom/xmldom": {
993
- "version": "0.9.0",
994
- "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.0.tgz",
995
- "integrity": "sha512-Zb9MTlKGnUdxglDKF75cJwvsNp+EhPwzguLSTp/u1yeDU59lz7eA9e14S9z/sn5HHKX5NEQZaKjePl/69uqGhw==",
993
+ "version": "0.9.2",
994
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.2.tgz",
995
+ "integrity": "sha512-afP3lpLtalPxgNGU4bxlsru4wSDsZwdSFKnHs6PR0q3KIEWWcAlBqAdx4aWlVtP1gV1FBWlJ3d0MgaRRdj/ucA==",
996
996
  "license": "MIT",
997
997
  "engines": {
998
- "node": ">=10.0.0"
998
+ "node": ">=14.0.0"
999
999
  }
1000
1000
  },
1001
1001
  "node_modules/abort-controller": {
@@ -1265,9 +1265,9 @@
1265
1265
  "license": "MIT"
1266
1266
  },
1267
1267
  "node_modules/axios": {
1268
- "version": "1.7.6",
1269
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.6.tgz",
1270
- "integrity": "sha512-Ekur6XDwhnJ5RgOCaxFnXyqlPALI3rVeukZMwOdfghW7/wGz784BYKiQq+QD8NPcr91KRo30KfHOchyijwWw7g==",
1268
+ "version": "1.7.7",
1269
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz",
1270
+ "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==",
1271
1271
  "license": "MIT",
1272
1272
  "dependencies": {
1273
1273
  "follow-redirects": "^1.15.6",
@@ -1768,13 +1768,13 @@
1768
1768
  "license": "MIT"
1769
1769
  },
1770
1770
  "node_modules/debug": {
1771
- "version": "4.3.6",
1772
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz",
1773
- "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==",
1771
+ "version": "4.3.7",
1772
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz",
1773
+ "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==",
1774
1774
  "devOptional": true,
1775
1775
  "license": "MIT",
1776
1776
  "dependencies": {
1777
- "ms": "2.1.2"
1777
+ "ms": "^2.1.3"
1778
1778
  },
1779
1779
  "engines": {
1780
1780
  "node": ">=6.0"
@@ -2089,9 +2089,9 @@
2089
2089
  }
2090
2090
  },
2091
2091
  "node_modules/follow-redirects": {
2092
- "version": "1.15.6",
2093
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
2094
- "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
2092
+ "version": "1.15.9",
2093
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
2094
+ "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
2095
2095
  "funding": [
2096
2096
  {
2097
2097
  "type": "individual",
@@ -2984,9 +2984,9 @@
2984
2984
  }
2985
2985
  },
2986
2986
  "node_modules/ms": {
2987
- "version": "2.1.2",
2988
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
2989
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
2987
+ "version": "2.1.3",
2988
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
2989
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
2990
2990
  "license": "MIT"
2991
2991
  },
2992
2992
  "node_modules/mv": {
@@ -3344,9 +3344,9 @@
3344
3344
  "license": "MIT"
3345
3345
  },
3346
3346
  "node_modules/picocolors": {
3347
- "version": "1.0.1",
3348
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz",
3349
- "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==",
3347
+ "version": "1.1.0",
3348
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz",
3349
+ "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==",
3350
3350
  "license": "ISC"
3351
3351
  },
3352
3352
  "node_modules/pkg-dir": {
@@ -3735,12 +3735,6 @@
3735
3735
  "node": ">=4"
3736
3736
  }
3737
3737
  },
3738
- "node_modules/send/node_modules/ms": {
3739
- "version": "2.1.3",
3740
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
3741
- "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
3742
- "license": "MIT"
3743
- },
3744
3738
  "node_modules/serve-favicon": {
3745
3739
  "version": "2.5.0",
3746
3740
  "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz",
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "xcuitest",
9
9
  "xctest"
10
10
  ],
11
- "version": "7.25.0",
11
+ "version": "7.26.1",
12
12
  "author": "Appium Contributors",
13
13
  "license": "Apache-2.0",
14
14
  "repository": {