@appium/base-driver 8.5.2 → 8.5.5

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 (141) hide show
  1. package/build/lib/basedriver/capabilities.d.ts.map +1 -1
  2. package/build/lib/basedriver/capabilities.js +1 -1
  3. package/build/lib/basedriver/commands/event.js +1 -1
  4. package/build/lib/basedriver/commands/find.d.ts.map +1 -1
  5. package/build/lib/basedriver/commands/find.js +1 -1
  6. package/build/lib/basedriver/commands/index.js +1 -1
  7. package/build/lib/basedriver/commands/log.d.ts.map +1 -1
  8. package/build/lib/basedriver/commands/log.js +1 -1
  9. package/build/lib/basedriver/commands/session.js +1 -1
  10. package/build/lib/basedriver/commands/settings.d.ts.map +1 -1
  11. package/build/lib/basedriver/commands/settings.js +1 -1
  12. package/build/lib/basedriver/commands/timeout.d.ts.map +1 -1
  13. package/build/lib/basedriver/commands/timeout.js +1 -1
  14. package/build/lib/basedriver/core.d.ts +120 -139
  15. package/build/lib/basedriver/core.d.ts.map +1 -1
  16. package/build/lib/basedriver/core.js +1 -49
  17. package/build/lib/basedriver/desired-caps.d.ts +5 -2
  18. package/build/lib/basedriver/desired-caps.d.ts.map +1 -1
  19. package/build/lib/basedriver/desired-caps.js +14 -18
  20. package/build/lib/basedriver/device-settings.d.ts +9 -9
  21. package/build/lib/basedriver/device-settings.d.ts.map +1 -1
  22. package/build/lib/basedriver/device-settings.js +4 -4
  23. package/build/lib/basedriver/driver.d.ts +43 -38
  24. package/build/lib/basedriver/driver.d.ts.map +1 -1
  25. package/build/lib/basedriver/driver.js +58 -11
  26. package/build/lib/basedriver/helpers.d.ts +8 -3
  27. package/build/lib/basedriver/helpers.d.ts.map +1 -1
  28. package/build/lib/basedriver/helpers.js +4 -6
  29. package/build/lib/basedriver/logger.d.ts +1 -1
  30. package/build/lib/basedriver/logger.d.ts.map +1 -1
  31. package/build/lib/basedriver/logger.js +1 -1
  32. package/build/lib/constants.js +1 -1
  33. package/build/lib/express/crash.d.ts.map +1 -1
  34. package/build/lib/express/crash.js +1 -1
  35. package/build/lib/express/express-logging.d.ts.map +1 -1
  36. package/build/lib/express/express-logging.js +1 -1
  37. package/build/lib/express/idempotency.js +1 -1
  38. package/build/lib/express/logger.d.ts +1 -1
  39. package/build/lib/express/logger.d.ts.map +1 -1
  40. package/build/lib/express/logger.js +1 -1
  41. package/build/lib/express/middleware.d.ts.map +1 -1
  42. package/build/lib/express/middleware.js +1 -1
  43. package/build/lib/express/server.d.ts +21 -0
  44. package/build/lib/express/server.d.ts.map +1 -1
  45. package/build/lib/express/server.js +4 -9
  46. package/build/lib/express/static.d.ts.map +1 -1
  47. package/build/lib/express/static.js +2 -2
  48. package/build/lib/express/websocket.d.ts +14 -11
  49. package/build/lib/express/websocket.d.ts.map +1 -1
  50. package/build/lib/express/websocket.js +2 -2
  51. package/build/lib/helpers/capabilities.d.ts.map +1 -1
  52. package/build/lib/helpers/capabilities.js +1 -1
  53. package/build/lib/index.d.ts +2 -1
  54. package/build/lib/index.js +7 -1
  55. package/build/lib/jsonwp-proxy/protocol-converter.d.ts.map +1 -1
  56. package/build/lib/jsonwp-proxy/protocol-converter.js +2 -2
  57. package/build/lib/jsonwp-proxy/proxy.d.ts +30 -5
  58. package/build/lib/jsonwp-proxy/proxy.d.ts.map +1 -1
  59. package/build/lib/jsonwp-proxy/proxy.js +20 -4
  60. package/build/lib/jsonwp-status/status.d.ts.map +1 -1
  61. package/build/lib/jsonwp-status/status.js +2 -2
  62. package/build/lib/protocol/errors.d.ts +17 -8
  63. package/build/lib/protocol/errors.d.ts.map +1 -1
  64. package/build/lib/protocol/errors.js +9 -5
  65. package/build/lib/protocol/helpers.js +1 -1
  66. package/build/lib/protocol/index.js +1 -1
  67. package/build/lib/protocol/protocol.d.ts.map +1 -1
  68. package/build/lib/protocol/protocol.js +1 -1
  69. package/build/lib/protocol/routes.d.ts +17 -3
  70. package/build/lib/protocol/routes.d.ts.map +1 -1
  71. package/build/lib/protocol/routes.js +1 -1
  72. package/build/lib/protocol/validators.js +1 -1
  73. package/build/test/basedriver/driver-e2e-tests.js +1 -1
  74. package/build/test/basedriver/driver-tests.js +1 -1
  75. package/build/test/basedriver/index.js +1 -1
  76. package/build/test/e2e/basedriver/driver.e2e.spec.js +1 -1
  77. package/build/test/e2e/basedriver/helpers.e2e.spec.js +1 -1
  78. package/build/test/e2e/basedriver/websockets.e2e.spec.js +1 -1
  79. package/build/test/e2e/express/server.e2e.spec.js +1 -1
  80. package/build/test/e2e/jsonwp-proxy/proxy.e2e.spec.js +1 -1
  81. package/build/test/e2e/protocol/fake-driver.js +1 -1
  82. package/build/test/e2e/protocol/helpers.js +1 -1
  83. package/build/test/e2e/protocol/protocol.e2e.spec.js +13 -13
  84. package/build/test/helpers.js +1 -1
  85. package/build/test/unit/basedriver/capabilities.spec.js +12 -12
  86. package/build/test/unit/basedriver/capability.spec.js +15 -15
  87. package/build/test/unit/basedriver/commands/event.spec.js +1 -1
  88. package/build/test/unit/basedriver/commands/log.spec.js +1 -1
  89. package/build/test/unit/basedriver/device-settings.spec.js +1 -1
  90. package/build/test/unit/basedriver/driver.spec.js +1 -1
  91. package/build/test/unit/basedriver/helpers.spec.js +33 -33
  92. package/build/test/unit/basedriver/timeout.spec.js +1 -1
  93. package/build/test/unit/express/server.spec.js +1 -1
  94. package/build/test/unit/express/static.spec.js +2 -2
  95. package/build/test/unit/jsonwp-proxy/mock-request.js +1 -1
  96. package/build/test/unit/jsonwp-proxy/protocol-converter.spec.js +1 -1
  97. package/build/test/unit/jsonwp-proxy/proxy.spec.js +2 -2
  98. package/build/test/unit/jsonwp-proxy/url.spec.js +1 -1
  99. package/build/test/unit/jsonwp-status/status.spec.js +1 -1
  100. package/build/test/unit/protocol/errors.spec.js +1 -1
  101. package/build/test/unit/protocol/routes.spec.js +1 -1
  102. package/build/test/unit/protocol/validator.spec.js +1 -1
  103. package/build/tsconfig.tsbuildinfo +1 -1
  104. package/lib/basedriver/capabilities.js +95 -47
  105. package/lib/basedriver/commands/event.js +4 -4
  106. package/lib/basedriver/commands/find.js +12 -26
  107. package/lib/basedriver/commands/index.js +7 -7
  108. package/lib/basedriver/commands/log.js +5 -7
  109. package/lib/basedriver/commands/session.js +3 -3
  110. package/lib/basedriver/commands/settings.js +3 -5
  111. package/lib/basedriver/commands/timeout.js +18 -23
  112. package/lib/basedriver/core.js +150 -229
  113. package/lib/basedriver/desired-caps.js +30 -29
  114. package/lib/basedriver/device-settings.js +21 -20
  115. package/lib/basedriver/driver.js +131 -96
  116. package/lib/basedriver/helpers.js +124 -81
  117. package/lib/basedriver/logger.js +1 -1
  118. package/lib/constants.js +2 -6
  119. package/lib/express/crash.js +4 -6
  120. package/lib/express/express-logging.js +26 -24
  121. package/lib/express/idempotency.js +16 -16
  122. package/lib/express/logger.js +1 -1
  123. package/lib/express/middleware.js +49 -33
  124. package/lib/express/server.js +68 -44
  125. package/lib/express/static.js +11 -12
  126. package/lib/express/websocket.js +26 -16
  127. package/lib/helpers/capabilities.js +11 -16
  128. package/lib/index.js +50 -33
  129. package/lib/jsonwp-proxy/protocol-converter.js +85 -69
  130. package/lib/jsonwp-proxy/proxy.js +116 -53
  131. package/lib/jsonwp-status/status.js +36 -29
  132. package/lib/protocol/errors.js +469 -292
  133. package/lib/protocol/helpers.js +5 -8
  134. package/lib/protocol/index.js +22 -15
  135. package/lib/protocol/protocol.js +103 -55
  136. package/lib/protocol/routes.js +430 -273
  137. package/lib/protocol/validators.js +5 -5
  138. package/package.json +9 -11
  139. package/test/basedriver/driver-e2e-tests.js +92 -66
  140. package/test/basedriver/driver-tests.js +90 -33
  141. package/test/basedriver/index.js +1 -1
@@ -1,7 +1,12 @@
1
1
  import log from './logger';
2
- import validator from 'validate.js';
2
+ import _validator from 'validate.js';
3
3
  import B from 'bluebird';
4
4
 
5
+ const validator =
6
+ /** @type {import('validate.js').ValidateJS & {promise: typeof import('bluebird')}} */ (
7
+ _validator
8
+ );
9
+
5
10
  /** @type {import('@appium/types').Constraints} */
6
11
  let desiredCapabilityConstraints = {
7
12
  platformName: {
@@ -9,53 +14,50 @@ let desiredCapabilityConstraints = {
9
14
  isString: true,
10
15
  },
11
16
  deviceName: {
12
- isString: true
17
+ isString: true,
13
18
  },
14
19
  platformVersion: {
15
- isString: true
20
+ isString: true,
16
21
  },
17
22
  newCommandTimeout: {
18
- isNumber: true
23
+ isNumber: true,
19
24
  },
20
25
  automationName: {
21
- isString: true
26
+ isString: true,
22
27
  },
23
28
  autoLaunch: {
24
- isBoolean: true
29
+ isBoolean: true,
25
30
  },
26
31
  udid: {
27
- isString: true
32
+ isString: true,
28
33
  },
29
34
  orientation: {
30
- inclusion: [
31
- 'LANDSCAPE',
32
- 'PORTRAIT'
33
- ]
35
+ inclusion: ['LANDSCAPE', 'PORTRAIT'],
34
36
  },
35
37
  autoWebview: {
36
- isBoolean: true
38
+ isBoolean: true,
37
39
  },
38
40
  noReset: {
39
- isBoolean: true
41
+ isBoolean: true,
40
42
  },
41
43
  fullReset: {
42
- isBoolean: true
44
+ isBoolean: true,
43
45
  },
44
46
  language: {
45
- isString: true
47
+ isString: true,
46
48
  },
47
49
  locale: {
48
- isString: true
50
+ isString: true,
49
51
  },
50
52
  eventTimings: {
51
- isBoolean: true
53
+ isBoolean: true,
52
54
  },
53
55
  printPageSourceOnFindFailure: {
54
- isBoolean: true
56
+ isBoolean: true,
55
57
  },
56
58
  };
57
59
 
58
- validator.validators.isString = function isString (value) {
60
+ validator.validators.isString = function isString(value) {
59
61
  if (typeof value === 'string') {
60
62
  return null;
61
63
  }
@@ -66,7 +68,7 @@ validator.validators.isString = function isString (value) {
66
68
 
67
69
  return 'must be of type string';
68
70
  };
69
- validator.validators.isNumber = function isNumber (value) {
71
+ validator.validators.isNumber = function isNumber(value) {
70
72
  if (typeof value === 'number') {
71
73
  return null;
72
74
  }
@@ -76,14 +78,14 @@ validator.validators.isNumber = function isNumber (value) {
76
78
  }
77
79
 
78
80
  // allow a string value
79
- if (typeof value === 'string' && !isNaN(value)) {
81
+ if (typeof value === 'string' && !isNaN(Number(value))) {
80
82
  log.warn('Number capability passed in as string. Functionality may be compromised.');
81
83
  return null;
82
84
  }
83
85
 
84
86
  return 'must be of type number';
85
87
  };
86
- validator.validators.isBoolean = function isBoolean (value) {
88
+ validator.validators.isBoolean = function isBoolean(value) {
87
89
  if (typeof value === 'boolean') {
88
90
  return null;
89
91
  }
@@ -99,7 +101,7 @@ validator.validators.isBoolean = function isBoolean (value) {
99
101
 
100
102
  return 'must be of type boolean';
101
103
  };
102
- validator.validators.isObject = function isObject (value) {
104
+ validator.validators.isObject = function isObject(value) {
103
105
  if (typeof value === 'object') {
104
106
  return null;
105
107
  }
@@ -110,7 +112,7 @@ validator.validators.isObject = function isObject (value) {
110
112
 
111
113
  return 'must be of type object';
112
114
  };
113
- validator.validators.isArray = function isArray (value) {
115
+ validator.validators.isArray = function isArray(value) {
114
116
  if (Array.isArray(value)) {
115
117
  return null;
116
118
  }
@@ -121,13 +123,13 @@ validator.validators.isArray = function isArray (value) {
121
123
 
122
124
  return 'must be of type array';
123
125
  };
124
- validator.validators.deprecated = function deprecated (value, options, key) {
126
+ validator.validators.deprecated = function deprecated(value, options, key) {
125
127
  if (options) {
126
128
  log.warn(`${key} is a deprecated capability`);
127
129
  }
128
130
  return null;
129
131
  };
130
- validator.validators.inclusionCaseInsensitive = function inclusionCaseInsensitive (value, options) {
132
+ validator.validators.inclusionCaseInsensitive = function inclusionCaseInsensitive(value, options) {
131
133
  if (typeof value === 'undefined') {
132
134
  return null;
133
135
  } else if (typeof value !== 'string') {
@@ -142,9 +144,8 @@ validator.validators.inclusionCaseInsensitive = function inclusionCaseInsensitiv
142
144
  };
143
145
 
144
146
  validator.promise = B;
145
- validator.prettify = function prettify (val) {
147
+ validator.prettify = function prettify(val) {
146
148
  return val;
147
149
  };
148
150
 
149
-
150
- export { desiredCapabilityConstraints, validator };
151
+ export {desiredCapabilityConstraints, validator};
@@ -1,9 +1,7 @@
1
- // @ts-check
2
-
3
1
  import _ from 'lodash';
4
2
  import log from './logger';
5
- import { node, util } from '@appium/support';
6
- import { errors } from '../protocol/errors';
3
+ import {node, util} from '@appium/support';
4
+ import {errors} from '../protocol/errors';
7
5
 
8
6
  /**
9
7
  * Maximum size (in bytes) of a given driver's settings object (which is internal to {@linkcode DriverSettings}).
@@ -11,14 +9,13 @@ import { errors } from '../protocol/errors';
11
9
  export const MAX_SETTINGS_SIZE = 20 * 1024 * 1024; // 20 MB
12
10
 
13
11
  /**
14
- * @template {Record<string,unknown>} T
12
+ * @template T
15
13
  * @implements {IDeviceSettings<T>}
16
14
  */
17
15
  class DeviceSettings {
18
-
19
16
  /**
20
17
  * @protected
21
- * @type {T}
18
+ * @type {Record<string,T>}
22
19
  */
23
20
  _settings;
24
21
 
@@ -30,30 +27,34 @@ class DeviceSettings {
30
27
 
31
28
  /**
32
29
  * Creates a _shallow copy_ of the `defaultSettings` parameter!
33
- * @param {T} [defaultSettings]
30
+ * @param {Record<string,T>} [defaultSettings]
34
31
  * @param {import('@appium/types').SettingsUpdateListener<T>} [onSettingsUpdate]
35
32
  */
36
- constructor (defaultSettings, onSettingsUpdate) {
37
- this._settings = /** @type {T} */({...(defaultSettings ?? {})});
38
- this._onSettingsUpdate = onSettingsUpdate ?? (async () => {});
33
+ constructor(defaultSettings = {}, onSettingsUpdate = async () => {}) {
34
+ this._settings = {...defaultSettings};
35
+ this._onSettingsUpdate = onSettingsUpdate;
39
36
  }
40
37
 
41
38
  /**
42
39
  * calls updateSettings from implementing driver every time a setting is changed.
43
- * @param {T} newSettings
40
+ * @param {Record<string,T>} newSettings
44
41
  */
45
- async update (newSettings) {
42
+ async update(newSettings) {
46
43
  if (!_.isPlainObject(newSettings)) {
47
- throw new errors.InvalidArgumentError(`Settings update should be called with valid JSON. Got ` +
48
- `${JSON.stringify(newSettings)} instead`);
44
+ throw new errors.InvalidArgumentError(
45
+ `Settings update should be called with valid JSON. Got ` +
46
+ `${JSON.stringify(newSettings)} instead`
47
+ );
49
48
  }
50
49
 
51
50
  if (node.getObjectSize({...this._settings, ...newSettings}) >= MAX_SETTINGS_SIZE) {
52
- throw new errors.InvalidArgumentError(`New settings cannot be applied, because the overall ` +
53
- `object size exceeds the allowed limit of ${util.toReadableSizeString(MAX_SETTINGS_SIZE)}`);
51
+ throw new errors.InvalidArgumentError(
52
+ `New settings cannot be applied, because the overall ` +
53
+ `object size exceeds the allowed limit of ${util.toReadableSizeString(MAX_SETTINGS_SIZE)}`
54
+ );
54
55
  }
55
56
 
56
- const props = /** @type {(keyof T & string)[]} */(_.keys(newSettings));
57
+ const props = /** @type {(keyof T & string)[]} */ (_.keys(newSettings));
57
58
  for (const prop of props) {
58
59
  if (!_.isUndefined(this._settings[prop])) {
59
60
  if (this._settings[prop] === newSettings[prop]) {
@@ -66,13 +67,13 @@ class DeviceSettings {
66
67
  }
67
68
  }
68
69
 
69
- getSettings () {
70
+ getSettings() {
70
71
  return this._settings;
71
72
  }
72
73
  }
73
74
 
74
75
  export default DeviceSettings;
75
- export { DeviceSettings };
76
+ export {DeviceSettings};
76
77
 
77
78
  /**
78
79
  * @template T
@@ -1,21 +1,22 @@
1
- // @ts-check
2
1
  /* eslint-disable require-await */
3
2
  /* eslint-disable no-unused-vars */
4
3
 
5
- import { DriverCore } from './core';
6
- import { util } from '@appium/support';
7
- import B from 'bluebird';
8
- import _ from 'lodash';
9
- import { fixCaps, isW3cCaps } from '../helpers/capabilities';
10
- import { DELETE_SESSION_COMMAND, determineProtocol, errors } from '../protocol';
11
4
  import {
5
+ validateCaps,
12
6
  APPIUM_OPTS_CAP,
13
7
  PREFIXED_APPIUM_OPTS_CAP,
14
8
  processCapabilities,
15
- promoteAppiumOptions
9
+ promoteAppiumOptions,
16
10
  } from './capabilities';
17
- import { createBaseDriverClass } from './commands';
11
+ import {DriverCore} from './core';
12
+ import {util} from '@appium/support';
13
+ import B from 'bluebird';
14
+ import _ from 'lodash';
15
+ import {fixCaps, isW3cCaps} from '../helpers/capabilities';
16
+ import {DELETE_SESSION_COMMAND, determineProtocol, errors} from '../protocol';
17
+ import {createBaseDriverClass} from './commands';
18
18
  import helpers from './helpers';
19
+ import {desiredCapabilityConstraints} from './desired-caps';
19
20
 
20
21
  const EVENT_SESSION_INIT = 'newSessionRequested';
21
22
  const EVENT_SESSION_START = 'newSessionStarted';
@@ -23,11 +24,11 @@ const EVENT_SESSION_QUIT_START = 'quitSessionRequested';
23
24
  const EVENT_SESSION_QUIT_DONE = 'quitSessionFinished';
24
25
  const ON_UNEXPECTED_SHUTDOWN_EVENT = 'onUnexpectedShutdown';
25
26
 
26
-
27
27
  /**
28
28
  * @implements {SessionHandler}
29
29
  */
30
30
  export class BaseDriverCore extends DriverCore {
31
+ _constraints = _.cloneDeep(desiredCapabilityConstraints);
31
32
 
32
33
  /** @type {Record<string,any>|undefined} */
33
34
  cliArgs;
@@ -37,11 +38,11 @@ export class BaseDriverCore extends DriverCore {
37
38
  // and ensuring that we execute commands one at a time. This method is called
38
39
  // by MJSONWP's express router.
39
40
  /**
40
- * @param {string} cmd
41
- * @param {...any[]} args
42
- * @returns {Promise<any>}
43
- */
44
- async executeCommand (cmd, ...args) {
41
+ * @param {string} cmd
42
+ * @param {...any} args
43
+ * @returns {Promise<any>}
44
+ */
45
+ async executeCommand(cmd, ...args) {
45
46
  // get start time for this command, and log in special cases
46
47
  let startTime = Date.now();
47
48
 
@@ -58,9 +59,7 @@ export class BaseDriverCore extends DriverCore {
58
59
  await this.clearNewCommandTimeout();
59
60
 
60
61
  if (this.shutdownUnexpectedly) {
61
- throw new errors.NoSuchDriverError(
62
- 'The driver was unexpectedly shut down!',
63
- );
62
+ throw new errors.NoSuchDriverError('The driver was unexpectedly shut down!');
64
63
  }
65
64
 
66
65
  // If we don't have this command, it must not be implemented
@@ -74,17 +73,14 @@ export class BaseDriverCore extends DriverCore {
74
73
  this[cmd](...args),
75
74
  new B((resolve, reject) => {
76
75
  unexpectedShutdownListener = reject;
77
- this.eventEmitter.on(
78
- ON_UNEXPECTED_SHUTDOWN_EVENT,
79
- unexpectedShutdownListener,
80
- );
76
+ this.eventEmitter.on(ON_UNEXPECTED_SHUTDOWN_EVENT, unexpectedShutdownListener);
81
77
  }),
82
78
  ]).finally(() => {
83
79
  if (unexpectedShutdownListener) {
84
80
  // This is needed to prevent memory leaks
85
81
  this.eventEmitter.removeListener(
86
- ON_UNEXPECTED_SHUTDOWN_EVENT,
87
- unexpectedShutdownListener,
82
+ ON_UNEXPECTED_SHUTDOWN_EVENT,
83
+ unexpectedShutdownListener
88
84
  );
89
85
  unexpectedShutdownListener = null;
90
86
  }
@@ -117,13 +113,11 @@ export class BaseDriverCore extends DriverCore {
117
113
  }
118
114
 
119
115
  /**
120
- *
121
- * @param {Error} err
122
- */
123
- async startUnexpectedShutdown (
124
- err = new errors.NoSuchDriverError(
125
- 'The driver was unexpectedly shut down!',
126
- ),
116
+ *
117
+ * @param {Error} err
118
+ */
119
+ async startUnexpectedShutdown(
120
+ err = new errors.NoSuchDriverError('The driver was unexpectedly shut down!')
127
121
  ) {
128
122
  this.eventEmitter.emit(ON_UNEXPECTED_SHUTDOWN_EVENT, err); // allow others to listen for this
129
123
  this.shutdownUnexpectedly = true;
@@ -136,7 +130,7 @@ export class BaseDriverCore extends DriverCore {
136
130
  }
137
131
  }
138
132
 
139
- async startNewCommandTimeout () {
133
+ async startNewCommandTimeout() {
140
134
  // make sure there are no rogue timeouts
141
135
  await this.clearNewCommandTimeout();
142
136
 
@@ -146,7 +140,7 @@ export class BaseDriverCore extends DriverCore {
146
140
  this.noCommandTimer = setTimeout(async () => {
147
141
  this.log.warn(
148
142
  `Shutting down because we waited ` +
149
- `${this.newCommandTimeoutMs / 1000.0} seconds for a command`,
143
+ `${this.newCommandTimeoutMs / 1000.0} seconds for a command`
150
144
  );
151
145
  const errorMessage =
152
146
  `New Command Timeout of ` +
@@ -164,7 +158,7 @@ export class BaseDriverCore extends DriverCore {
164
158
  * @param {number} port
165
159
  * @param {string} path
166
160
  */
167
- assignServer (server, host, port, path) {
161
+ assignServer(server, host, port, path) {
168
162
  this.server = server;
169
163
  this.serverHost = host;
170
164
  this.serverPort = port;
@@ -172,10 +166,10 @@ export class BaseDriverCore extends DriverCore {
172
166
  }
173
167
 
174
168
  /*
175
- * Restart the session with the original caps,
176
- * preserving the timeout config.
177
- */
178
- async reset () {
169
+ * Restart the session with the original caps,
170
+ * preserving the timeout config.
171
+ */
172
+ async reset() {
179
173
  this.log.debug('Resetting app mid-session');
180
174
  this.log.debug('Running generic full reset');
181
175
 
@@ -209,40 +203,33 @@ export class BaseDriverCore extends DriverCore {
209
203
  }
210
204
 
211
205
  /**
212
- *
213
- * Historically the first two arguments were reserved for JSONWP capabilities.
214
- * Appium 2 has dropped the support of these, so now we only accept capability
215
- * objects in W3C format and thus allow any of the three arguments to represent
216
- * the latter.
217
- * @param {W3CCapabilities} w3cCapabilities1
218
- * @param {W3CCapabilities} [w3cCapabilities2]
219
- * @param {W3CCapabilities} [w3cCapabilities]
220
- * @param {DriverData[]} [driverData]
221
- * @returns {Promise<[string,object]>}
222
- */
223
- async createSession (
224
- w3cCapabilities1,
225
- w3cCapabilities2,
226
- w3cCapabilities,
227
- driverData,
228
- ) {
206
+ *
207
+ * Historically the first two arguments were reserved for JSONWP capabilities.
208
+ * Appium 2 has dropped the support of these, so now we only accept capability
209
+ * objects in W3C format and thus allow any of the three arguments to represent
210
+ * the latter.
211
+ * @param {W3CCapabilities} w3cCapabilities1
212
+ * @param {W3CCapabilities} [w3cCapabilities2]
213
+ * @param {W3CCapabilities} [w3cCapabilities]
214
+ * @param {DriverData[]} [driverData]
215
+ * @returns {Promise<[string,object]>}
216
+ */
217
+ async createSession(w3cCapabilities1, w3cCapabilities2, w3cCapabilities, driverData) {
229
218
  if (this.sessionId !== null) {
230
219
  throw new errors.SessionNotCreatedError(
231
- 'Cannot create a new session while one is in progress',
220
+ 'Cannot create a new session while one is in progress'
232
221
  );
233
222
  }
234
223
 
235
224
  this.log.debug();
236
225
 
237
- const originalCaps = _.cloneDeep([
238
- w3cCapabilities,
239
- w3cCapabilities1,
240
- w3cCapabilities2,
241
- ].find(isW3cCaps));
226
+ const originalCaps = _.cloneDeep(
227
+ [w3cCapabilities, w3cCapabilities1, w3cCapabilities2].find(isW3cCaps)
228
+ );
242
229
  if (!originalCaps) {
243
230
  throw new errors.SessionNotCreatedError(
244
- 'Appium only supports W3C-style capability objects. ' +
245
- 'Your client is sending an older capabilities format. Please update your client library.',
231
+ 'Appium only supports W3C-style capability objects. ' +
232
+ 'Your client is sending an older capabilities format. Please update your client library.'
246
233
  );
247
234
  }
248
235
 
@@ -250,23 +237,15 @@ export class BaseDriverCore extends DriverCore {
250
237
 
251
238
  this.originalCaps = _.cloneDeep(originalCaps);
252
239
  this.log.debug(
253
- `Creating session with W3C capabilities: ${JSON.stringify(
254
- originalCaps,
255
- null,
256
- 2,
257
- )}`,
240
+ `Creating session with W3C capabilities: ${JSON.stringify(originalCaps, null, 2)}`
258
241
  );
259
242
 
260
243
  let caps;
261
244
  try {
262
- caps = processCapabilities(
263
- originalCaps,
264
- this.desiredCapConstraints,
265
- this.shouldValidateCaps,
266
- );
245
+ caps = processCapabilities(originalCaps, this.desiredCapConstraints, this.shouldValidateCaps);
267
246
  if (caps[APPIUM_OPTS_CAP]) {
268
247
  this.log.debug(
269
- `Found ${PREFIXED_APPIUM_OPTS_CAP} capability present; will promote items inside to caps`,
248
+ `Found ${PREFIXED_APPIUM_OPTS_CAP} capability present; will promote items inside to caps`
270
249
  );
271
250
  caps = promoteAppiumOptions(caps);
272
251
  }
@@ -289,9 +268,9 @@ export class BaseDriverCore extends DriverCore {
289
268
  // both to true, but this is misguided and strange, so error here instead
290
269
  if (this.opts.noReset && this.opts.fullReset) {
291
270
  throw new Error(
292
- "The 'noReset' and 'fullReset' capabilities are mutually " +
293
- 'exclusive and should not both be set to true. You ' +
294
- "probably meant to just use 'fullReset' on its own",
271
+ "The 'noReset' and 'fullReset' capabilities are mutually " +
272
+ 'exclusive and should not both be set to true. You ' +
273
+ "probably meant to just use 'fullReset' on its own"
295
274
  );
296
275
  }
297
276
  if (this.opts.noReset === true) {
@@ -320,12 +299,12 @@ export class BaseDriverCore extends DriverCore {
320
299
  }
321
300
 
322
301
  /**
323
- *
324
- * @param {string} [sessionId]
325
- * @param {DriverData[]} [driverData]
326
- * @returns {Promise<void>}
327
- */
328
- async deleteSession (sessionId, driverData) {
302
+ *
303
+ * @param {string} [sessionId]
304
+ * @param {DriverData[]} [driverData]
305
+ * @returns {Promise<void>}
306
+ */
307
+ async deleteSession(sessionId, driverData) {
329
308
  await this.clearNewCommandTimeout();
330
309
  if (this.isCommandsQueueEnabled && this.commandsQueueGuard.isBusy()) {
331
310
  // simple hack to release pending commands if they exist
@@ -338,14 +317,80 @@ export class BaseDriverCore extends DriverCore {
338
317
  this.sessionId = null;
339
318
  this._log.prefix = helpers.generateDriverLogPrefix(this);
340
319
  }
320
+
321
+ /**
322
+ *
323
+ * @param {Capabilities} caps
324
+ */
325
+ logExtraCaps(caps) {
326
+ let extraCaps = _.difference(_.keys(caps), _.keys(this._constraints));
327
+ if (extraCaps.length) {
328
+ this.log.warn(
329
+ `The following capabilities were provided, but are not ` + `recognized by Appium:`
330
+ );
331
+ for (const cap of extraCaps) {
332
+ this.log.warn(` ${cap}`);
333
+ }
334
+ }
335
+ }
336
+
337
+ /**
338
+ *
339
+ * @param {Capabilities} caps
340
+ * @returns {boolean}
341
+ */
342
+ validateDesiredCaps(caps) {
343
+ if (!this.shouldValidateCaps) {
344
+ return true;
345
+ }
346
+
347
+ try {
348
+ validateCaps(caps, this._constraints);
349
+ } catch (e) {
350
+ this.log.errorAndThrow(
351
+ new errors.SessionNotCreatedError(
352
+ `The desiredCapabilities object was not valid for the ` +
353
+ `following reason(s): ${e.message}`
354
+ )
355
+ );
356
+ }
357
+
358
+ this.logExtraCaps(caps);
359
+
360
+ return true;
361
+ }
362
+
363
+ // we only want subclasses to ever extend the contraints
364
+ set desiredCapConstraints(constraints) {
365
+ this._constraints = Object.assign(this._constraints, constraints);
366
+ // 'presence' means different things in different versions of the validator,
367
+ // when we say 'true' we mean that it should not be able to be empty
368
+ for (const [, value] of _.toPairs(this._constraints)) {
369
+ if (value && value.presence === true) {
370
+ value.presence = {
371
+ allowEmpty: false,
372
+ };
373
+ }
374
+ }
375
+ }
376
+
377
+ get desiredCapConstraints() {
378
+ return this._constraints;
379
+ }
341
380
  }
342
381
 
343
382
  /**
344
383
  * This ensures that all of the mixins correctly implement the interface described in {@linkcode Driver}.
345
384
  * @implements {Driver}
346
385
  */
347
- class BaseDriver extends createBaseDriverClass(BaseDriverCore) {}
348
- export { BaseDriver };
386
+ class _BaseDriver extends createBaseDriverClass(BaseDriverCore) {}
387
+
388
+ /**
389
+ * @type {import('@appium/types').DriverClass<Driver>}
390
+ */
391
+ const BaseDriver = _BaseDriver;
392
+
393
+ export {BaseDriver};
349
394
  export default BaseDriver;
350
395
 
351
396
  /**
@@ -357,7 +402,6 @@ export default BaseDriver;
357
402
  * @typedef {import('@appium/types').DriverData} DriverData
358
403
  */
359
404
 
360
-
361
405
  /**
362
406
  * @callback UpdateServerCallback
363
407
  * @param {import('express').Express} app - Express app
@@ -369,16 +413,7 @@ export default BaseDriver;
369
413
  * This is used to extend {@linkcode BaseDriverCore} by the mixins and also external drivers.
370
414
  * @template [Proto={}]
371
415
  * @template [Static={}]
372
- * @typedef {import('@appium/types').Class<BaseDriverCore & Proto,BaseDriverStatic & Static>} BaseDriverBase
373
- */
374
-
375
- /**
376
- * Static properties of `BaseDriver` and optional properties for subclasses.
377
- * @template {ExternalDriver} [T=ExternalDriver]
378
- * @typedef BaseDriverStatic
379
- * @property {string} baseVersion
380
- * @property {UpdateServerCallback} [updateServer]
381
- * @property {import('@appium/types').MethodMap<T>} [newMethodMap]
416
+ * @typedef {import('@appium/types').Class<BaseDriverCore & Proto,import('@appium/types').DriverStatic & Static>} BaseDriverBase
382
417
  */
383
418
 
384
419
  /**