@appium/base-driver 10.0.0-beta.1 → 10.0.0-rc.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.
Files changed (46) hide show
  1. package/build/lib/basedriver/capabilities.d.ts +1 -1
  2. package/build/lib/basedriver/capabilities.d.ts.map +1 -1
  3. package/build/lib/basedriver/capabilities.js +1 -1
  4. package/build/lib/basedriver/capabilities.js.map +1 -1
  5. package/build/lib/basedriver/commands/execute.js.map +1 -1
  6. package/build/lib/basedriver/commands/timeout.js +8 -9
  7. package/build/lib/basedriver/commands/timeout.js.map +1 -1
  8. package/build/lib/basedriver/core.d.ts +2 -1
  9. package/build/lib/basedriver/core.d.ts.map +1 -1
  10. package/build/lib/basedriver/core.js +2 -2
  11. package/build/lib/basedriver/core.js.map +1 -1
  12. package/build/lib/basedriver/driver.d.ts +2 -3
  13. package/build/lib/basedriver/driver.d.ts.map +1 -1
  14. package/build/lib/basedriver/driver.js +2 -11
  15. package/build/lib/basedriver/driver.js.map +1 -1
  16. package/build/lib/basedriver/extension-core.js +1 -1
  17. package/build/lib/basedriver/extension-core.js.map +1 -1
  18. package/build/lib/basedriver/helpers.js +3 -3
  19. package/build/lib/basedriver/helpers.js.map +1 -1
  20. package/build/lib/express/server.js +2 -2
  21. package/build/lib/express/server.js.map +1 -1
  22. package/build/lib/jsonwp-proxy/protocol-converter.js +2 -2
  23. package/build/lib/jsonwp-proxy/protocol-converter.js.map +1 -1
  24. package/build/lib/jsonwp-proxy/proxy.js +1 -1
  25. package/build/lib/jsonwp-proxy/proxy.js.map +1 -1
  26. package/build/lib/protocol/protocol.d.ts +16 -24
  27. package/build/lib/protocol/protocol.d.ts.map +1 -1
  28. package/build/lib/protocol/protocol.js +94 -115
  29. package/build/lib/protocol/protocol.js.map +1 -1
  30. package/build/lib/protocol/routes.d.ts +3 -2
  31. package/build/lib/protocol/routes.d.ts.map +1 -1
  32. package/build/lib/protocol/routes.js +11 -9
  33. package/build/lib/protocol/routes.js.map +1 -1
  34. package/lib/basedriver/capabilities.ts +2 -2
  35. package/lib/basedriver/commands/execute.ts +1 -1
  36. package/lib/basedriver/commands/timeout.ts +8 -12
  37. package/lib/basedriver/core.ts +4 -2
  38. package/lib/basedriver/driver.ts +2 -14
  39. package/lib/basedriver/extension-core.ts +1 -1
  40. package/lib/basedriver/helpers.js +3 -3
  41. package/lib/express/server.js +2 -2
  42. package/lib/jsonwp-proxy/protocol-converter.js +2 -2
  43. package/lib/jsonwp-proxy/proxy.js +1 -1
  44. package/lib/protocol/{protocol.js → protocol.ts} +140 -141
  45. package/lib/protocol/routes.js +11 -9
  46. package/package.json +6 -6
@@ -16,6 +16,11 @@ import {MAX_LOG_BODY_LENGTH, PROTOCOLS, DEFAULT_BASE_PATH} from '../constants';
16
16
  import {isW3cCaps} from '../helpers/capabilities';
17
17
  import log from '../basedriver/logger';
18
18
  import { generateDriverLogPrefix } from '../basedriver/helpers';
19
+ import type { Core, AppiumLogger, PayloadParams, MethodMap, Driver, DriverMethodDef } from '@appium/types';
20
+ import type { BaseDriver } from '../basedriver/driver';
21
+ import type { Request, Response, Application } from 'express';
22
+ import type { MultidimensionalReadonlyArray } from 'type-fest';
23
+ import type { RouteConfiguringFunction } from '../express/server';
19
24
 
20
25
  export const CREATE_SESSION_COMMAND = 'createSession';
21
26
  export const DELETE_SESSION_COMMAND = 'deleteSession';
@@ -23,20 +28,14 @@ export const GET_STATUS_COMMAND = 'getStatus';
23
28
  export const LIST_DRIVER_COMMANDS_COMMAND = 'listCommands';
24
29
  export const LIST_DRIVER_EXTENSIONS_COMMAND = 'listExtensions';
25
30
 
26
- /** @type {Set<string>} */
27
- const deprecatedCommandsLogged = new Set();
31
+ export const deprecatedCommandsLogged: Set<string> = new Set();
28
32
 
29
- function determineProtocol(createSessionArgs) {
33
+ export function determineProtocol(createSessionArgs: any[]): keyof typeof PROTOCOLS {
30
34
  return _.some(createSessionArgs, isW3cCaps) ? PROTOCOLS.W3C : PROTOCOLS.MJSONWP;
31
35
  }
32
36
 
33
- /**
34
- *
35
- * @param {import('../basedriver/driver').BaseDriver} driver
36
- * @param {string | null} [sessionId=null]
37
- * @returns {keyof PROTOCOLS}
38
- */
39
- function extractProtocol(driver, sessionId = null) {
37
+
38
+ function extractProtocol(driver: Core<any>, sessionId: string | null = null): keyof typeof PROTOCOLS {
40
39
  const dstDriver = _.isFunction(driver.driverForSession) && sessionId
41
40
  ? driver.driverForSession(sessionId)
42
41
  : driver;
@@ -51,22 +50,11 @@ function extractProtocol(driver, sessionId = null) {
51
50
  return dstDriver?.protocol ?? PROTOCOLS.W3C;
52
51
  }
53
52
 
54
- /**
55
- *
56
- * @param {any} command
57
- * @returns {boolean}
58
- */
59
- function isSessionCommand(command) {
53
+ export function isSessionCommand(command: string): boolean {
60
54
  return !_.includes(NO_SESSION_ID_COMMANDS, command);
61
55
  }
62
56
 
63
- /**
64
- *
65
- * @param {import('@appium/types').ExternalDriver} driver
66
- * @param {string?} [sessionId]
67
- * @returns {import('@appium/types').AppiumLogger}
68
- */
69
- function getLogger(driver, sessionId = null) {
57
+ function getLogger(driver: Core<any>, sessionId: string | null = null): AppiumLogger {
70
58
  const dstDriver =
71
59
  sessionId && _.isFunction(driver.driverForSession)
72
60
  ? driver.driverForSession(sessionId) ?? driver
@@ -79,94 +67,116 @@ function getLogger(driver, sessionId = null) {
79
67
  return logger.getLogger(logPrefix);
80
68
  }
81
69
 
82
- function wrapParams(paramSets, jsonObj) {
70
+ function wrapParams<T>(paramSets, jsonObj: T): T | Record<string, T> {
83
71
  /* There are commands like performTouch which take a single parameter (primitive type or array).
84
72
  * Some drivers choose to pass this parameter as a value (eg. [action1, action2...]) while others to
85
73
  * wrap it within an object(eg' {gesture: [action1, action2...]}), which makes it hard to validate.
86
74
  * The wrap option in the spec enforce wrapping before validation, so that all params are wrapped at
87
75
  * the time they are validated and later passed to the commands.
88
76
  */
89
- let res = jsonObj;
90
- if (_.isArray(jsonObj) || !_.isObject(jsonObj)) {
91
- res = {};
92
- res[paramSets.wrap] = jsonObj;
93
- }
94
- return res;
77
+ return (_.isArray(jsonObj) || !_.isObject(jsonObj)) && paramSets.wrap
78
+ ? {[paramSets.wrap]: jsonObj}
79
+ : jsonObj;
95
80
  }
96
81
 
97
- function unwrapParams(paramSets, jsonObj) {
82
+ function unwrapParams<T>(paramSets: PayloadParams, jsonObj: T): T | Record<string, T> {
98
83
  /* There are commands like setNetworkConnection which send parameters wrapped inside a key such as
99
84
  * "parameters". This function unwraps them (eg. {"parameters": {"type": 1}} becomes {"type": 1}).
100
85
  */
101
- let res = jsonObj;
102
- if (_.isObject(jsonObj)) {
103
- // some clients, like ruby, don't wrap
104
- if (jsonObj[paramSets.unwrap]) {
105
- res = jsonObj[paramSets.unwrap];
106
- }
107
- }
108
- return res;
86
+ return _.isObject(jsonObj) && paramSets.unwrap && jsonObj[paramSets.unwrap]
87
+ ? jsonObj[paramSets.unwrap]
88
+ : jsonObj;
109
89
  }
110
90
 
111
- export function checkParams(paramSets, jsonObj, protocol) {
112
- let requiredParams = [];
113
- let optionalParams = [];
114
- let receivedParams = _.keys(jsonObj);
115
-
116
- if (paramSets) {
117
- if (paramSets.required) {
118
- // we might have an array of parameters,
119
- // or an array of arrays of parameters, so standardize
120
- if (!_.isArray(_.first(paramSets.required))) {
121
- requiredParams = [paramSets.required];
122
- } else {
123
- requiredParams = paramSets.required;
124
- }
125
- }
126
- // optional parameters are just an array
127
- if (paramSets.optional) {
128
- optionalParams = paramSets.optional;
129
- }
91
+ function hasMultipleRequiredParamSets(
92
+ required: ReadonlyArray<string> | MultidimensionalReadonlyArray<string, 2> | undefined
93
+ ): required is MultidimensionalReadonlyArray<string, 2> {
94
+ //@ts-expect-error Needed to convince lodash typechecks
95
+ return Boolean(required && _.isArray(_.first(required)));
96
+ }
130
97
 
131
- // If a function was provided as the 'validate' key, it will here be called with
132
- // jsonObj as the param. If it returns something falsy, verification will be
133
- // considered to have passed. If it returns something else, that will be the
134
- // argument to an error which is thrown to the user
135
- if (paramSets.validate) {
136
- let message = paramSets.validate(jsonObj, protocol);
137
- if (message) {
138
- throw new errors.InvalidArgumentError(message);
139
- }
140
- }
98
+ function pickKnownParams(args: Record<string, any>, unknownNames: string[]): Record<string, any> {
99
+ if (_.isEmpty(unknownNames)) {
100
+ return args;
101
+ }
102
+ log.info(`The following arguments are not known and will be ignored: ${unknownNames}`);
103
+ return _.pickBy(args, (v, k) => !unknownNames.includes(k));
104
+ }
105
+
106
+ export function checkParams(
107
+ paramSpec: PayloadParams,
108
+ args: Record<string, any>,
109
+ protocol?: keyof typeof PROTOCOLS
110
+ ): Record<string, any> {
111
+ let requiredParams: string[][] = [];
112
+ let optionalParams: string[] = [];
113
+ const actualParamNames: string[] = _.keys(args);
114
+
115
+ if (paramSpec.required) {
116
+ // we might have an array of parameters,
117
+ // or an array of arrays of parameters, so standardize
118
+ requiredParams = _.cloneDeep(
119
+ (hasMultipleRequiredParamSets(paramSpec.required)
120
+ ? paramSpec.required
121
+ : [paramSpec.required]
122
+ ) as string[][]
123
+ );
124
+ }
125
+ // optional parameters are just an array
126
+ if (paramSpec.optional) {
127
+ optionalParams = _.cloneDeep(paramSpec.optional as string[]);
141
128
  }
142
129
 
143
- // if we have no required parameters, all is well
144
- if (requiredParams.length === 0) {
145
- return;
130
+ // If a function was provided as the 'validate' key, it will here be called with
131
+ // args as the param. If it returns something falsy, verification will be
132
+ // considered to have passed. If it returns something else, that will be the
133
+ // argument to an error which is thrown to the user
134
+ if (paramSpec.validate) {
135
+ const message = paramSpec.validate(args, protocol ?? PROTOCOLS.W3C);
136
+ if (message) {
137
+ throw new errors.InvalidArgumentError(_.isString(message) ? message : undefined);
138
+ }
146
139
  }
147
140
 
148
141
  // some clients pass in the session id in the params
149
- if (optionalParams.indexOf('sessionId') === -1) {
142
+ if (!_.includes(optionalParams, 'sessionId')) {
150
143
  optionalParams.push('sessionId');
151
144
  }
152
-
153
145
  // some clients pass in an element id in the params
154
- if (optionalParams.indexOf('id') === -1) {
146
+ if (!_.includes(optionalParams, 'id')) {
155
147
  optionalParams.push('id');
156
148
  }
157
149
 
150
+ if (_.isEmpty(requiredParams)) {
151
+ // if we don't have any required parameters, then just filter out unknown ones
152
+ return pickKnownParams(args, _.difference(actualParamNames, optionalParams));
153
+ }
154
+
158
155
  // go through the required parameters and check against our arguments
159
- for (let params of requiredParams) {
160
- if (
161
- _.difference(receivedParams, params, optionalParams).length === 0 &&
162
- _.difference(params, receivedParams).length === 0
163
- ) {
164
- // we have a set of parameters that is correct
165
- // so short-circuit
166
- return;
156
+ let matchedReqParamSet: string[] = [];
157
+ for (const requiredParamsSet of requiredParams) {
158
+ if (!_.isArray(requiredParamsSet)) {
159
+ throw new Error(
160
+ `The required parameter set item ${JSON.stringify(requiredParamsSet)} ` +
161
+ `in ${JSON.stringify(paramSpec)} is not an array. ` +
162
+ `This is a bug in the method map definition.`
163
+ );
164
+ }
165
+ if (_.isEmpty(_.difference(requiredParamsSet, actualParamNames))) {
166
+ return pickKnownParams(
167
+ args,
168
+ _.difference(actualParamNames, requiredParamsSet, optionalParams)
169
+ );
170
+ }
171
+ if (!_.isEmpty(requiredParamsSet) && _.isEmpty(matchedReqParamSet)) {
172
+ matchedReqParamSet = requiredParamsSet;
167
173
  }
168
174
  }
169
- throw new BadParametersError(paramSets, receivedParams);
175
+ throw new BadParametersError({
176
+ ...paramSpec,
177
+ required: matchedReqParamSet,
178
+ optional: optionalParams,
179
+ }, actualParamNames);
170
180
  }
171
181
 
172
182
  /*
@@ -176,25 +186,25 @@ export function checkParams(paramSets, jsonObj, protocol) {
176
186
  * on handling parameters. This method returns an array of arguments which will
177
187
  * be applied to a command.
178
188
  */
179
- export function makeArgs(requestParams, jsonObj, payloadParams, protocol) {
189
+ export function makeArgs(requestParams: PayloadParams, jsonObj: any, payloadParams: PayloadParams): any[] {
180
190
  // We want to pass the "url" parameters to the commands in reverse order
181
191
  // since the command will sometimes want to ignore, say, the sessionId.
182
192
  // This has the effect of putting sessionId last, which means in JS we can
183
193
  // omit it from the function signature if we're not going to use it.
184
- let urlParams = _.keys(requestParams).reverse();
194
+ const urlParams = _.keys(requestParams).reverse();
185
195
 
186
196
  // In the simple case, the required parameters are a basic array in
187
197
  // payloadParams.required, so start there. It's possible that there are
188
198
  // multiple optional sets of required params, though, so handle that case
189
199
  // too.
190
200
  let requiredParams = payloadParams.required;
191
- if (_.isArray(_.first(payloadParams.required))) {
201
+ if (hasMultipleRequiredParamSets(payloadParams.required)) {
192
202
  // If there are optional sets of required params, then we will have an
193
203
  // array of arrays in payloadParams.required, so loop through each set and
194
204
  // pick the one that matches which JSON params were actually sent. We've
195
205
  // already been through validation so we're guaranteed to find a match.
196
- let keys = _.keys(jsonObj);
197
- for (let params of payloadParams.required) {
206
+ const keys = _.keys(jsonObj);
207
+ for (const params of payloadParams.required) {
198
208
  if (_.without(params, ...keys).length === 0) {
199
209
  requiredParams = params;
200
210
  break;
@@ -211,7 +221,7 @@ export function makeArgs(requestParams, jsonObj, payloadParams, protocol) {
211
221
  // which will be applied to the handling command. For example if it returns
212
222
  // [1, 2, 3], we will call `command(1, 2, 3, ...)` (url params are separate
213
223
  // from JSON params and get concatenated below).
214
- args = payloadParams.makeArgs(jsonObj, protocol);
224
+ args = payloadParams.makeArgs(jsonObj);
215
225
  } else {
216
226
  // Otherwise, collect all the required and optional params and flatten them
217
227
  // into an argument array
@@ -226,7 +236,7 @@ export function makeArgs(requestParams, jsonObj, payloadParams, protocol) {
226
236
  return args;
227
237
  }
228
238
 
229
- function validateExecuteMethodParams(params, paramSpec) {
239
+ export function validateExecuteMethodParams(params: any[], paramSpec?: PayloadParams): any[] {
230
240
  // the w3c protocol will give us an array of arguments to apply to a javascript function.
231
241
  // that's not what we're doing. we're going to look for a JS object as the first arg, so we
232
242
  // can perform validation on it. we'll ignore everything else.
@@ -236,40 +246,29 @@ function validateExecuteMethodParams(params, paramSpec) {
236
246
  `arguments to execute script and instead received: ${JSON.stringify(params)}`
237
247
  );
238
248
  }
239
- let args = params[0] ?? {};
249
+ const args: Record<string, any> = params[0] ?? {};
240
250
  if (!_.isPlainObject(args)) {
241
251
  throw new errors.InvalidArgumentError(
242
252
  `Did not receive an appropriate execute method parameters object. It needs to be ` +
243
253
  `deserializable as a plain JS object`
244
254
  );
245
255
  }
246
- if (!paramSpec) {
247
- paramSpec = {required: [], optional: []};
248
- } else {
249
- paramSpec.required ??= [];
250
- paramSpec.optional ??= [];
251
- const unknownNames = _.difference(_.keys(args), paramSpec.required, paramSpec.optional);
252
- if (!_.isEmpty(unknownNames)) {
253
- log.info(`The following script arguments are not known and will be ignored: ${unknownNames}`);
254
- args = _.pickBy(args, (v, k) => !unknownNames.includes(k));
255
- }
256
- checkParams(paramSpec, args, null);
257
- }
258
- const argsToApply = makeArgs({}, args, paramSpec, null);
259
- return argsToApply;
256
+ const specToUse = {
257
+ ...(paramSpec ?? {}),
258
+ required: paramSpec?.required ?? [],
259
+ optional: paramSpec?.optional ?? [],
260
+ };
261
+ const filteredArgs = checkParams(specToUse, args);
262
+ return makeArgs({}, filteredArgs, specToUse);
260
263
  }
261
264
 
262
- /**
263
- *
264
- * @param {import('@appium/types').Core} driver
265
- * @returns {import('../express/server').RouteConfiguringFunction}
266
- */
267
- function routeConfiguringFunction(driver) {
265
+
266
+ export function routeConfiguringFunction(driver: Core<any>): RouteConfiguringFunction {
268
267
  if (!driver.sessionExists) {
269
268
  throw new Error('Drivers must implement `sessionExists` property');
270
269
  }
271
270
 
272
- if (!(/** @type {any} */ (driver).executeCommand || /** @type {any} */ (driver).execute)) {
271
+ if (!((driver as any).executeCommand || (driver as any).execute)) {
273
272
  throw new Error('Drivers must implement `executeCommand` or `execute` method');
274
273
  }
275
274
 
@@ -280,10 +279,10 @@ function routeConfiguringFunction(driver) {
280
279
  // for example in determining proxy avoidance
281
280
  driver.basePath = basePath;
282
281
 
283
- const allMethods = {...METHOD_MAP, ...extraMethodMap};
284
-
282
+ const allMethods: MethodMap<Driver> = {...METHOD_MAP, ...extraMethodMap};
285
283
  for (const [path, methods] of _.toPairs(allMethods)) {
286
284
  for (const [method, spec] of _.toPairs(methods)) {
285
+ const isSessCommand = spec.command ? isSessionCommand(spec.command) : false;
287
286
  // set up the express route handler
288
287
  buildHandler(
289
288
  app,
@@ -291,29 +290,36 @@ function routeConfiguringFunction(driver) {
291
290
  `${basePath}${path}`,
292
291
  spec,
293
292
  driver,
294
- isSessionCommand(/** @type {import('@appium/types').DriverMethodDef} */ (spec).command)
293
+ isSessCommand
295
294
  );
296
295
  }
297
296
  }
298
297
  };
299
298
  }
300
299
 
301
- function buildHandler(app, method, path, spec, driver, isSessCmd) {
302
- let asyncHandler = async (/** @type {import('express').Request} */ req, /** @type {import('express').Response} */ res) => {
300
+ function buildHandler(
301
+ app: Application,
302
+ method: string,
303
+ path: string,
304
+ spec: DriverMethodDef<Driver>,
305
+ driver: Core<any>,
306
+ isSessCmd: boolean
307
+ ): void {
308
+ const asyncHandler = async (req: Request, res: Response) => {
303
309
  let jsonObj = req.body;
304
- let httpResBody = /** @type {any} */ ({});
310
+ let httpResBody = {} as any;
305
311
  let httpStatus = 200;
306
- let newSessionId;
312
+ let newSessionId: string | undefined;
307
313
  let currentProtocol = extractProtocol(driver, req.params.sessionId);
308
314
 
309
315
  try {
310
316
  // if the route accessed is deprecated, log a warning
311
- if (spec.deprecated && !deprecatedCommandsLogged.has(spec.command)) {
317
+ if (spec.deprecated && spec.command && !deprecatedCommandsLogged.has(spec.command)) {
312
318
  deprecatedCommandsLogged.add(spec.command);
313
319
  getLogger(driver, req.params.sessionId).warn(
314
- `Command '${spec.command}' has been deprecated and will be removed in a future ` +
315
- `version of Appium or your driver/plugin. Please use a different method or contact the ` +
316
- `driver/plugin author to add explicit support for the command before it is removed`
320
+ `The ${method} ${path} endpoint has been deprecated and will be removed in a future ` +
321
+ `version of Appium or your driver/plugin. Please use a different endpoint or contact the ` +
322
+ `driver/plugin author to add explicit support for the endpoint before it is removed`
317
323
  );
318
324
  }
319
325
 
@@ -332,12 +338,12 @@ function buildHandler(app, method, path, spec, driver, isSessCmd) {
332
338
  // commands and generally would not want that command to be proxied instead of handled by the
333
339
  // plugin)
334
340
  let didPluginOverrideProxy = false;
335
- if (isSessCmd && !spec.neverProxy && driverShouldDoJwpProxy(driver, req, spec.command)) {
341
+ if (isSessCmd && !spec.neverProxy && spec.command && driverShouldDoJwpProxy(driver, req, spec.command)) {
336
342
  if (
337
- !driver.pluginsToHandleCmd ||
343
+ !('pluginsToHandleCmd' in driver) || !_.isFunction(driver.pluginsToHandleCmd) ||
338
344
  driver.pluginsToHandleCmd(spec.command, req.params.sessionId).length === 0
339
345
  ) {
340
- await doJwpProxy(driver, req, res);
346
+ await doJwpProxy(driver as BaseDriver<any>, req, res);
341
347
  return;
342
348
  }
343
349
  getLogger(driver, req.params.sessionId).debug(
@@ -373,12 +379,14 @@ function buildHandler(app, method, path, spec, driver, isSessCmd) {
373
379
  }
374
380
 
375
381
  // ensure that the json payload conforms to the spec
376
- checkParams(spec.payloadParams, jsonObj, currentProtocol);
382
+ if (spec.payloadParams) {
383
+ checkParams(spec.payloadParams, jsonObj, currentProtocol);
384
+ }
377
385
 
378
386
  // turn the command and json payload into an argument list for
379
387
  // the driver methods
380
- let args = makeArgs(req.params, jsonObj, spec.payloadParams || {}, currentProtocol);
381
- let driverRes;
388
+ const args = makeArgs(req.params, jsonObj, spec.payloadParams || {});
389
+ let driverRes: any;
382
390
  // validate command args according to MJSONWP
383
391
  if (validators[spec.command]) {
384
392
  validators[spec.command](...args);
@@ -398,7 +406,7 @@ function buildHandler(app, method, path, spec, driver, isSessCmd) {
398
406
  args.push({reqForProxy: req});
399
407
  }
400
408
 
401
- driverRes = await driver.executeCommand(spec.command, ...args);
409
+ driverRes = await (driver as BaseDriver<any>).executeCommand(spec.command, ...args);
402
410
 
403
411
  // Get the protocol after executeCommand
404
412
  currentProtocol = extractProtocol(driver, req.params.sessionId) || currentProtocol;
@@ -517,7 +525,7 @@ function buildHandler(app, method, path, spec, driver, isSessCmd) {
517
525
  });
518
526
  }
519
527
 
520
- function driverShouldDoJwpProxy(driver, req, command) {
528
+ export function driverShouldDoJwpProxy(driver: Core<any>, req: import('express').Request, command: string): boolean {
521
529
  // drivers need to explicitly say when the proxy is active
522
530
  if (!driver.proxyActive(req.params.sessionId)) {
523
531
  return false;
@@ -538,7 +546,7 @@ function driverShouldDoJwpProxy(driver, req, command) {
538
546
  return true;
539
547
  }
540
548
 
541
- async function doJwpProxy(driver, req, res) {
549
+ async function doJwpProxy(driver: BaseDriver<any>, req: Request, res: Response): Promise<void> {
542
550
  getLogger(driver, req.params.sessionId).info(
543
551
  'Driver proxy active, passing request on via HTTP proxy'
544
552
  );
@@ -557,12 +565,3 @@ async function doJwpProxy(driver, req, res) {
557
565
  }
558
566
  }
559
567
  }
560
-
561
- export {
562
- routeConfiguringFunction,
563
- isSessionCommand,
564
- driverShouldDoJwpProxy,
565
- determineProtocol,
566
- deprecatedCommandsLogged,
567
- validateExecuteMethodParams,
568
- };
@@ -42,12 +42,7 @@ export const METHOD_MAP = /** @type {const} */ ({
42
42
  POST: {
43
43
  command: 'timeouts',
44
44
  payloadParams: {
45
- validate: ({script, pageLoad, implicit}) => {
46
- if ([script, pageLoad, implicit].every(_.isNil)) {
47
- return 'W3C protocol expects any of script, pageLoad or implicit to be set';
48
- }
49
- },
50
- optional: ['script', 'pageLoad', 'implicit'],
45
+ optional: ['type', 'ms', 'script', 'pageLoad', 'implicit'],
51
46
  },
52
47
  },
53
48
  },
@@ -274,8 +269,15 @@ export const METHOD_MAP = /** @type {const} */ ({
274
269
  POST: {command: 'setRotation', payloadParams: {required: ['x', 'y', 'z']}},
275
270
  },
276
271
  '/session/:sessionId/location': {
277
- GET: {command: 'getGeoLocation'},
278
- POST: {command: 'setGeoLocation', payloadParams: {required: ['location']}},
272
+ GET: {
273
+ command: 'getGeoLocation',
274
+ deprecated: true,
275
+ },
276
+ POST: {
277
+ command: 'setGeoLocation',
278
+ payloadParams: {required: ['location']},
279
+ deprecated: true,
280
+ },
279
281
  },
280
282
  '/session/:sessionId/orientation': {
281
283
  GET: {command: 'getOrientation'},
@@ -411,7 +413,7 @@ export const METHOD_MAP = /** @type {const} */ ({
411
413
  // #endregion
412
414
 
413
415
  //
414
- // 3rd party vendor/protcol support
416
+ // 3rd party vendor/protocol support
415
417
  //
416
418
  // #region Selenium/Chromium browsers
417
419
  '/session/:sessionId/se/log': {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appium/base-driver",
3
- "version": "10.0.0-beta.1",
3
+ "version": "10.0.0-rc.1",
4
4
  "description": "Base driver class for Appium drivers",
5
5
  "keywords": [
6
6
  "automation",
@@ -44,8 +44,8 @@
44
44
  "test:types": "tsd"
45
45
  },
46
46
  "dependencies": {
47
- "@appium/support": "^6.1.0",
48
- "@appium/types": "^0.25.3",
47
+ "@appium/support": "^6.1.1",
48
+ "@appium/types": "^0.26.0",
49
49
  "@colors/colors": "1.6.0",
50
50
  "async-lock": "1.4.1",
51
51
  "asyncbox": "3.0.0",
@@ -62,20 +62,20 @@
62
62
  "path-to-regexp": "8.2.0",
63
63
  "serve-favicon": "2.5.0",
64
64
  "source-map-support": "0.5.21",
65
- "type-fest": "4.40.0"
65
+ "type-fest": "4.41.0"
66
66
  },
67
67
  "optionalDependencies": {
68
68
  "spdy": "4.0.2"
69
69
  },
70
70
  "engines": {
71
- "node": "^20.9.0 || >=22.11.0",
71
+ "node": "^20.19.0 || >=22.12.0",
72
72
  "npm": ">=10"
73
73
  },
74
74
  "publishConfig": {
75
75
  "access": "public",
76
76
  "tag": "beta"
77
77
  },
78
- "gitHead": "9bb5f3f706c5ae1c1ed600a8d0c4e9536936c5ff",
78
+ "gitHead": "92680d9b4a95da18a812187773240a51b52f5f29",
79
79
  "tsd": {
80
80
  "directory": "test/types"
81
81
  }