@appium/base-driver 10.7.0 → 10.7.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 (159) hide show
  1. package/README.md +2 -2
  2. package/build/lib/basedriver/capabilities.d.ts +1 -1
  3. package/build/lib/basedriver/capabilities.d.ts.map +1 -1
  4. package/build/lib/basedriver/capabilities.js +4 -8
  5. package/build/lib/basedriver/capabilities.js.map +1 -1
  6. package/build/lib/basedriver/commands/bidi.d.ts.map +1 -1
  7. package/build/lib/basedriver/commands/bidi.js +1 -3
  8. package/build/lib/basedriver/commands/bidi.js.map +1 -1
  9. package/build/lib/basedriver/commands/event.d.ts.map +1 -1
  10. package/build/lib/basedriver/commands/event.js.map +1 -1
  11. package/build/lib/basedriver/commands/execute.d.ts.map +1 -1
  12. package/build/lib/basedriver/commands/execute.js +1 -1
  13. package/build/lib/basedriver/commands/execute.js.map +1 -1
  14. package/build/lib/basedriver/commands/find.d.ts.map +1 -1
  15. package/build/lib/basedriver/commands/find.js.map +1 -1
  16. package/build/lib/basedriver/commands/log.d.ts.map +1 -1
  17. package/build/lib/basedriver/commands/log.js +1 -2
  18. package/build/lib/basedriver/commands/log.js.map +1 -1
  19. package/build/lib/basedriver/commands/mixin.d.ts.map +1 -1
  20. package/build/lib/basedriver/commands/mixin.js.map +1 -1
  21. package/build/lib/basedriver/commands/timeout.d.ts.map +1 -1
  22. package/build/lib/basedriver/commands/timeout.js +1 -1
  23. package/build/lib/basedriver/commands/timeout.js.map +1 -1
  24. package/build/lib/basedriver/core.d.ts +1 -2
  25. package/build/lib/basedriver/core.d.ts.map +1 -1
  26. package/build/lib/basedriver/core.js +6 -10
  27. package/build/lib/basedriver/core.js.map +1 -1
  28. package/build/lib/basedriver/device-settings.d.ts +1 -1
  29. package/build/lib/basedriver/device-settings.d.ts.map +1 -1
  30. package/build/lib/basedriver/device-settings.js +2 -3
  31. package/build/lib/basedriver/device-settings.js.map +1 -1
  32. package/build/lib/basedriver/driver.d.ts +1 -2
  33. package/build/lib/basedriver/driver.d.ts.map +1 -1
  34. package/build/lib/basedriver/driver.js +6 -11
  35. package/build/lib/basedriver/driver.js.map +1 -1
  36. package/build/lib/basedriver/extension-core.d.ts.map +1 -1
  37. package/build/lib/basedriver/extension-core.js +1 -1
  38. package/build/lib/basedriver/extension-core.js.map +1 -1
  39. package/build/lib/basedriver/helpers.d.ts.map +1 -1
  40. package/build/lib/basedriver/helpers.js +6 -11
  41. package/build/lib/basedriver/helpers.js.map +1 -1
  42. package/build/lib/basedriver/ipc.d.ts +1 -1
  43. package/build/lib/basedriver/ipc.d.ts.map +1 -1
  44. package/build/lib/basedriver/ipc.js +3 -5
  45. package/build/lib/basedriver/ipc.js.map +1 -1
  46. package/build/lib/basedriver/validation.d.ts.map +1 -1
  47. package/build/lib/basedriver/validation.js +1 -2
  48. package/build/lib/basedriver/validation.js.map +1 -1
  49. package/build/lib/express/express-logging.d.ts.map +1 -1
  50. package/build/lib/express/express-logging.js +4 -2
  51. package/build/lib/express/express-logging.js.map +1 -1
  52. package/build/lib/express/idempotency.d.ts +1 -1
  53. package/build/lib/express/idempotency.d.ts.map +1 -1
  54. package/build/lib/express/idempotency.js +6 -9
  55. package/build/lib/express/idempotency.js.map +1 -1
  56. package/build/lib/express/middleware.d.ts +1 -1
  57. package/build/lib/express/middleware.d.ts.map +1 -1
  58. package/build/lib/express/middleware.js +1 -1
  59. package/build/lib/express/middleware.js.map +1 -1
  60. package/build/lib/express/server.d.ts +2 -2
  61. package/build/lib/express/server.d.ts.map +1 -1
  62. package/build/lib/express/server.js +8 -9
  63. package/build/lib/express/server.js.map +1 -1
  64. package/build/lib/express/websocket.d.ts.map +1 -1
  65. package/build/lib/express/websocket.js.map +1 -1
  66. package/build/lib/helpers/capabilities.d.ts +1 -1
  67. package/build/lib/helpers/capabilities.d.ts.map +1 -1
  68. package/build/lib/helpers/capabilities.js.map +1 -1
  69. package/build/lib/helpers/extension-command-name.d.ts.map +1 -1
  70. package/build/lib/helpers/extension-command-name.js.map +1 -1
  71. package/build/lib/helpers/levenshtein-match.d.ts.map +1 -1
  72. package/build/lib/helpers/levenshtein-match.js +1 -4
  73. package/build/lib/helpers/levenshtein-match.js.map +1 -1
  74. package/build/lib/index.d.ts +21 -18
  75. package/build/lib/index.d.ts.map +1 -1
  76. package/build/lib/index.js +9 -12
  77. package/build/lib/index.js.map +1 -1
  78. package/build/lib/jsonwp-proxy/protocol-converter.d.ts.map +1 -1
  79. package/build/lib/jsonwp-proxy/protocol-converter.js +6 -15
  80. package/build/lib/jsonwp-proxy/protocol-converter.js.map +1 -1
  81. package/build/lib/jsonwp-proxy/proxy.d.ts +3 -3
  82. package/build/lib/jsonwp-proxy/proxy.d.ts.map +1 -1
  83. package/build/lib/jsonwp-proxy/proxy.js +17 -19
  84. package/build/lib/jsonwp-proxy/proxy.js.map +1 -1
  85. package/build/lib/jsonwp-status/status.d.ts.map +1 -1
  86. package/build/lib/jsonwp-status/status.js.map +1 -1
  87. package/build/lib/protocol/errors.d.ts +1 -1
  88. package/build/lib/protocol/errors.d.ts.map +1 -1
  89. package/build/lib/protocol/errors.js +11 -28
  90. package/build/lib/protocol/errors.js.map +1 -1
  91. package/build/lib/protocol/helpers.d.ts.map +1 -1
  92. package/build/lib/protocol/helpers.js.map +1 -1
  93. package/build/lib/protocol/index.d.ts +4 -4
  94. package/build/lib/protocol/index.d.ts.map +1 -1
  95. package/build/lib/protocol/index.js +12 -12
  96. package/build/lib/protocol/index.js.map +1 -1
  97. package/build/lib/protocol/protocol.d.ts +1 -1
  98. package/build/lib/protocol/protocol.d.ts.map +1 -1
  99. package/build/lib/protocol/protocol.js +16 -30
  100. package/build/lib/protocol/protocol.js.map +1 -1
  101. package/build/lib/protocol/routes.d.ts +1 -1
  102. package/build/lib/protocol/routes.d.ts.map +1 -1
  103. package/build/lib/protocol/routes.js +5 -15
  104. package/build/lib/protocol/routes.js.map +1 -1
  105. package/build/lib/test-pages/handlers.d.ts.map +1 -1
  106. package/build/lib/test-pages/handlers.js +2 -2
  107. package/build/lib/test-pages/handlers.js.map +1 -1
  108. package/build/lib/test-pages/index.d.ts +1 -1
  109. package/build/lib/test-pages/index.d.ts.map +1 -1
  110. package/build/lib/test-pages/index.js +4 -4
  111. package/build/lib/test-pages/index.js.map +1 -1
  112. package/build/lib/test-pages/static-dir.d.ts.map +1 -1
  113. package/build/lib/test-pages/static-dir.js +5 -6
  114. package/build/lib/test-pages/static-dir.js.map +1 -1
  115. package/build/lib/test-pages/template.d.ts.map +1 -1
  116. package/build/lib/test-pages/template.js.map +1 -1
  117. package/build/lib/utils.d.ts.map +1 -1
  118. package/build/lib/utils.js.map +1 -1
  119. package/lib/basedriver/capabilities.ts +14 -37
  120. package/lib/basedriver/commands/bidi.ts +4 -14
  121. package/lib/basedriver/commands/event.ts +9 -15
  122. package/lib/basedriver/commands/execute.ts +5 -14
  123. package/lib/basedriver/commands/find.ts +3 -10
  124. package/lib/basedriver/commands/log.ts +2 -2
  125. package/lib/basedriver/commands/mixin.ts +1 -0
  126. package/lib/basedriver/commands/timeout.ts +5 -9
  127. package/lib/basedriver/core.ts +9 -15
  128. package/lib/basedriver/device-settings.ts +6 -9
  129. package/lib/basedriver/driver.ts +24 -48
  130. package/lib/basedriver/extension-core.ts +7 -12
  131. package/lib/basedriver/helpers.ts +18 -45
  132. package/lib/basedriver/ipc.ts +13 -18
  133. package/lib/basedriver/validation.ts +6 -16
  134. package/lib/express/express-logging.ts +11 -11
  135. package/lib/express/idempotency.ts +10 -19
  136. package/lib/express/middleware.ts +10 -18
  137. package/lib/express/server.ts +29 -38
  138. package/lib/express/websocket.ts +7 -13
  139. package/lib/helpers/capabilities.ts +2 -3
  140. package/lib/helpers/extension-command-name.ts +2 -4
  141. package/lib/helpers/levenshtein-match.ts +2 -7
  142. package/lib/{index.js → index.ts} +7 -9
  143. package/lib/jsonwp-proxy/protocol-converter.ts +24 -88
  144. package/lib/jsonwp-proxy/proxy.ts +34 -62
  145. package/lib/jsonwp-status/status.ts +5 -10
  146. package/lib/protocol/errors.ts +24 -70
  147. package/lib/protocol/helpers.ts +1 -0
  148. package/lib/protocol/index.ts +20 -26
  149. package/lib/protocol/protocol.ts +38 -82
  150. package/lib/protocol/routes.ts +8 -21
  151. package/lib/test-pages/handlers.ts +4 -2
  152. package/lib/test-pages/index.ts +5 -3
  153. package/lib/test-pages/static-dir.ts +6 -6
  154. package/lib/test-pages/template.ts +1 -3
  155. package/lib/utils.ts +1 -4
  156. package/package.json +29 -32
  157. package/tsconfig.json +14 -9
  158. package/LICENSE +0 -201
  159. package/index.js +0 -1
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-vars */
2
2
  import type {Constraints, Element, IFindCommands} from '@appium/types';
3
+
3
4
  import {errors} from '../../protocol';
4
5
  import type {BaseDriver} from '../driver';
5
6
  import {mixin} from './mixin';
@@ -71,19 +72,11 @@ async function findElOrElsWithProcessing<C extends Constraints>(
71
72
  }
72
73
 
73
74
  const FindCommands: IFindCommands = {
74
- async findElement<C extends Constraints>(
75
- this: BaseDriver<C>,
76
- strategy: string,
77
- selector: string,
78
- ) {
75
+ async findElement<C extends Constraints>(this: BaseDriver<C>, strategy: string, selector: string) {
79
76
  return await this.findElOrElsWithProcessing(strategy, selector, false);
80
77
  },
81
78
 
82
- async findElements<C extends Constraints>(
83
- this: BaseDriver<C>,
84
- strategy: string,
85
- selector: string,
86
- ) {
79
+ async findElements<C extends Constraints>(this: BaseDriver<C>, strategy: string, selector: string) {
87
80
  return await this.findElOrElsWithProcessing(strategy, selector, true);
88
81
  },
89
82
 
@@ -1,4 +1,5 @@
1
1
  import type {Constraints, Driver, ILogCommands} from '@appium/types';
2
+
2
3
  import type {BaseDriver} from '../driver';
3
4
  import {mixin} from './mixin';
4
5
 
@@ -23,8 +24,7 @@ const LogCommands: ILogCommands = {
23
24
  Object.entries(this.supportedLogTypes).map(([key, value]) => [key, value.description]),
24
25
  );
25
26
  throw new Error(
26
- `Unsupported log type '${String(logType)}'. ` +
27
- `Supported types: ${JSON.stringify(logsTypesWithDescriptions)}`,
27
+ `Unsupported log type '${String(logType)}'. ` + `Supported types: ${JSON.stringify(logsTypesWithDescriptions)}`,
28
28
  );
29
29
  }
30
30
 
@@ -1,4 +1,5 @@
1
1
  import type {Constraints} from '@appium/types';
2
+
2
3
  import {BaseDriver} from '../driver';
3
4
 
4
5
  /**
@@ -1,8 +1,9 @@
1
- import {waitForCondition} from 'asyncbox';
2
1
  import {util} from '@appium/support';
2
+ import type {Constraints, ITimeoutCommands} from '@appium/types';
3
+ import {waitForCondition} from 'asyncbox';
4
+
3
5
  import {errors} from '../../protocol';
4
6
  import type {BaseDriver} from '../driver';
5
- import type {Constraints, ITimeoutCommands} from '@appium/types';
6
7
  import {mixin} from './mixin';
7
8
 
8
9
  declare module '../driver' {
@@ -40,9 +41,7 @@ const TimeoutCommands: ITimeoutCommands = {
40
41
 
41
42
  this.log.debug(`W3C timeout argument: ${JSON.stringify({script, pageLoad, implicit})}}`);
42
43
  if ([script, pageLoad, implicit].every((value) => value == null)) {
43
- throw new errors.InvalidArgumentError(
44
- 'W3C protocol expects any of script, pageLoad or implicit to be set',
45
- );
44
+ throw new errors.InvalidArgumentError('W3C protocol expects any of script, pageLoad or implicit to be set');
46
45
  }
47
46
  if (util.hasValue(script)) {
48
47
  await this.scriptTimeoutW3C(script);
@@ -110,10 +109,7 @@ const TimeoutCommands: ITimeoutCommands = {
110
109
  }
111
110
  },
112
111
 
113
- async implicitWaitForCondition<C extends Constraints>(
114
- this: BaseDriver<C>,
115
- condFn: (...args: any[]) => Promise<any>,
116
- ) {
112
+ async implicitWaitForCondition<C extends Constraints>(this: BaseDriver<C>, condFn: (...args: any[]) => Promise<any>) {
117
113
  this.log.debug(`Waiting up to ${this.implicitWaitMs} ms for condition`);
118
114
  const wrappedCondFn = async (...args: any[]) => {
119
115
  // reset command timeout
@@ -1,3 +1,6 @@
1
+ import os from 'node:os';
2
+
3
+ import {util} from '@appium/support';
1
4
  import type {
2
5
  AppiumLogger,
3
6
  Constraints,
@@ -12,13 +15,12 @@ import type {
12
15
  StringRecord,
13
16
  } from '@appium/types';
14
17
  import AsyncLock from 'async-lock';
15
- import {util} from '@appium/support';
16
- import os from 'node:os';
18
+
17
19
  import {DEFAULT_BASE_PATH, PROTOCOLS} from '../constants';
18
20
  import {errors} from '../protocol';
19
21
  import {DeviceSettings} from './device-settings';
20
- import * as helpers from './helpers';
21
22
  import {ExtensionCore} from './extension-core';
23
+ import * as helpers from './helpers';
22
24
 
23
25
  const NEW_COMMAND_TIMEOUT_MS = 60 * 1000;
24
26
 
@@ -113,7 +115,7 @@ export class DriverCore<const C extends Constraints, Settings extends StringReco
113
115
  this.shouldValidateCaps = shouldValidateCaps;
114
116
 
115
117
  // keeping track of initial opts
116
- this.initialOpts = structuredClone(opts);
118
+ this.initialOpts = {...opts};
117
119
 
118
120
  this.sessionId = null;
119
121
  this.helpers = helpers;
@@ -275,17 +277,12 @@ export class DriverCore<const C extends Constraints, Settings extends StringReco
275
277
  `the feature name split by a colon. Got '${fullName}' instead`,
276
278
  );
277
279
  }
278
- return [
279
- fullName.substring(0, separatorPos).toLowerCase(),
280
- fullName.substring(separatorPos + 1),
281
- ];
280
+ return [fullName.substring(0, separatorPos).toLowerCase(), fullName.substring(separatorPos + 1)];
282
281
  };
283
282
  const parseFullNames = (fullNames: string[]) => fullNames.map(parseFullName);
284
283
  const matches = (pair: string[]) => {
285
284
  const [automationName, featureName] = pair;
286
- return (
287
- [currentAutomationName, ALL_DRIVERS_MATCH].includes(automationName) && featureName === name
288
- );
285
+ return [currentAutomationName, ALL_DRIVERS_MATCH].includes(automationName) && featureName === name;
289
286
  };
290
287
 
291
288
  // if we have explicitly denied this feature, return false immediately
@@ -334,9 +331,7 @@ export class DriverCore<const C extends Constraints, Settings extends StringReco
334
331
  }
335
332
 
336
333
  if (!validStrategies.includes(strategy)) {
337
- throw new errors.InvalidSelectorError(
338
- `Locator Strategy '${strategy}' is not supported for this session`,
339
- );
334
+ throw new errors.InvalidSelectorError(`Locator Strategy '${strategy}' is not supported for this session`);
340
335
  }
341
336
  }
342
337
 
@@ -390,7 +385,6 @@ export class DriverCore<const C extends Constraints, Settings extends StringReco
390
385
  }
391
386
 
392
387
  /**
393
- *
394
388
  * @param {Driver} driver
395
389
  */
396
390
  addManagedDriver(driver: Driver) {
@@ -1,7 +1,8 @@
1
- import {util, node} from '@appium/support';
2
- import {log} from './logger';
1
+ import {node, util} from '@appium/support';
2
+ import type {IDeviceSettings, SettingsUpdateListener, StringRecord} from '@appium/types';
3
+
3
4
  import {errors} from '../protocol/errors';
4
- import type {StringRecord, IDeviceSettings, SettingsUpdateListener} from '@appium/types';
5
+ import {log} from './logger';
5
6
 
6
7
  /**
7
8
  * Maximum size (in bytes) of a given driver's settings object (which is internal to {@linkcode DeviceSettings}).
@@ -21,10 +22,7 @@ export class DeviceSettings<T extends StringRecord = StringRecord> implements ID
21
22
  * @param defaultSettings - Initial settings (shallow-copied).
22
23
  * @param onSettingsUpdate - Called when a setting is changed; receives (prop, newValue, curValue).
23
24
  */
24
- constructor(
25
- defaultSettings: T = {} as T,
26
- onSettingsUpdate: SettingsUpdateListener<T> = async () => {},
27
- ) {
25
+ constructor(defaultSettings: T = {} as T, onSettingsUpdate: SettingsUpdateListener<T> = async () => {}) {
28
26
  this._settings = {...defaultSettings};
29
27
  this._onSettingsUpdate = onSettingsUpdate;
30
28
  }
@@ -37,8 +35,7 @@ export class DeviceSettings<T extends StringRecord = StringRecord> implements ID
37
35
  async update(newSettings: T): Promise<void> {
38
36
  if (!util.isPlainObject(newSettings)) {
39
37
  throw new errors.InvalidArgumentError(
40
- `Settings update should be called with valid JSON. Got ` +
41
- `${JSON.stringify(newSettings)} instead`,
38
+ `Settings update should be called with valid JSON. Got ` + `${JSON.stringify(newSettings)} instead`,
42
39
  );
43
40
  }
44
41
 
@@ -1,35 +1,35 @@
1
- import type AsyncLock from 'async-lock';
2
1
  import {util} from '@appium/support';
3
2
  import {
4
- BASE_DESIRED_CAP_CONSTRAINTS,
5
3
  type AppiumServer,
4
+ BASE_DESIRED_CAP_CONSTRAINTS,
6
5
  type BaseDriverCapConstraints,
7
6
  type Capabilities,
8
7
  type Constraints,
9
8
  type DefaultCreateSessionResult,
9
+ type DefaultDeleteSessionResult,
10
10
  type Driver,
11
11
  type DriverCaps,
12
12
  type DriverData,
13
+ type InitialOpts,
13
14
  type ServerArgs,
15
+ type SessionCapabilities,
16
+ type SingularSessionData,
14
17
  type StringRecord,
15
18
  type W3CDriverCaps,
16
- type InitialOpts,
17
- type DefaultDeleteSessionResult,
18
- type SingularSessionData,
19
- type SessionCapabilities,
20
19
  } from '@appium/types';
20
+ import type AsyncLock from 'async-lock';
21
+
21
22
  import {fixCaps, isW3cCaps} from '../helpers/capabilities';
23
+ import {resolveExecuteExtensionName} from '../helpers/extension-command-name';
22
24
  import {getLevenshteinSuggestion} from '../helpers/levenshtein-match';
23
25
  import {calcSignature} from '../helpers/session';
24
26
  import {DELETE_SESSION_COMMAND, determineProtocol, errors} from '../protocol';
27
+ import {mergePlainObjects} from '../utils';
25
28
  import {processCapabilities, validateCaps} from './capabilities';
26
29
  import {DriverCore} from './core';
27
30
  import * as helpers from './helpers';
28
- import {mergePlainObjects} from '../utils';
29
- import {resolveExecuteExtensionName} from '../helpers/extension-command-name';
30
31
 
31
- type CommandInvoker<C extends Constraints> = BaseDriver<C> &
32
- Record<string, ((...args: any[]) => any) | undefined>;
32
+ type CommandInvoker<C extends Constraints> = BaseDriver<C> & Record<string, ((...args: any[]) => any) | undefined>;
33
33
 
34
34
  const EVENT_SESSION_INIT = 'newSessionRequested';
35
35
  const EVENT_SESSION_START = 'newSessionStarted';
@@ -73,11 +73,7 @@ export class BaseDriver<
73
73
  */
74
74
  protected get _desiredCapConstraints(): Readonly<BaseDriverCapConstraints & C> {
75
75
  return Object.freeze(
76
- mergePlainObjects(
77
- {},
78
- BASE_DESIRED_CAP_CONSTRAINTS,
79
- this.desiredCapConstraints,
80
- ) as BaseDriverCapConstraints & C,
76
+ mergePlainObjects({}, BASE_DESIRED_CAP_CONSTRAINTS, this.desiredCapConstraints) as BaseDriverCapConstraints & C,
81
77
  );
82
78
  }
83
79
 
@@ -149,11 +145,7 @@ export class BaseDriver<
149
145
  // automatic session deletion in this.onCommandTimeout. Of course we don't
150
146
  // want to trigger the timer when the user is shutting down the session
151
147
  // intentionally
152
- if (
153
- !wasSessionShutdownUnexpectedly &&
154
- this.isCommandsQueueEnabled &&
155
- cmd !== DELETE_SESSION_COMMAND
156
- ) {
148
+ if (!wasSessionShutdownUnexpectedly && this.isCommandsQueueEnabled && cmd !== DELETE_SESSION_COMMAND) {
157
149
  // resetting existing timeout
158
150
  await this.startNewCommandTimeout();
159
151
  }
@@ -205,9 +197,7 @@ export class BaseDriver<
205
197
  return cmd;
206
198
  }
207
199
 
208
- async startUnexpectedShutdown(
209
- err: Error = new errors.NoSuchDriverError('The driver was unexpectedly shut down!'),
210
- ) {
200
+ async startUnexpectedShutdown(err: Error = new errors.NoSuchDriverError('The driver was unexpectedly shut down!')) {
211
201
  this.eventEmitter.emit(ON_UNEXPECTED_SHUTDOWN_EVENT, err); // allow others to listen for this
212
202
  this.shutdownUnexpectedly = true;
213
203
  try {
@@ -227,10 +217,7 @@ export class BaseDriver<
227
217
  if (!this.newCommandTimeoutMs) return; // eslint-disable-line curly
228
218
 
229
219
  this.noCommandTimer = setTimeout(async () => {
230
- this.log.warn(
231
- `Shutting down because we waited ` +
232
- `${this.newCommandTimeoutMs / 1000.0} seconds for a command`,
233
- );
220
+ this.log.warn(`Shutting down because we waited ` + `${this.newCommandTimeoutMs / 1000.0} seconds for a command`);
234
221
  const errorMessage =
235
222
  `New Command Timeout of ` +
236
223
  `${this.newCommandTimeoutMs / 1000.0} seconds ` +
@@ -277,7 +264,6 @@ export class BaseDriver<
277
264
  }
278
265
 
279
266
  /**
280
- *
281
267
  * Historically the first two arguments were reserved for JSONWP capabilities.
282
268
  * Appium 2 has dropped the support of these, so now we only accept capability
283
269
  * objects in W3C format and thus allow any of the three arguments to represent
@@ -291,16 +277,12 @@ export class BaseDriver<
291
277
  driverData?: DriverData[],
292
278
  ): Promise<CreateResult> {
293
279
  if (this.sessionId !== null) {
294
- throw new errors.SessionNotCreatedError(
295
- 'Cannot create a new session while one is in progress',
296
- );
280
+ throw new errors.SessionNotCreatedError('Cannot create a new session while one is in progress');
297
281
  }
298
282
 
299
283
  this.log.debug();
300
284
 
301
- const originalCaps = structuredClone(
302
- [w3cCapabilities, w3cCapabilities1, w3cCapabilities2].find(isW3cCaps),
303
- );
285
+ const originalCaps = structuredClone([w3cCapabilities, w3cCapabilities1, w3cCapabilities2].find(isW3cCaps));
304
286
  if (!originalCaps) {
305
287
  throw new errors.SessionNotCreatedError(
306
288
  'Appium only supports W3C-style capability objects. ' +
@@ -311,17 +293,11 @@ export class BaseDriver<
311
293
  this.setProtocolW3C();
312
294
 
313
295
  this.originalCaps = originalCaps;
314
- this.log.debug(
315
- `Creating session with W3C capabilities: ${JSON.stringify(originalCaps, null, 2)}`,
316
- );
296
+ this.log.debug(`Creating session with W3C capabilities: ${JSON.stringify(originalCaps, null, 2)}`);
317
297
 
318
298
  let caps: DriverCaps<C>;
319
299
  try {
320
- caps = processCapabilities(
321
- originalCaps,
322
- this._desiredCapConstraints,
323
- this.shouldValidateCaps,
324
- ) as DriverCaps<C>;
300
+ caps = processCapabilities(originalCaps, this._desiredCapConstraints, this.shouldValidateCaps) as DriverCaps<C>;
325
301
  caps = fixCaps(caps, this._desiredCapConstraints, this.log) as DriverCaps<C>;
326
302
  } catch (e) {
327
303
  const message = e instanceof Error ? e.message : String(e);
@@ -334,7 +310,7 @@ export class BaseDriver<
334
310
  this.sessionCreationTimestampMs = Date.now();
335
311
  this.caps = caps;
336
312
  // merge caps onto opts so we don't need to worry about what's where
337
- this.opts = {...structuredClone(this.initialOpts), ...this.caps};
313
+ this.opts = {...this.initialOpts, ...this.caps};
338
314
 
339
315
  // deal with resets
340
316
  // some people like to do weird things by setting noReset and fullReset
@@ -382,9 +358,10 @@ export class BaseDriver<
382
358
  * Use {@linkcode EventCommands.getLogEvents} instead to get the event history.
383
359
  */
384
360
  async getSession() {
385
- return (
386
- this.caps.eventTimings ? {...this.caps, events: this.eventHistory} : this.caps
387
- ) as SingularSessionData<C, SessionData>;
361
+ return (this.caps.eventTimings ? {...this.caps, events: this.eventHistory} : this.caps) as SingularSessionData<
362
+ C,
363
+ SessionData
364
+ >;
388
365
  }
389
366
 
390
367
  /**
@@ -432,8 +409,7 @@ export class BaseDriver<
432
409
  const capError = e instanceof Error ? e : new Error(String(e));
433
410
  throw this.log.errorWithException(
434
411
  new errors.SessionNotCreatedError(
435
- `Session capabilities were not valid for the ` +
436
- `following reason(s): ${capError.message}`,
412
+ `Session capabilities were not valid for the ` + `following reason(s): ${capError.message}`,
437
413
  capError,
438
414
  ),
439
415
  );
@@ -1,5 +1,6 @@
1
- import {logger, util} from '@appium/support';
2
1
  import {EventEmitter} from 'node:events';
2
+
3
+ import {logger, util} from '@appium/support';
3
4
  import type {
4
5
  AppiumLogger,
5
6
  BidiModuleMap,
@@ -9,6 +10,7 @@ import type {
9
10
  IpcData,
10
11
  StringRecord,
11
12
  } from '@appium/types';
13
+
12
14
  import {MAX_LOG_BODY_LENGTH} from '../constants';
13
15
  import {errors} from '../protocol';
14
16
  import {BIDI_COMMANDS} from '../protocol/bidi-commands';
@@ -43,9 +45,7 @@ export class ExtensionCore {
43
45
  updateBidiCommands(cmds: BidiModuleMap): void {
44
46
  const overlappingKeys = Object.keys(cmds).filter((key) => key in this.bidiCommands);
45
47
  if (overlappingKeys.length) {
46
- this.log.warn(
47
- `Overwriting existing bidi modules: ${JSON.stringify(overlappingKeys)}. This may not be intended!`,
48
- );
48
+ this.log.warn(`Overwriting existing bidi modules: ${JSON.stringify(overlappingKeys)}. This may not be intended!`);
49
49
  }
50
50
  this.bidiCommands = {
51
51
  ...this.bidiCommands,
@@ -107,9 +107,7 @@ export class ExtensionCore {
107
107
  if (params?.required?.length) {
108
108
  for (const requiredParam of params.required) {
109
109
  if (bidiParams[requiredParam] === undefined) {
110
- throw new errors.InvalidArgumentError(
111
- `The ${requiredParam} parameter was required but you omitted it`,
112
- );
110
+ throw new errors.InvalidArgumentError(`The ${requiredParam} parameter was required but you omitted it`);
113
111
  }
114
112
  args.push(bidiParams[requiredParam]);
115
113
  }
@@ -127,15 +125,12 @@ export class ExtensionCore {
127
125
  `method '${command}'`,
128
126
  );
129
127
  // call the handler with the signature appropriate to extension type (plugin or driver)
130
- const commandHandler = (
131
- this as unknown as Record<string, (...handlerArgs: any[]) => Promise<unknown>>
132
- )[command];
128
+ const commandHandler = (this as unknown as Record<string, (...handlerArgs: any[]) => Promise<unknown>>)[command];
133
129
  const response =
134
130
  next && driver
135
131
  ? await commandHandler.call(this, next, driver, ...args)
136
132
  : await commandHandler.call(this, ...args);
137
- const finalResponse: BiDiResultData =
138
- response === undefined ? {} : (response as BiDiResultData);
133
+ const finalResponse: BiDiResultData = response === undefined ? {} : (response as BiDiResultData);
139
134
  this.log.debug(
140
135
  `Responding to bidi command '${bidiCmd}' with ` +
141
136
  `${util.truncateString(JSON.stringify(finalResponse), {length: MAX_LOG_BODY_LENGTH})}`,
@@ -1,21 +1,17 @@
1
1
  import nodeFs from 'node:fs';
2
2
  import path from 'node:path';
3
- import {log as logger} from './logger';
4
- import {tempDir, fs, util, timing, node} from '@appium/support';
5
- import {LRUCache} from 'lru-cache';
3
+ import type {Readable} from 'node:stream';
4
+
5
+ import {fs, node, tempDir, timing, util} from '@appium/support';
6
+ import type {CachedAppInfo, ConfigureAppOptions, DriverHelpers, HTTPHeaders, PostProcessOptions} from '@appium/types';
6
7
  import AsyncLock from 'async-lock';
7
8
  import axios from 'axios';
8
- import type {
9
- ConfigureAppOptions,
10
- CachedAppInfo,
11
- PostProcessOptions,
12
- HTTPHeaders,
13
- DriverHelpers,
14
- } from '@appium/types';
15
9
  import type {AxiosResponseHeaders, RawAxiosRequestHeaders} from 'axios';
16
- import type {Readable} from 'node:stream';
10
+ import {LRUCache} from 'lru-cache';
17
11
  import type {PackageJson} from 'type-fest';
18
12
 
13
+ import {log as logger} from './logger';
14
+
19
15
  // for compat with running tests transpiled and in-place
20
16
  export const BASEDRIVER_VER = readBaseDriverVersion();
21
17
 
@@ -31,10 +27,7 @@ const APPLICATIONS_CACHE = new LRUCache<string, CachedAppInfoEntry>({
31
27
  ttl: CACHED_APPS_MAX_AGE_MS, // expire after 24 hours
32
28
  updateAgeOnGet: true,
33
29
  dispose: ({fullPath}, app) => {
34
- logger.info(
35
- `The application '${app}' cached at '${fullPath}' has ` +
36
- `expired after ${CACHED_APPS_MAX_AGE_MS}ms`,
37
- );
30
+ logger.info(`The application '${app}' cached at '${fullPath}' has ` + `expired after ${CACHED_APPS_MAX_AGE_MS}ms`);
38
31
  if (fullPath) {
39
32
  void fs.rimraf(fullPath);
40
33
  }
@@ -52,9 +45,7 @@ process.on('exit', () => {
52
45
  }
53
46
 
54
47
  const appPaths = [...APPLICATIONS_CACHE.values()].map(({fullPath}) => fullPath);
55
- logger.debug(
56
- `Performing cleanup of ${util.pluralize('cached application', appPaths.length, true)}`,
57
- );
48
+ logger.debug(`Performing cleanup of ${util.pluralize('cached application', appPaths.length, true)}`);
58
49
  for (const appPath of appPaths) {
59
50
  if (!appPath) {
60
51
  continue;
@@ -285,8 +276,7 @@ export async function configureApp(
285
276
  }
286
277
 
287
278
  verifyAppExtension(newApp, supportedAppExtensions);
288
- return appCacheKey !== toCacheKey(newApp) &&
289
- (packageHash || Object.values(remoteAppProps).some(Boolean))
279
+ return appCacheKey !== toCacheKey(newApp) && (packageHash || Object.values(remoteAppProps).some(Boolean))
290
280
  ? await storeAppInCache(newApp)
291
281
  : newApp;
292
282
  });
@@ -386,9 +376,7 @@ export function generateDriverLogPrefix(obj: object | null, _sessionId?: string
386
376
 
387
377
  // #region Private helpers
388
378
 
389
- function parseAppLink(
390
- appLink: string,
391
- ): URL | {protocol?: string; pathname?: string; href?: string; search?: string} {
379
+ function parseAppLink(appLink: string): URL | {protocol?: string; pathname?: string; href?: string; search?: string} {
392
380
  try {
393
381
  return new URL(appLink);
394
382
  } catch {
@@ -438,10 +426,7 @@ function toCacheKey(app: string): string {
438
426
  return app;
439
427
  }
440
428
 
441
- async function queryAppLink(
442
- appLink: string,
443
- reqHeaders: RawAxiosRequestHeaders,
444
- ): Promise<RemoteAppData> {
429
+ async function queryAppLink(appLink: string, reqHeaders: RawAxiosRequestHeaders): Promise<RemoteAppData> {
445
430
  const url = new URL(appLink);
446
431
  // Extract credentials, then remove them from the URL for axios
447
432
  const {username, password} = url;
@@ -454,8 +439,7 @@ async function queryAppLink(
454
439
  auth: axiosAuth,
455
440
  responseType: 'stream' as const,
456
441
  timeout: APP_DOWNLOAD_TIMEOUT_MS,
457
- validateStatus: (status: number) =>
458
- (status >= 200 && status < 300) || status === HTTP_STATUS_NOT_MODIFIED,
442
+ validateStatus: (status: number) => (status >= 200 && status < 300) || status === HTTP_STATUS_NOT_MODIFIED,
459
443
  headers: reqHeaders,
460
444
  };
461
445
  try {
@@ -510,10 +494,7 @@ function determineFilename(
510
494
  replacement: SANITIZE_REPLACEMENT,
511
495
  });
512
496
  const extname = path.extname(basename);
513
- if (
514
- headers['content-disposition'] &&
515
- /^attachment/i.test(String(headers['content-disposition']))
516
- ) {
497
+ if (headers['content-disposition'] && /^attachment/i.test(String(headers['content-disposition']))) {
517
498
  logger.debug(`Content-Disposition: ${headers['content-disposition']}`);
518
499
  const match = /filename="([^"]+)/i.exec(String(headers['content-disposition']));
519
500
  if (match) {
@@ -522,13 +503,9 @@ function determineFilename(
522
503
  }
523
504
 
524
505
  // assign the default file name and the extension if none has been detected
525
- const resultingName = basename
526
- ? basename.substring(0, basename.length - extname.length)
527
- : DEFAULT_BASENAME;
506
+ const resultingName = basename ? basename.substring(0, basename.length - extname.length) : DEFAULT_BASENAME;
528
507
  let resultingExt = extname;
529
- if (
530
- !supportedAppExtensions.map((ext) => ext.toLowerCase()).includes(resultingExt.toLowerCase())
531
- ) {
508
+ if (!supportedAppExtensions.map((ext) => ext.toLowerCase()).includes(resultingExt.toLowerCase())) {
532
509
  logger.info(
533
510
  `The current file extension '${resultingExt}' is not supported. ` +
534
511
  `Defaulting to '${supportedAppExtensions[0]}'`,
@@ -539,9 +516,7 @@ function determineFilename(
539
516
  }
540
517
 
541
518
  function verifyAppExtension(app: string, supportedAppExtensions: string[]): string {
542
- if (
543
- supportedAppExtensions.map((ext) => ext.toLowerCase()).includes(path.extname(app).toLowerCase())
544
- ) {
519
+ if (supportedAppExtensions.map((ext) => ext.toLowerCase()).includes(path.extname(app).toLowerCase())) {
545
520
  return app;
546
521
  }
547
522
  throw new Error(
@@ -592,9 +567,7 @@ function readBaseDriverVersion(): string {
592
567
  if (!pkgRoot) {
593
568
  throw new Error('Cannot find the @appium/base-driver package root');
594
569
  }
595
- const pkg = JSON.parse(
596
- nodeFs.readFileSync(path.join(pkgRoot, 'package.json'), 'utf8'),
597
- ) as PackageJson;
570
+ const pkg = JSON.parse(nodeFs.readFileSync(path.join(pkgRoot, 'package.json'), 'utf8')) as PackageJson;
598
571
  if (typeof pkg.version !== 'string') {
599
572
  throw new Error('Invalid `package.json` for @appium/base-driver');
600
573
  }
@@ -1,16 +1,18 @@
1
- import {log} from './logger';
1
+ import EventEmitter from 'node:events';
2
+
3
+ import {node} from '@appium/support';
2
4
  import type {
3
- StringRecord,
4
- IIpcSubscription,
5
- IAppiumIpc,
6
- IpcMessage,
7
- IpcEvent,
8
5
  AppiumLogger,
6
+ IAppiumIpc,
7
+ IIpcSubscription,
9
8
  IpcData,
9
+ IpcEvent,
10
+ IpcMessage,
11
+ StringRecord,
10
12
  } from '@appium/types';
11
- import EventEmitter from 'node:events';
12
13
  import {sleep} from 'asyncbox';
13
- import {node} from '@appium/support';
14
+
15
+ import {log} from './logger';
14
16
 
15
17
  const DEF_MAX_OBJ_SIZE_BYTES = 1024 * 1024; // 1mb seems like plenty for any plugin to pass a message
16
18
  const DEF_MAX_TOPICS = 1000;
@@ -26,10 +28,7 @@ export type AppiumIpcOpts = {
26
28
 
27
29
  const ASYNC_ITERATOR_STOP = Symbol('asyncIteratorStop');
28
30
 
29
- export class IpcSubscription<T extends IpcData>
30
- extends EventEmitter<IpcEvent<T>>
31
- implements IIpcSubscription<T>
32
- {
31
+ export class IpcSubscription<T extends IpcData> extends EventEmitter<IpcEvent<T>> implements IIpcSubscription<T> {
33
32
  constructor(
34
33
  public readonly subscriber: string,
35
34
  public readonly topic: string,
@@ -110,9 +109,7 @@ export class AppiumIpc implements IAppiumIpc {
110
109
  subscribe<T extends IpcData>(topic: string, subscriber: string): IpcSubscription<T> {
111
110
  this.log.info(`Subscribing ${subscriber} to topic '${topic}'`);
112
111
  if (this.subscriptionExists(topic, subscriber)) {
113
- throw new Error(
114
- `Subscription already exists for topic "${topic}" and subscriber "${subscriber}"`,
115
- );
112
+ throw new Error(`Subscription already exists for topic "${topic}" and subscriber "${subscriber}"`);
116
113
  }
117
114
 
118
115
  this.ensureTopic(topic);
@@ -157,9 +154,7 @@ export class AppiumIpc implements IAppiumIpc {
157
154
 
158
155
  this.messageByTopic[topic] = message;
159
156
 
160
- const subs = this.subs[topic]
161
- ? this.subs[topic].filter((sub) => sub.subscriber !== publisher)
162
- : [];
157
+ const subs = this.subs[topic] ? this.subs[topic].filter((sub) => sub.subscriber !== publisher) : [];
163
158
 
164
159
  for (const sub of subs) {
165
160
  sub.emit(EVT_MESSAGE, structuredClone(message));
@@ -1,12 +1,10 @@
1
- import type {Constraint} from '@appium/types';
2
1
  import {util} from '@appium/support';
2
+ import type {Constraint} from '@appium/types';
3
+
3
4
  import {log} from './logger';
4
5
 
5
6
  export class Validator {
6
- private readonly _validators: Record<
7
- keyof Constraint,
8
- (value: any, options?: any, key?: string) => string | null
9
- > = {
7
+ private readonly _validators: Record<keyof Constraint, (value: any, options?: any, key?: string) => string | null> = {
10
8
  isString: (value: any, options?: any): string | null => {
11
9
  if (value === undefined || options == null) {
12
10
  return null;
@@ -108,8 +106,7 @@ export class Validator {
108
106
  }
109
107
  if (
110
108
  !options?.allowEmpty &&
111
- ((value !== undefined && util.isEmpty(value)) ||
112
- (typeof value === 'string' && !value.trim()))
109
+ ((value !== undefined && util.isEmpty(value)) || (typeof value === 'string' && !value.trim()))
113
110
  ) {
114
111
  return 'must not be empty or blank';
115
112
  }
@@ -117,10 +114,7 @@ export class Validator {
117
114
  },
118
115
  };
119
116
 
120
- validate(
121
- values: Record<string, any>,
122
- constraints: Record<string, Constraint>,
123
- ): Record<string, string[]> | null {
117
+ validate(values: Record<string, any>, constraints: Record<string, Constraint>): Record<string, string[]> | null {
124
118
  const result: Record<string, string[]> = {};
125
119
  for (const [key, constraint] of Object.entries(constraints)) {
126
120
  const value = values[key];
@@ -129,11 +123,7 @@ export class Validator {
129
123
  continue;
130
124
  }
131
125
 
132
- const validationError = this._validators[validatorName as keyof Constraint](
133
- value,
134
- options,
135
- key,
136
- );
126
+ const validationError = this._validators[validatorName as keyof Constraint](value, options, key);
137
127
  if (validationError == null) {
138
128
  continue;
139
129
  }