@appium/base-driver 9.3.3 → 9.3.4
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.
- package/build/lib/basedriver/capabilities.d.ts +59 -36
- package/build/lib/basedriver/capabilities.d.ts.map +1 -1
- package/build/lib/basedriver/capabilities.js +57 -45
- package/build/lib/basedriver/capabilities.js.map +1 -1
- package/build/lib/basedriver/commands/event.d.ts +1 -1
- package/build/lib/basedriver/commands/event.d.ts.map +1 -1
- package/build/lib/basedriver/commands/event.js.map +1 -1
- package/build/lib/basedriver/commands/execute.d.ts +1 -1
- package/build/lib/basedriver/commands/execute.d.ts.map +1 -1
- package/build/lib/basedriver/commands/execute.js.map +1 -1
- package/build/lib/basedriver/commands/find.d.ts +1 -1
- package/build/lib/basedriver/commands/find.d.ts.map +1 -1
- package/build/lib/basedriver/commands/find.js.map +1 -1
- package/build/lib/basedriver/commands/index.d.ts +7 -7
- package/build/lib/basedriver/commands/index.d.ts.map +1 -1
- package/build/lib/basedriver/commands/index.js +7 -21
- package/build/lib/basedriver/commands/index.js.map +1 -1
- package/build/lib/basedriver/commands/log.d.ts +1 -1
- package/build/lib/basedriver/commands/log.d.ts.map +1 -1
- package/build/lib/basedriver/commands/log.js.map +1 -1
- package/build/lib/basedriver/commands/mixin.d.ts +4 -4
- package/build/lib/basedriver/commands/mixin.d.ts.map +1 -1
- package/build/lib/basedriver/commands/mixin.js +5 -4
- package/build/lib/basedriver/commands/mixin.js.map +1 -1
- package/build/lib/basedriver/commands/session.d.ts +1 -1
- package/build/lib/basedriver/commands/session.d.ts.map +1 -1
- package/build/lib/basedriver/commands/session.js +1 -4
- package/build/lib/basedriver/commands/session.js.map +1 -1
- package/build/lib/basedriver/commands/settings.d.ts +1 -1
- package/build/lib/basedriver/commands/settings.d.ts.map +1 -1
- package/build/lib/basedriver/commands/settings.js.map +1 -1
- package/build/lib/basedriver/commands/timeout.d.ts +1 -1
- package/build/lib/basedriver/commands/timeout.d.ts.map +1 -1
- package/build/lib/basedriver/commands/timeout.js +1 -4
- package/build/lib/basedriver/commands/timeout.js.map +1 -1
- package/build/lib/basedriver/core.d.ts +13 -17
- package/build/lib/basedriver/core.d.ts.map +1 -1
- package/build/lib/basedriver/core.js +32 -20
- package/build/lib/basedriver/core.js.map +1 -1
- package/build/lib/basedriver/device-settings.d.ts +11 -11
- package/build/lib/basedriver/device-settings.d.ts.map +1 -1
- package/build/lib/basedriver/device-settings.js +7 -8
- package/build/lib/basedriver/device-settings.js.map +1 -1
- package/build/lib/basedriver/driver.d.ts +23 -108
- package/build/lib/basedriver/driver.d.ts.map +1 -1
- package/build/lib/basedriver/driver.js +21 -126
- package/build/lib/basedriver/driver.js.map +1 -1
- package/build/lib/basedriver/helpers.d.ts +21 -98
- package/build/lib/basedriver/helpers.d.ts.map +1 -1
- package/build/lib/basedriver/helpers.js +178 -182
- package/build/lib/basedriver/helpers.js.map +1 -1
- package/build/lib/express/server.d.ts +3 -3
- package/build/lib/express/server.d.ts.map +1 -1
- package/build/lib/express/server.js +4 -2
- package/build/lib/express/server.js.map +1 -1
- package/build/lib/express/websocket.d.ts +5 -44
- package/build/lib/express/websocket.d.ts.map +1 -1
- package/build/lib/express/websocket.js +10 -39
- package/build/lib/express/websocket.js.map +1 -1
- package/build/lib/helpers/capabilities.d.ts +2 -2
- package/build/lib/helpers/capabilities.d.ts.map +1 -1
- package/build/lib/helpers/capabilities.js +2 -3
- package/build/lib/helpers/capabilities.js.map +1 -1
- package/build/lib/protocol/protocol.d.ts +1 -1
- package/build/lib/protocol/protocol.d.ts.map +1 -1
- package/build/lib/protocol/protocol.js +10 -2
- package/build/lib/protocol/protocol.js.map +1 -1
- package/build/lib/protocol/routes.d.ts +1 -0
- package/build/lib/protocol/routes.d.ts.map +1 -1
- package/build/lib/protocol/routes.js +12 -10
- package/build/lib/protocol/routes.js.map +1 -1
- package/lib/basedriver/capabilities.js +70 -56
- package/lib/basedriver/commands/event.ts +3 -2
- package/lib/basedriver/commands/execute.ts +2 -1
- package/lib/basedriver/commands/find.ts +1 -0
- package/lib/basedriver/commands/index.ts +7 -7
- package/lib/basedriver/commands/log.ts +2 -4
- package/lib/basedriver/commands/mixin.ts +5 -4
- package/lib/basedriver/commands/session.ts +9 -7
- package/lib/basedriver/commands/settings.ts +1 -0
- package/lib/basedriver/commands/timeout.ts +17 -17
- package/lib/basedriver/core.js +11 -25
- package/lib/basedriver/device-settings.js +9 -11
- package/lib/basedriver/{driver.js → driver.ts} +69 -175
- package/lib/basedriver/helpers.js +214 -212
- package/lib/express/server.js +4 -2
- package/lib/express/websocket.js +10 -39
- package/lib/helpers/capabilities.js +2 -3
- package/lib/protocol/protocol.js +11 -2
- package/lib/protocol/routes.js +12 -13
- package/package.json +10 -6
|
@@ -11,19 +11,24 @@ const PREFIXED_APPIUM_OPTS_CAP = `${APPIUM_VENDOR_PREFIX}options`;
|
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Takes primary caps object and merges it into a secondary caps object.
|
|
14
|
-
* @template {Constraints}
|
|
15
|
-
* @template {Constraints}
|
|
16
|
-
* @
|
|
17
|
-
* @
|
|
18
|
-
* @
|
|
14
|
+
* @template {Constraints} T
|
|
15
|
+
* @template {Constraints} U
|
|
16
|
+
* @template {Capabilities<T>} Primary
|
|
17
|
+
* @template {Capabilities<U>} Secondary
|
|
18
|
+
* @param {Primary} [primary]
|
|
19
|
+
* @param {Secondary} [secondary]
|
|
20
|
+
* @returns {MergeExclusive<Primary, Secondary>}
|
|
19
21
|
* @see https://www.w3.org/TR/webdriver/#dfn-merging-capabilities)
|
|
20
22
|
*/
|
|
21
|
-
function mergeCaps(
|
|
22
|
-
|
|
23
|
+
function mergeCaps(
|
|
24
|
+
primary = /** @type {Primary} */ ({}),
|
|
25
|
+
secondary = /** @type {Secondary} */ ({})
|
|
26
|
+
) {
|
|
27
|
+
let result = /** @type {MergeExclusive<Primary, Secondary>} */ ({
|
|
23
28
|
...primary,
|
|
24
29
|
});
|
|
25
30
|
|
|
26
|
-
for (let [name, value] of
|
|
31
|
+
for (let [name, value] of Object.entries(secondary)) {
|
|
27
32
|
// Overwriting is not allowed. Primary and secondary must have different properties (w3c rule 4.4)
|
|
28
33
|
if (!_.isUndefined(primary[name])) {
|
|
29
34
|
throw new errors.InvalidArgumentError(
|
|
@@ -38,9 +43,9 @@ function mergeCaps(primary = {}, secondary = {}) {
|
|
|
38
43
|
return result;
|
|
39
44
|
}
|
|
40
45
|
|
|
41
|
-
// Validates caps against a set of constraints
|
|
42
46
|
/**
|
|
43
|
-
*
|
|
47
|
+
* Validates caps against a set of constraints
|
|
48
|
+
* @template {Constraints} C
|
|
44
49
|
* @param {Capabilities<C>} caps
|
|
45
50
|
* @param {C} [constraints]
|
|
46
51
|
* @param {ValidateCapsOpts} [opts]
|
|
@@ -121,11 +126,11 @@ function isStandardCap(cap) {
|
|
|
121
126
|
|
|
122
127
|
/**
|
|
123
128
|
* If the 'appium:' prefix was provided and it's a valid capability, strip out the prefix
|
|
124
|
-
* @template {Constraints}
|
|
125
|
-
* @param {
|
|
129
|
+
* @template {Constraints} C
|
|
130
|
+
* @param {NSCapabilities<C>} caps
|
|
126
131
|
* @see https://www.w3.org/TR/webdriver/#dfn-extension-capabilities
|
|
127
132
|
* @internal
|
|
128
|
-
* @returns {
|
|
133
|
+
* @returns {Capabilities<C>}
|
|
129
134
|
*/
|
|
130
135
|
function stripAppiumPrefixes(caps) {
|
|
131
136
|
// split into prefixed and non-prefixed.
|
|
@@ -135,14 +140,12 @@ function stripAppiumPrefixes(caps) {
|
|
|
135
140
|
);
|
|
136
141
|
|
|
137
142
|
// initialize this with the k/v pairs of the non-prefixed caps
|
|
138
|
-
let strippedCaps = /** @type {
|
|
139
|
-
_.pick(caps, nonPrefixedCaps)
|
|
140
|
-
);
|
|
143
|
+
let strippedCaps = /** @type {Capabilities<C>} */ (_.pick(caps, nonPrefixedCaps));
|
|
141
144
|
const badPrefixedCaps = [];
|
|
142
145
|
|
|
143
146
|
// Strip out the 'appium:' prefix
|
|
144
147
|
for (let prefixedCap of prefixedCaps) {
|
|
145
|
-
const strippedCapName = /** @type {StringKeyOf<
|
|
148
|
+
const strippedCapName = /** @type {StringKeyOf<Capabilities<C>>} */ (
|
|
146
149
|
prefixedCap.substring(APPIUM_VENDOR_PREFIX.length)
|
|
147
150
|
);
|
|
148
151
|
|
|
@@ -175,8 +178,8 @@ function stripAppiumPrefixes(caps) {
|
|
|
175
178
|
|
|
176
179
|
/**
|
|
177
180
|
* Get an array of all the unprefixed caps that are being used in 'alwaysMatch' and all of the 'firstMatch' object
|
|
178
|
-
* @template {Constraints}
|
|
179
|
-
* @param {
|
|
181
|
+
* @template {Constraints} C
|
|
182
|
+
* @param {W3CCapabilities<C>} caps A capabilities object
|
|
180
183
|
*/
|
|
181
184
|
function findNonPrefixedCaps({alwaysMatch = {}, firstMatch = []}) {
|
|
182
185
|
return _.chain([alwaysMatch, ...firstMatch])
|
|
@@ -191,13 +194,25 @@ function findNonPrefixedCaps({alwaysMatch = {}, firstMatch = []}) {
|
|
|
191
194
|
.value();
|
|
192
195
|
}
|
|
193
196
|
|
|
197
|
+
/**
|
|
198
|
+
* Returned by {@linkcode parseCaps}
|
|
199
|
+
* @template {Constraints} C
|
|
200
|
+
* @typedef ParsedCaps
|
|
201
|
+
* @property {NSCapabilities<C>[]} allFirstMatchCaps
|
|
202
|
+
* @property {Capabilities<C>[]} validatedFirstMatchCaps
|
|
203
|
+
* @property {NSCapabilities<C>} requiredCaps
|
|
204
|
+
* @property {Capabilities<C>|null} matchedCaps
|
|
205
|
+
* @property {string[]} validationErrors
|
|
206
|
+
*/
|
|
207
|
+
|
|
194
208
|
/**
|
|
195
209
|
* Parse capabilities
|
|
196
|
-
* @template {Constraints}
|
|
197
|
-
* @param {
|
|
210
|
+
* @template {Constraints} C
|
|
211
|
+
* @param {W3CCapabilities<C>} caps
|
|
198
212
|
* @param {C} [constraints]
|
|
199
213
|
* @param {boolean} [shouldValidateCaps]
|
|
200
214
|
* @see https://www.w3.org/TR/webdriver/#processing-capabilities
|
|
215
|
+
* @returns {ParsedCaps<C>}
|
|
201
216
|
*/
|
|
202
217
|
function parseCaps(caps, constraints = /** @type {C} */ ({}), shouldValidateCaps = true) {
|
|
203
218
|
// If capabilities request is not an object, return error (#1.1)
|
|
@@ -210,8 +225,8 @@ function parseCaps(caps, constraints = /** @type {C} */ ({}), shouldValidateCaps
|
|
|
210
225
|
// Let 'requiredCaps' be property named 'alwaysMatch' from capabilities request (#2)
|
|
211
226
|
// and 'allFirstMatchCaps' be property named 'firstMatch' from capabilities request (#3)
|
|
212
227
|
let {
|
|
213
|
-
alwaysMatch: requiredCaps = {}, // If 'requiredCaps' is undefined, set it to an empty JSON object (#2.1)
|
|
214
|
-
firstMatch: allFirstMatchCaps = [{}], // If 'firstMatch' is undefined set it to a singleton list with one empty object (#3.1)
|
|
228
|
+
alwaysMatch: requiredCaps = /** @type {NSCapabilities<C>} */ ({}), // If 'requiredCaps' is undefined, set it to an empty JSON object (#2.1)
|
|
229
|
+
firstMatch: allFirstMatchCaps = /** @type {NSCapabilities<C>[]} */ ([{}]), // If 'firstMatch' is undefined set it to a singleton list with one empty object (#3.1)
|
|
215
230
|
} = caps;
|
|
216
231
|
|
|
217
232
|
// Reject 'firstMatch' argument if it's not an array (#3.2)
|
|
@@ -241,6 +256,7 @@ function parseCaps(caps, constraints = /** @type {C} */ ({}), shouldValidateCaps
|
|
|
241
256
|
|
|
242
257
|
// Strip out the 'appium:' prefix from all
|
|
243
258
|
let strippedRequiredCaps = stripAppiumPrefixes(requiredCaps);
|
|
259
|
+
/** @type {Capabilities<C>[]} */
|
|
244
260
|
let strippedAllFirstMatchCaps = allFirstMatchCaps.map(stripAppiumPrefixes);
|
|
245
261
|
|
|
246
262
|
// Validate the requiredCaps. But don't validate 'presence' because if that constraint fails on 'alwaysMatch' it could still pass on one of the 'firstMatch' keys
|
|
@@ -259,24 +275,23 @@ function parseCaps(caps, constraints = /** @type {C} */ ({}), shouldValidateCaps
|
|
|
259
275
|
/** @type {string[]} */
|
|
260
276
|
let validationErrors = [];
|
|
261
277
|
let validatedFirstMatchCaps = _.compact(
|
|
262
|
-
strippedAllFirstMatchCaps.map(
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
? validateCaps(firstMatchCaps, filteredConstraints)
|
|
271
|
-
: firstMatchCaps;
|
|
272
|
-
} catch (e) {
|
|
273
|
-
validationErrors.push(e.message);
|
|
274
|
-
}
|
|
278
|
+
strippedAllFirstMatchCaps.map((firstMatchCaps) => {
|
|
279
|
+
try {
|
|
280
|
+
// Validate firstMatch caps
|
|
281
|
+
return shouldValidateCaps
|
|
282
|
+
? validateCaps(firstMatchCaps, filteredConstraints)
|
|
283
|
+
: firstMatchCaps;
|
|
284
|
+
} catch (e) {
|
|
285
|
+
validationErrors.push(e.message);
|
|
275
286
|
}
|
|
276
|
-
)
|
|
287
|
+
})
|
|
277
288
|
);
|
|
278
289
|
|
|
279
|
-
|
|
290
|
+
/**
|
|
291
|
+
* Try to merge requiredCaps with first match capabilities, break once it finds its first match
|
|
292
|
+
* (see spec #6)
|
|
293
|
+
* @type {ParsedCaps<C>['matchedCaps']}
|
|
294
|
+
*/
|
|
280
295
|
let matchedCaps = null;
|
|
281
296
|
for (let firstMatchCaps of validatedFirstMatchCaps) {
|
|
282
297
|
try {
|
|
@@ -300,13 +315,14 @@ function parseCaps(caps, constraints = /** @type {C} */ ({}), shouldValidateCaps
|
|
|
300
315
|
};
|
|
301
316
|
}
|
|
302
317
|
|
|
303
|
-
// Calls parseCaps and just returns the matchedCaps variable
|
|
304
318
|
/**
|
|
319
|
+
* Calls parseCaps and just returns the matchedCaps variable
|
|
305
320
|
* @template {Constraints} C
|
|
306
|
-
* @
|
|
321
|
+
* @template {W3CCapabilities<C>} W3CCaps
|
|
322
|
+
* @param {W3CCaps} w3cCaps
|
|
307
323
|
* @param {C} [constraints]
|
|
308
324
|
* @param {boolean} [shouldValidateCaps]
|
|
309
|
-
* @returns {
|
|
325
|
+
* @returns {Capabilities<C>}
|
|
310
326
|
*/
|
|
311
327
|
function processCapabilities(
|
|
312
328
|
w3cCaps,
|
|
@@ -400,8 +416,8 @@ function promoteAppiumOptionsForObject(obj) {
|
|
|
400
416
|
* capability and promoted it to the top level.
|
|
401
417
|
*
|
|
402
418
|
* @template {Constraints} C
|
|
403
|
-
* @param {
|
|
404
|
-
* @return {
|
|
419
|
+
* @param {W3CCapabilities<C>} originalCaps
|
|
420
|
+
* @return {W3CCapabilities<C>} the capabilities with 'options' promoted if necessary
|
|
405
421
|
*/
|
|
406
422
|
function promoteAppiumOptions(originalCaps) {
|
|
407
423
|
const result = {};
|
|
@@ -451,28 +467,26 @@ export {
|
|
|
451
467
|
*/
|
|
452
468
|
|
|
453
469
|
/**
|
|
454
|
-
* @template {Constraints}
|
|
455
|
-
* @
|
|
456
|
-
* @typedef {import('@appium/types').NSCapabilities<C, Extra>} NSCapabilities
|
|
470
|
+
* @template {Constraints} C
|
|
471
|
+
* @typedef {import('@appium/types').NSCapabilities<C>} NSCapabilities
|
|
457
472
|
*/
|
|
458
473
|
|
|
459
474
|
/**
|
|
460
|
-
* @template {Constraints}
|
|
461
|
-
* @
|
|
462
|
-
* @typedef {import('@appium/types').Capabilities<C, Extra>} Capabilities
|
|
475
|
+
* @template {Constraints} C
|
|
476
|
+
* @typedef {import('@appium/types').Capabilities<C>} Capabilities
|
|
463
477
|
*/
|
|
464
478
|
|
|
465
479
|
/**
|
|
466
|
-
* @template {Constraints}
|
|
467
|
-
* @
|
|
468
|
-
* @typedef {import('@appium/types').W3CCapabilities<C, Extra>} W3CCapabilities
|
|
480
|
+
* @template {Constraints} C
|
|
481
|
+
* @typedef {import('@appium/types').W3CCapabilities<C>} W3CCapabilities
|
|
469
482
|
*/
|
|
470
483
|
|
|
471
|
-
/**
|
|
472
|
-
* @template T,U
|
|
473
|
-
* @typedef {import('type-fest').Merge<T,U>} Merge
|
|
474
|
-
*/
|
|
475
484
|
/**
|
|
476
485
|
* @template T
|
|
477
486
|
* @typedef {import('type-fest').StringKeyOf<T>} StringKeyOf
|
|
478
487
|
*/
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* @template T,U
|
|
491
|
+
* @typedef {import('type-fest').MergeExclusive<T, U>} MergeExclusive<T,U>
|
|
492
|
+
*/
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
1
|
import {Constraints, IEventCommands} from '@appium/types';
|
|
3
|
-
import
|
|
2
|
+
import _ from 'lodash';
|
|
4
3
|
import {BaseDriver} from '../driver';
|
|
4
|
+
import {mixin} from './mixin';
|
|
5
5
|
|
|
6
6
|
declare module '../driver' {
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
8
|
interface BaseDriver<C extends Constraints> extends IEventCommands {}
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -12,6 +12,7 @@ import {mixin} from './mixin';
|
|
|
12
12
|
import {BaseDriver} from '../driver';
|
|
13
13
|
|
|
14
14
|
declare module '../driver' {
|
|
15
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
15
16
|
interface BaseDriver<C extends Constraints> extends IExecuteCommands {}
|
|
16
17
|
}
|
|
17
18
|
|
|
@@ -19,7 +20,7 @@ const ExecuteCommands: IExecuteCommands = {
|
|
|
19
20
|
async executeMethod<C extends Constraints>(
|
|
20
21
|
this: BaseDriver<C>,
|
|
21
22
|
script: string,
|
|
22
|
-
protoArgs: [StringRecord] |
|
|
23
|
+
protoArgs: readonly [StringRecord<unknown>] | readonly unknown[]
|
|
23
24
|
) {
|
|
24
25
|
const Driver = this.constructor as DriverClass<Driver<C>>;
|
|
25
26
|
const commandMetadata = {...Driver.executeMethodMap?.[script]};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import './event';
|
|
2
|
+
import './find';
|
|
3
|
+
import './log';
|
|
4
|
+
import './session';
|
|
5
|
+
import './settings';
|
|
6
|
+
import './timeout';
|
|
7
|
+
import './execute';
|
|
@@ -4,6 +4,7 @@ import {BaseDriver} from '../driver';
|
|
|
4
4
|
import {mixin} from './mixin';
|
|
5
5
|
|
|
6
6
|
declare module '../driver' {
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
7
8
|
interface BaseDriver<C extends Constraints> extends ILogCommands {}
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -15,10 +16,7 @@ const LogCommands: ILogCommands = {
|
|
|
15
16
|
return Object.keys(this.supportedLogTypes);
|
|
16
17
|
},
|
|
17
18
|
|
|
18
|
-
async getLog<C extends Constraints>(
|
|
19
|
-
this: Driver<C>,
|
|
20
|
-
logType: keyof ILogCommands['supportedLogTypes']
|
|
21
|
-
) {
|
|
19
|
+
async getLog<C extends Constraints>(this: Driver<C>, logType: string) {
|
|
22
20
|
this.log.debug(`Retrieving '${String(logType)}' logs`);
|
|
23
21
|
|
|
24
22
|
if (!(logType in this.supportedLogTypes)) {
|
|
@@ -2,13 +2,14 @@ import {Constraints} from '@appium/types';
|
|
|
2
2
|
import {BaseDriver} from '../driver';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* This function assigns a mixin `T` to the `
|
|
6
|
-
* While each mixin has its own interface which is (in isolation) unrelated to `
|
|
7
|
-
* on this generic type `T` is that it must be a partial of `
|
|
8
|
-
* that it does not conflict with the existing interface of `
|
|
5
|
+
* This function assigns a mixin `T` to the `BaseDriver` class' prototype.
|
|
6
|
+
* While each mixin has its own interface which is (in isolation) unrelated to `BaseDriver`, the constraint
|
|
7
|
+
* on this generic type `T` is that it must be a partial of `BaseDriver`'s interface. This enforces
|
|
8
|
+
* that it does not conflict with the existing interface of `BaseDriver`. In that way, you can
|
|
9
9
|
* think of it as a type guard.
|
|
10
10
|
* @param mixin Mixin implementation
|
|
11
11
|
*/
|
|
12
12
|
export function mixin<C extends Constraints, T extends Partial<BaseDriver<C>>>(mixin: T): void {
|
|
13
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
13
14
|
Object.assign(BaseDriver.prototype, mixin);
|
|
14
15
|
}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
import {Constraints, ISessionCommands, MultiSessionData} from '@appium/types';
|
|
1
|
+
import {Constraints, ISessionCommands, MultiSessionData, SingularSessionData} from '@appium/types';
|
|
2
2
|
import {BaseDriver} from '../driver';
|
|
3
3
|
import {mixin} from './mixin';
|
|
4
4
|
|
|
5
5
|
declare module '../driver' {
|
|
6
|
-
interface BaseDriver<
|
|
6
|
+
interface BaseDriver<
|
|
7
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
8
|
+
C extends Constraints
|
|
9
|
+
> extends ISessionCommands {}
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
const SessionCommands: ISessionCommands = {
|
|
10
13
|
async getSessions<C extends Constraints>(this: BaseDriver<C>) {
|
|
11
|
-
const ret: MultiSessionData[] = [];
|
|
14
|
+
const ret: MultiSessionData<C>[] = [];
|
|
12
15
|
|
|
13
16
|
if (this.sessionId) {
|
|
14
17
|
ret.push({
|
|
@@ -24,10 +27,9 @@ const SessionCommands: ISessionCommands = {
|
|
|
24
27
|
* Returns capabilities for the session and event history (if applicable)
|
|
25
28
|
*/
|
|
26
29
|
async getSession<C extends Constraints>(this: BaseDriver<C>) {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
return this.caps;
|
|
30
|
+
return <SingularSessionData<C>>(
|
|
31
|
+
(this.caps.eventTimings ? {...this.caps, events: this.eventHistory} : this.caps)
|
|
32
|
+
);
|
|
31
33
|
},
|
|
32
34
|
};
|
|
33
35
|
|
|
@@ -3,6 +3,7 @@ import {Constraints, ISettingsCommands, StringRecord} from '@appium/types';
|
|
|
3
3
|
import {mixin} from './mixin';
|
|
4
4
|
|
|
5
5
|
declare module '../driver' {
|
|
6
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
6
7
|
interface BaseDriver<C extends Constraints> extends ISettingsCommands {}
|
|
7
8
|
}
|
|
8
9
|
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
|
|
3
|
-
/* eslint-disable no-unused-vars */
|
|
4
|
-
/* eslint-disable require-await */
|
|
5
1
|
import {waitForCondition} from 'asyncbox';
|
|
6
2
|
import _ from 'lodash';
|
|
7
3
|
import {util} from '@appium/support';
|
|
@@ -11,13 +7,14 @@ import {Constraints, ITimeoutCommands} from '@appium/types';
|
|
|
11
7
|
import {mixin} from './mixin';
|
|
12
8
|
|
|
13
9
|
declare module '../driver' {
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
14
11
|
interface BaseDriver<C extends Constraints> extends ITimeoutCommands {}
|
|
15
12
|
}
|
|
16
13
|
|
|
17
14
|
const MIN_TIMEOUT = 0;
|
|
18
15
|
|
|
19
16
|
const TimeoutCommands: ITimeoutCommands = {
|
|
20
|
-
async timeouts(type, ms, script, pageLoad, implicit) {
|
|
17
|
+
async timeouts<C extends Constraints>(this: BaseDriver<C>, type, ms, script, pageLoad, implicit) {
|
|
21
18
|
if (util.hasValue(type) && util.hasValue(ms)) {
|
|
22
19
|
this.log.debug(`MJSONWP timeout arguments: ${JSON.stringify({type, ms})}}`);
|
|
23
20
|
|
|
@@ -66,42 +63,42 @@ const TimeoutCommands: ITimeoutCommands = {
|
|
|
66
63
|
},
|
|
67
64
|
|
|
68
65
|
// implicit
|
|
69
|
-
async implicitWaitW3C(ms) {
|
|
66
|
+
async implicitWaitW3C<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
70
67
|
await this.implicitWait(ms);
|
|
71
68
|
},
|
|
72
69
|
|
|
73
|
-
async implicitWaitMJSONWP(ms) {
|
|
70
|
+
async implicitWaitMJSONWP<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
74
71
|
await this.implicitWait(ms);
|
|
75
72
|
},
|
|
76
73
|
|
|
77
|
-
async implicitWait(ms) {
|
|
78
|
-
|
|
74
|
+
async implicitWait<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
75
|
+
this.setImplicitWait(this.parseTimeoutArgument(ms));
|
|
79
76
|
},
|
|
80
77
|
|
|
81
78
|
// pageLoad
|
|
82
|
-
async pageLoadTimeoutW3C(ms) {
|
|
79
|
+
async pageLoadTimeoutW3C<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
83
80
|
throw new errors.NotImplementedError('Not implemented yet for pageLoad.');
|
|
84
81
|
},
|
|
85
82
|
|
|
86
|
-
async pageLoadTimeoutMJSONWP(ms) {
|
|
83
|
+
async pageLoadTimeoutMJSONWP<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
87
84
|
throw new errors.NotImplementedError('Not implemented yet for pageLoad.');
|
|
88
85
|
},
|
|
89
86
|
|
|
90
87
|
// script
|
|
91
|
-
async scriptTimeoutW3C(ms) {
|
|
88
|
+
async scriptTimeoutW3C<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
92
89
|
throw new errors.NotImplementedError('Not implemented yet for script.');
|
|
93
90
|
},
|
|
94
91
|
|
|
95
|
-
async scriptTimeoutMJSONWP(ms) {
|
|
92
|
+
async scriptTimeoutMJSONWP<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
96
93
|
throw new errors.NotImplementedError('Not implemented yet for script.');
|
|
97
94
|
},
|
|
98
95
|
|
|
99
96
|
// command
|
|
100
|
-
async newCommandTimeout(ms) {
|
|
97
|
+
async newCommandTimeout<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
101
98
|
this.setNewCommandTimeout(this.parseTimeoutArgument(ms));
|
|
102
99
|
},
|
|
103
100
|
|
|
104
|
-
setImplicitWait(ms) {
|
|
101
|
+
setImplicitWait<C extends Constraints>(this: BaseDriver<C>, ms: number) {
|
|
105
102
|
// eslint-disable-line require-await
|
|
106
103
|
this.implicitWaitMs = ms;
|
|
107
104
|
this.log.debug(`Set implicit wait to ${ms}ms`);
|
|
@@ -115,7 +112,7 @@ const TimeoutCommands: ITimeoutCommands = {
|
|
|
115
112
|
}
|
|
116
113
|
},
|
|
117
114
|
|
|
118
|
-
setNewCommandTimeout(ms) {
|
|
115
|
+
setNewCommandTimeout<C extends Constraints>(this: BaseDriver<C>, ms: number) {
|
|
119
116
|
this.newCommandTimeoutMs = ms;
|
|
120
117
|
this.log.debug(`Set new command timeout to ${ms}ms`);
|
|
121
118
|
if (this.managedDrivers && this.managedDrivers.length) {
|
|
@@ -128,7 +125,10 @@ const TimeoutCommands: ITimeoutCommands = {
|
|
|
128
125
|
}
|
|
129
126
|
},
|
|
130
127
|
|
|
131
|
-
async implicitWaitForCondition(
|
|
128
|
+
async implicitWaitForCondition<C extends Constraints>(
|
|
129
|
+
this: BaseDriver<C>,
|
|
130
|
+
condFn: (...args: any[]) => Promise<any>
|
|
131
|
+
) {
|
|
132
132
|
this.log.debug(`Waiting up to ${this.implicitWaitMs} ms for condition`);
|
|
133
133
|
const wrappedCondFn = async (...args: any[]) => {
|
|
134
134
|
// reset command timeout
|
package/lib/basedriver/core.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-unused-vars */
|
|
2
2
|
/* eslint-disable require-await */
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import {logger} from '@appium/support';
|
|
5
5
|
import AsyncLock from 'async-lock';
|
|
6
6
|
import {EventEmitter} from 'events';
|
|
7
7
|
import _ from 'lodash';
|
|
@@ -9,18 +9,16 @@ import os from 'os';
|
|
|
9
9
|
import {DEFAULT_BASE_PATH, PROTOCOLS} from '../constants';
|
|
10
10
|
import {errors} from '../protocol';
|
|
11
11
|
import DeviceSettings from './device-settings';
|
|
12
|
-
import helpers from './helpers';
|
|
13
|
-
|
|
14
|
-
// for compat with running tests transpiled and in-place
|
|
15
|
-
const {version: BASEDRIVER_VER} = fs.readPackageJsonFrom(__dirname);
|
|
12
|
+
import helpers, {BASEDRIVER_VER} from './helpers';
|
|
16
13
|
|
|
17
14
|
const NEW_COMMAND_TIMEOUT_MS = 60 * 1000;
|
|
18
15
|
|
|
19
16
|
const ON_UNEXPECTED_SHUTDOWN_EVENT = 'onUnexpectedShutdown';
|
|
20
17
|
|
|
21
18
|
/**
|
|
22
|
-
* @template {Constraints}
|
|
23
|
-
* @
|
|
19
|
+
* @template {Constraints} C
|
|
20
|
+
* @template {StringRecord} [Settings=StringRecord]
|
|
21
|
+
* @implements {Core<C, Settings>}
|
|
24
22
|
*/
|
|
25
23
|
class DriverCore {
|
|
26
24
|
/**
|
|
@@ -40,7 +38,7 @@ class DriverCore {
|
|
|
40
38
|
opts;
|
|
41
39
|
|
|
42
40
|
/**
|
|
43
|
-
* @type {
|
|
41
|
+
* @type {import('@appium/types').DriverOpts<C>}
|
|
44
42
|
*/
|
|
45
43
|
initialOpts;
|
|
46
44
|
|
|
@@ -98,7 +96,6 @@ class DriverCore {
|
|
|
98
96
|
_log;
|
|
99
97
|
|
|
100
98
|
/**
|
|
101
|
-
* @protected
|
|
102
99
|
* @type {boolean}
|
|
103
100
|
*/
|
|
104
101
|
shutdownUnexpectedly;
|
|
@@ -119,7 +116,7 @@ class DriverCore {
|
|
|
119
116
|
* we set it to an empty DeviceSettings instance here to make sure that the
|
|
120
117
|
* default settings are applied even if an extending driver doesn't utilize
|
|
121
118
|
* the settings functionality itself
|
|
122
|
-
* @type {DeviceSettings}
|
|
119
|
+
* @type {DeviceSettings<Settings>}
|
|
123
120
|
*/
|
|
124
121
|
settings;
|
|
125
122
|
|
|
@@ -184,11 +181,9 @@ class DriverCore {
|
|
|
184
181
|
* specific driver sessions. This data can be later used to adjust
|
|
185
182
|
* properties for driver instances running in parallel.
|
|
186
183
|
* Override it in inherited driver classes if necessary.
|
|
187
|
-
*
|
|
188
|
-
* @return {Record<string,unknown>} Driver properties mapping
|
|
189
184
|
*/
|
|
190
185
|
get driverData() {
|
|
191
|
-
return {};
|
|
186
|
+
return /** @type {import('@appium/types').DriverData} */ ({});
|
|
192
187
|
}
|
|
193
188
|
|
|
194
189
|
/**
|
|
@@ -260,7 +255,7 @@ class DriverCore {
|
|
|
260
255
|
* @returns {Core<C> | null}
|
|
261
256
|
*/
|
|
262
257
|
driverForSession(sessionId) {
|
|
263
|
-
return this;
|
|
258
|
+
return /** @type {Core<C> | null} */ (this);
|
|
264
259
|
}
|
|
265
260
|
|
|
266
261
|
isMjsonwpProtocol() {
|
|
@@ -448,19 +443,10 @@ export {DriverCore};
|
|
|
448
443
|
* @typedef {import('@appium/types').BaseDriverCapConstraints} BaseDriverCapConstraints
|
|
449
444
|
*/
|
|
450
445
|
|
|
451
|
-
/**
|
|
452
|
-
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
453
|
-
* @template {StringRecord|void} [Extra=void]
|
|
454
|
-
* @typedef {import('@appium/types').Capabilities<C, Extra>} Capabilities
|
|
455
|
-
*/
|
|
456
|
-
/**
|
|
457
|
-
* @template {StringRecord} [T={}]
|
|
458
|
-
* @typedef {import('@appium/types').W3CCapabilities<T>} W3CCapabilities
|
|
459
|
-
*/
|
|
460
|
-
|
|
461
446
|
/**
|
|
462
447
|
* @template {Constraints} C
|
|
463
|
-
* @
|
|
448
|
+
* @template {StringRecord} [S=StringRecord]
|
|
449
|
+
* @typedef {import('@appium/types').Core<C, S>} Core
|
|
464
450
|
*/
|
|
465
451
|
|
|
466
452
|
/**
|
|
@@ -9,13 +9,13 @@ import {errors} from '../protocol/errors';
|
|
|
9
9
|
export const MAX_SETTINGS_SIZE = 20 * 1024 * 1024; // 20 MB
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
|
-
* @template T
|
|
12
|
+
* @template {import('@appium/types').StringRecord} T
|
|
13
13
|
* @implements {IDeviceSettings<T>}
|
|
14
14
|
*/
|
|
15
|
-
class DeviceSettings {
|
|
15
|
+
export class DeviceSettings {
|
|
16
16
|
/**
|
|
17
17
|
* @protected
|
|
18
|
-
* @type {
|
|
18
|
+
* @type {T}
|
|
19
19
|
*/
|
|
20
20
|
_settings;
|
|
21
21
|
|
|
@@ -27,17 +27,17 @@ class DeviceSettings {
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Creates a _shallow copy_ of the `defaultSettings` parameter!
|
|
30
|
-
* @param {
|
|
30
|
+
* @param {T} [defaultSettings]
|
|
31
31
|
* @param {import('@appium/types').SettingsUpdateListener<T>} [onSettingsUpdate]
|
|
32
32
|
*/
|
|
33
|
-
constructor(defaultSettings = {}, onSettingsUpdate = async () => {}) {
|
|
33
|
+
constructor(defaultSettings = /** @type {T} */ ({}), onSettingsUpdate = async () => {}) {
|
|
34
34
|
this._settings = {...defaultSettings};
|
|
35
35
|
this._onSettingsUpdate = onSettingsUpdate;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* calls updateSettings from implementing driver every time a setting is changed.
|
|
40
|
-
* @param {
|
|
40
|
+
* @param {T} newSettings
|
|
41
41
|
*/
|
|
42
42
|
async update(newSettings) {
|
|
43
43
|
if (!_.isPlainObject(newSettings)) {
|
|
@@ -54,8 +54,7 @@ class DeviceSettings {
|
|
|
54
54
|
);
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
for (const prop of props) {
|
|
57
|
+
for (const prop in newSettings) {
|
|
59
58
|
if (!_.isUndefined(this._settings[prop])) {
|
|
60
59
|
if (this._settings[prop] === newSettings[prop]) {
|
|
61
60
|
log.debug(`The value of '${prop}' setting did not change. Skipping the update for it`);
|
|
@@ -73,9 +72,8 @@ class DeviceSettings {
|
|
|
73
72
|
}
|
|
74
73
|
|
|
75
74
|
export default DeviceSettings;
|
|
76
|
-
export {DeviceSettings};
|
|
77
75
|
|
|
78
76
|
/**
|
|
79
|
-
* @template T
|
|
80
|
-
* @typedef {import('@appium/types').
|
|
77
|
+
* @template {import('@appium/types').StringRecord} [T=import('@appium/types').StringRecord]
|
|
78
|
+
* @typedef {import('@appium/types').IDeviceSettings<T>} IDeviceSettings
|
|
81
79
|
*/
|