@appium/base-driver 8.7.1 → 8.7.3
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 +207 -42
- package/build/lib/basedriver/capabilities.d.ts.map +1 -1
- package/build/lib/basedriver/capabilities.js +39 -44
- package/build/lib/basedriver/capabilities.js.map +1 -0
- package/build/lib/basedriver/commands/event.js +3 -3
- package/build/lib/basedriver/commands/event.js.map +1 -0
- package/build/lib/basedriver/commands/execute.js +3 -3
- package/build/lib/basedriver/commands/execute.js.map +1 -0
- package/build/lib/basedriver/commands/find.js.map +1 -0
- package/build/lib/basedriver/commands/index.js.map +1 -0
- package/build/lib/basedriver/commands/log.js +3 -3
- package/build/lib/basedriver/commands/log.js.map +1 -0
- package/build/lib/basedriver/commands/session.js +3 -3
- package/build/lib/basedriver/commands/session.js.map +1 -0
- package/build/lib/basedriver/commands/settings.js.map +1 -0
- package/build/lib/basedriver/commands/timeout.js +3 -3
- package/build/lib/basedriver/commands/timeout.js.map +1 -0
- package/build/lib/basedriver/core.d.ts +171 -20
- package/build/lib/basedriver/core.d.ts.map +1 -1
- package/build/lib/basedriver/core.js +4 -6
- package/build/lib/basedriver/core.js.map +1 -0
- package/build/lib/basedriver/desired-caps.d.ts +0 -2
- package/build/lib/basedriver/desired-caps.d.ts.map +1 -1
- package/build/lib/basedriver/desired-caps.js +4 -53
- package/build/lib/basedriver/desired-caps.js.map +1 -0
- package/build/lib/basedriver/device-settings.js +3 -3
- package/build/lib/basedriver/device-settings.js.map +1 -0
- package/build/lib/basedriver/driver.d.ts +323 -28
- package/build/lib/basedriver/driver.d.ts.map +1 -1
- package/build/lib/basedriver/driver.js +27 -30
- package/build/lib/basedriver/driver.js.map +1 -0
- package/build/lib/basedriver/helpers.d.ts +1 -1
- package/build/lib/basedriver/helpers.d.ts.map +1 -1
- package/build/lib/basedriver/helpers.js +3 -3
- package/build/lib/basedriver/helpers.js.map +1 -0
- package/build/lib/basedriver/logger.js.map +1 -0
- package/build/lib/constants.js.map +1 -0
- package/build/lib/express/crash.js.map +1 -0
- package/build/lib/express/express-logging.js +3 -3
- package/build/lib/express/express-logging.js.map +1 -0
- package/build/lib/express/idempotency.js +3 -3
- package/build/lib/express/idempotency.js.map +1 -0
- package/build/lib/express/logger.js.map +1 -0
- package/build/lib/express/middleware.js +3 -3
- package/build/lib/express/middleware.js.map +1 -0
- package/build/lib/express/server.js +3 -3
- package/build/lib/express/server.js.map +1 -0
- package/build/lib/express/static.js +3 -3
- package/build/lib/express/static.js.map +1 -0
- package/build/lib/express/websocket.js +3 -3
- package/build/lib/express/websocket.js.map +1 -0
- package/build/lib/helpers/capabilities.d.ts +66 -5
- package/build/lib/helpers/capabilities.d.ts.map +1 -1
- package/build/lib/helpers/capabilities.js +7 -7
- package/build/lib/helpers/capabilities.js.map +1 -0
- package/build/lib/index.d.ts +1 -1
- package/build/lib/index.d.ts.map +1 -1
- package/build/lib/index.js +10 -3
- package/build/lib/index.js.map +1 -0
- package/build/lib/jsonwp-proxy/protocol-converter.js +3 -3
- package/build/lib/jsonwp-proxy/protocol-converter.js.map +1 -0
- package/build/lib/jsonwp-proxy/proxy.js +3 -3
- package/build/lib/jsonwp-proxy/proxy.js.map +1 -0
- package/build/lib/jsonwp-status/status.js +3 -3
- package/build/lib/jsonwp-status/status.js.map +1 -0
- package/build/lib/protocol/errors.js +3 -3
- package/build/lib/protocol/errors.js.map +1 -0
- package/build/lib/protocol/helpers.js +3 -3
- package/build/lib/protocol/helpers.js.map +1 -0
- package/build/lib/protocol/index.js.map +1 -0
- package/build/lib/protocol/protocol.js +3 -3
- package/build/lib/protocol/protocol.js.map +1 -0
- package/build/lib/protocol/routes.js +3 -3
- package/build/lib/protocol/routes.js.map +1 -0
- package/build/lib/protocol/validators.js +3 -3
- package/build/lib/protocol/validators.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/lib/basedriver/capabilities.js +151 -93
- package/lib/basedriver/core.js +34 -18
- package/lib/basedriver/desired-caps.js +1 -53
- package/lib/basedriver/driver.js +113 -51
- package/lib/helpers/capabilities.js +19 -9
- package/lib/index.js +1 -0
- package/package.json +9 -10
|
@@ -10,17 +10,21 @@ const APPIUM_VENDOR_PREFIX = 'appium:';
|
|
|
10
10
|
const APPIUM_OPTS_CAP = 'options';
|
|
11
11
|
const PREFIXED_APPIUM_OPTS_CAP = `${APPIUM_VENDOR_PREFIX}${APPIUM_OPTS_CAP}`;
|
|
12
12
|
|
|
13
|
-
// Takes primary caps object and merges it into a secondary caps object.
|
|
14
|
-
// (see https://www.w3.org/TR/webdriver/#dfn-merging-capabilities)
|
|
15
13
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @
|
|
18
|
-
* @
|
|
14
|
+
* Takes primary caps object and merges it into a secondary caps object.
|
|
15
|
+
* @template {Constraints} [T={}]
|
|
16
|
+
* @template {Constraints} [U={}]
|
|
17
|
+
* @param {Capabilities<T>} [primary]
|
|
18
|
+
* @param {Capabilities<U>} [secondary]
|
|
19
|
+
* @returns {import('type-fest').Merge<Capabilities<T>, Capabilities<U>>}
|
|
20
|
+
* @see https://www.w3.org/TR/webdriver/#dfn-merging-capabilities)
|
|
19
21
|
*/
|
|
20
22
|
function mergeCaps(primary = {}, secondary = {}) {
|
|
21
|
-
let result =
|
|
23
|
+
let result = /** @type {import('type-fest').Merge<Capabilities<T>, Capabilities<U>>} */ ({
|
|
24
|
+
...primary,
|
|
25
|
+
});
|
|
22
26
|
|
|
23
|
-
for (let [name, value] of _.toPairs(secondary)) {
|
|
27
|
+
for (let [name, value] of /** @type {[keyof typeof secondary, any]} */ (_.toPairs(secondary))) {
|
|
24
28
|
// Overwriting is not allowed. Primary and secondary must have different properties (w3c rule 4.4)
|
|
25
29
|
if (!_.isUndefined(primary[name])) {
|
|
26
30
|
throw new errors.InvalidArgumentError(
|
|
@@ -29,7 +33,7 @@ function mergeCaps(primary = {}, secondary = {}) {
|
|
|
29
33
|
)}) and secondary (${JSON.stringify(secondary)}) object`
|
|
30
34
|
);
|
|
31
35
|
}
|
|
32
|
-
result[name] = value;
|
|
36
|
+
result[/** @type {keyof typeof result} */ (name)] = value;
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
return result;
|
|
@@ -37,29 +41,37 @@ function mergeCaps(primary = {}, secondary = {}) {
|
|
|
37
41
|
|
|
38
42
|
// Validates caps against a set of constraints
|
|
39
43
|
/**
|
|
40
|
-
*
|
|
41
|
-
* @param {Capabilities} caps
|
|
42
|
-
* @param {
|
|
44
|
+
* @template {Constraints} [C={}]
|
|
45
|
+
* @param {Capabilities<C>} caps
|
|
46
|
+
* @param {C} [constraints]
|
|
43
47
|
* @param {ValidateCapsOpts} [opts]
|
|
44
|
-
* @returns {Capabilities}
|
|
48
|
+
* @returns {Capabilities<C>}
|
|
45
49
|
*/
|
|
46
|
-
function validateCaps(caps, constraints = {}, opts = {}) {
|
|
50
|
+
function validateCaps(caps, constraints = /** @type {C} */ ({}), opts = {}) {
|
|
47
51
|
let {skipPresenceConstraint} = opts;
|
|
48
52
|
|
|
49
53
|
if (!_.isPlainObject(caps)) {
|
|
50
54
|
throw new errors.InvalidArgumentError(`must be a JSON object`);
|
|
51
55
|
}
|
|
52
56
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
// Remove the 'presence' constraint if we're not checking for it
|
|
58
|
+
constraints = /** @type {C} */ (
|
|
59
|
+
_.mapValues(
|
|
60
|
+
constraints,
|
|
61
|
+
skipPresenceConstraint
|
|
62
|
+
? /** @param {Constraint} constraint */
|
|
63
|
+
(constraint) => _.omit(constraint, 'presence')
|
|
64
|
+
: /** @param {Constraint} constraint */
|
|
65
|
+
(constraint) => {
|
|
66
|
+
if (constraint.presence === true) {
|
|
67
|
+
return {..._.omit(constraint, 'presence'), presence: {allowEmpty: false}};
|
|
68
|
+
}
|
|
69
|
+
return constraint;
|
|
70
|
+
}
|
|
71
|
+
)
|
|
72
|
+
);
|
|
61
73
|
|
|
62
|
-
|
|
74
|
+
const validationErrors = validator.validate(_.pickBy(caps, util.hasValue), constraints, {
|
|
63
75
|
fullMessages: false,
|
|
64
76
|
});
|
|
65
77
|
|
|
@@ -77,54 +89,78 @@ function validateCaps(caps, constraints = {}, opts = {}) {
|
|
|
77
89
|
return caps;
|
|
78
90
|
}
|
|
79
91
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
+
/**
|
|
93
|
+
* Standard, non-prefixed capabilities
|
|
94
|
+
* @see https://www.w3.org/TR/webdriver/#dfn-table-of-standard-capabilities)
|
|
95
|
+
*/
|
|
96
|
+
export const STANDARD_CAPS = Object.freeze(
|
|
97
|
+
new Set(
|
|
98
|
+
/** @type {import('type-fest').StringKeyOf<import('@appium/types').StandardCapabilities>[]} */ ([
|
|
99
|
+
'browserName',
|
|
100
|
+
'browserVersion',
|
|
101
|
+
'platformName',
|
|
102
|
+
'acceptInsecureCerts',
|
|
103
|
+
'pageLoadStrategy',
|
|
104
|
+
'proxy',
|
|
105
|
+
'setWindowRect',
|
|
106
|
+
'timeouts',
|
|
107
|
+
'unhandledPromptBehavior',
|
|
108
|
+
])
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
const STANDARD_CAPS_LOWER = new Set([...STANDARD_CAPS].map((cap) => cap.toLowerCase()));
|
|
92
113
|
|
|
114
|
+
/**
|
|
115
|
+
* @param {string} cap
|
|
116
|
+
* @returns {boolean}
|
|
117
|
+
*/
|
|
93
118
|
function isStandardCap(cap) {
|
|
94
|
-
return
|
|
95
|
-
STANDARD_CAPS,
|
|
96
|
-
(standardCap) => standardCap.toLowerCase() === `${cap}`.toLowerCase()
|
|
97
|
-
);
|
|
119
|
+
return STANDARD_CAPS_LOWER.has(cap.toLowerCase());
|
|
98
120
|
}
|
|
99
121
|
|
|
100
|
-
|
|
101
|
-
|
|
122
|
+
/**
|
|
123
|
+
* If the 'appium:' prefix was provided and it's a valid capability, strip out the prefix
|
|
124
|
+
* @template {Constraints} [C={}]
|
|
125
|
+
* @param {import('@appium/types').NSCapabilities<C>} caps
|
|
126
|
+
* @see https://www.w3.org/TR/webdriver/#dfn-extension-capabilities
|
|
127
|
+
* @internal
|
|
128
|
+
* @returns {import('@appium/types').Capabilities<C>}
|
|
129
|
+
*/
|
|
102
130
|
function stripAppiumPrefixes(caps) {
|
|
103
|
-
|
|
104
|
-
|
|
131
|
+
// split into prefixed and non-prefixed.
|
|
132
|
+
// non-prefixed should be standard caps at this point
|
|
133
|
+
const [prefixedCaps, nonPrefixedCaps] = _.partition(_.keys(caps), (cap) =>
|
|
134
|
+
String(cap).startsWith(APPIUM_VENDOR_PREFIX)
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
// initialize this with the k/v pairs of the non-prefixed caps
|
|
138
|
+
let strippedCaps = /** @type {import('@appium/types').Capabilities<C>} */ (
|
|
139
|
+
_.pick(caps, nonPrefixedCaps)
|
|
140
|
+
);
|
|
105
141
|
const badPrefixedCaps = [];
|
|
106
142
|
|
|
107
143
|
// Strip out the 'appium:' prefix
|
|
108
144
|
for (let prefixedCap of prefixedCaps) {
|
|
109
|
-
const strippedCapName =
|
|
145
|
+
const strippedCapName =
|
|
146
|
+
/** @type {import('type-fest').StringKeyOf<import('@appium/types').Capabilities<C>>} */ (
|
|
147
|
+
prefixedCap.substring(APPIUM_VENDOR_PREFIX.length)
|
|
148
|
+
);
|
|
110
149
|
|
|
111
150
|
// If it's standard capability that was prefixed, add it to an array of incorrectly prefixed capabilities
|
|
112
151
|
if (isStandardCap(strippedCapName)) {
|
|
113
152
|
badPrefixedCaps.push(strippedCapName);
|
|
114
|
-
if (_.isNil(
|
|
115
|
-
|
|
153
|
+
if (_.isNil(strippedCaps[strippedCapName])) {
|
|
154
|
+
strippedCaps[strippedCapName] = caps[prefixedCap];
|
|
116
155
|
} else {
|
|
117
156
|
log.warn(
|
|
118
157
|
`Ignoring capability '${prefixedCap}=${caps[prefixedCap]}' and ` +
|
|
119
|
-
`using capability '${strippedCapName}=${
|
|
158
|
+
`using capability '${strippedCapName}=${strippedCaps[strippedCapName]}'`
|
|
120
159
|
);
|
|
121
160
|
}
|
|
122
161
|
} else {
|
|
123
|
-
|
|
162
|
+
strippedCaps[strippedCapName] = caps[prefixedCap];
|
|
124
163
|
}
|
|
125
|
-
|
|
126
|
-
// Strip out the prefix
|
|
127
|
-
delete caps[prefixedCap];
|
|
128
164
|
}
|
|
129
165
|
|
|
130
166
|
// If we found standard caps that were incorrectly prefixed, throw an exception (e.g.: don't accept 'appium:platformName', only accept just 'platformName')
|
|
@@ -135,11 +171,13 @@ function stripAppiumPrefixes(caps) {
|
|
|
135
171
|
)} are standard capabilities and do not require "appium:" prefix`
|
|
136
172
|
);
|
|
137
173
|
}
|
|
174
|
+
return strippedCaps;
|
|
138
175
|
}
|
|
139
176
|
|
|
140
177
|
/**
|
|
141
178
|
* Get an array of all the unprefixed caps that are being used in 'alwaysMatch' and all of the 'firstMatch' object
|
|
142
|
-
* @
|
|
179
|
+
* @template {Constraints} [C={}]
|
|
180
|
+
* @param {import('@appium/types').W3CCapabilities<C>} caps A capabilities object
|
|
143
181
|
*/
|
|
144
182
|
function findNonPrefixedCaps({alwaysMatch = {}, firstMatch = []}) {
|
|
145
183
|
return _.chain([alwaysMatch, ...firstMatch])
|
|
@@ -154,15 +192,15 @@ function findNonPrefixedCaps({alwaysMatch = {}, firstMatch = []}) {
|
|
|
154
192
|
.value();
|
|
155
193
|
}
|
|
156
194
|
|
|
157
|
-
// Parse capabilities (based on https://www.w3.org/TR/webdriver/#processing-capabilities)
|
|
158
195
|
/**
|
|
159
|
-
*
|
|
160
|
-
* @
|
|
161
|
-
* @param {
|
|
196
|
+
* Parse capabilities
|
|
197
|
+
* @template {Constraints} [C={}]
|
|
198
|
+
* @param {import('@appium/types').W3CCapabilities<C>} caps
|
|
199
|
+
* @param {C} [constraints]
|
|
162
200
|
* @param {boolean} [shouldValidateCaps]
|
|
163
|
-
* @
|
|
201
|
+
* @see https://www.w3.org/TR/webdriver/#processing-capabilities
|
|
164
202
|
*/
|
|
165
|
-
function parseCaps(caps, constraints = {}, shouldValidateCaps = true) {
|
|
203
|
+
function parseCaps(caps, constraints = /** @type {C} */ ({}), shouldValidateCaps = true) {
|
|
166
204
|
// If capabilities request is not an object, return error (#1.1)
|
|
167
205
|
if (!_.isPlainObject(caps)) {
|
|
168
206
|
throw new errors.InvalidArgumentError(
|
|
@@ -203,49 +241,47 @@ function parseCaps(caps, constraints = {}, shouldValidateCaps = true) {
|
|
|
203
241
|
}
|
|
204
242
|
|
|
205
243
|
// Strip out the 'appium:' prefix from all
|
|
206
|
-
stripAppiumPrefixes(requiredCaps);
|
|
207
|
-
|
|
208
|
-
stripAppiumPrefixes(firstMatchCaps);
|
|
209
|
-
}
|
|
244
|
+
let strippedRequiredCaps = stripAppiumPrefixes(requiredCaps);
|
|
245
|
+
let strippedAllFirstMatchCaps = allFirstMatchCaps.map(stripAppiumPrefixes);
|
|
210
246
|
|
|
211
247
|
// 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
|
|
212
248
|
if (shouldValidateCaps) {
|
|
213
|
-
|
|
249
|
+
strippedRequiredCaps = validateCaps(strippedRequiredCaps, constraints, {
|
|
214
250
|
skipPresenceConstraint: true,
|
|
215
251
|
});
|
|
216
252
|
}
|
|
217
|
-
|
|
218
253
|
// Remove the 'presence' constraint for any keys that are already present in 'requiredCaps'
|
|
219
254
|
// since we know that this constraint has already passed
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
if (requiredCapsKeys.includes(key)) {
|
|
224
|
-
delete filteredConstraints[key];
|
|
225
|
-
}
|
|
226
|
-
}
|
|
255
|
+
const filteredConstraints = /** @type {C} */ (
|
|
256
|
+
_.omitBy(constraints, (_, key) => key in strippedRequiredCaps)
|
|
257
|
+
);
|
|
227
258
|
|
|
228
259
|
// Validate all of the first match capabilities and return an array with only the valid caps (see spec #5)
|
|
260
|
+
/** @type {string[]} */
|
|
229
261
|
let validationErrors = [];
|
|
230
|
-
/** @type {Capabilities[]} */
|
|
231
262
|
let validatedFirstMatchCaps = _.compact(
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
263
|
+
strippedAllFirstMatchCaps.map(
|
|
264
|
+
/**
|
|
265
|
+
* @param {import('@appium/types').Capabilities<C>} firstMatchCaps
|
|
266
|
+
*/
|
|
267
|
+
(firstMatchCaps) => {
|
|
268
|
+
try {
|
|
269
|
+
// Validate firstMatch caps
|
|
270
|
+
return shouldValidateCaps
|
|
271
|
+
? validateCaps(firstMatchCaps, filteredConstraints)
|
|
272
|
+
: firstMatchCaps;
|
|
273
|
+
} catch (e) {
|
|
274
|
+
validationErrors.push(e.message);
|
|
275
|
+
}
|
|
240
276
|
}
|
|
241
|
-
|
|
277
|
+
)
|
|
242
278
|
);
|
|
243
279
|
|
|
244
280
|
// Try to merge requiredCaps with first match capabilities, break once it finds its first match (see spec #6)
|
|
245
281
|
let matchedCaps = null;
|
|
246
282
|
for (let firstMatchCaps of validatedFirstMatchCaps) {
|
|
247
283
|
try {
|
|
248
|
-
matchedCaps = mergeCaps(
|
|
284
|
+
matchedCaps = mergeCaps(strippedRequiredCaps, firstMatchCaps);
|
|
249
285
|
if (matchedCaps) {
|
|
250
286
|
break;
|
|
251
287
|
}
|
|
@@ -267,13 +303,17 @@ function parseCaps(caps, constraints = {}, shouldValidateCaps = true) {
|
|
|
267
303
|
|
|
268
304
|
// Calls parseCaps and just returns the matchedCaps variable
|
|
269
305
|
/**
|
|
270
|
-
*
|
|
271
|
-
* @param {W3CCapabilities} w3cCaps
|
|
272
|
-
* @param {
|
|
306
|
+
* @template {Constraints} C
|
|
307
|
+
* @param {import('@appium/types').W3CCapabilities<C>} w3cCaps
|
|
308
|
+
* @param {C} [constraints]
|
|
273
309
|
* @param {boolean} [shouldValidateCaps]
|
|
274
|
-
* @returns {Capabilities}
|
|
310
|
+
* @returns {import('@appium/types').Capabilities<C>}
|
|
275
311
|
*/
|
|
276
|
-
function processCapabilities(
|
|
312
|
+
function processCapabilities(
|
|
313
|
+
w3cCaps,
|
|
314
|
+
constraints = /** @type {C} */ ({}),
|
|
315
|
+
shouldValidateCaps = true
|
|
316
|
+
) {
|
|
277
317
|
const {matchedCaps, validationErrors} = parseCaps(w3cCaps, constraints, shouldValidateCaps);
|
|
278
318
|
|
|
279
319
|
// If we found an error throw an exception
|
|
@@ -291,7 +331,7 @@ function processCapabilities(w3cCaps, constraints = {}, shouldValidateCaps = tru
|
|
|
291
331
|
}
|
|
292
332
|
}
|
|
293
333
|
|
|
294
|
-
return matchedCaps ?? {};
|
|
334
|
+
return /** @type {Capabilities<C>} */ (matchedCaps ?? {});
|
|
295
335
|
}
|
|
296
336
|
|
|
297
337
|
/**
|
|
@@ -317,10 +357,9 @@ function promoteAppiumOptions(originalCaps) {
|
|
|
317
357
|
}
|
|
318
358
|
|
|
319
359
|
// first get rid of any prefixes inside appium:options
|
|
320
|
-
stripAppiumPrefixes(appiumOptions);
|
|
321
|
-
|
|
360
|
+
const strippedAppiumOptions = stripAppiumPrefixes(appiumOptions);
|
|
322
361
|
// warn if we are going to overwrite any keys on the base caps object
|
|
323
|
-
const overwrittenKeys = _.intersection(Object.keys(caps), Object.keys(
|
|
362
|
+
const overwrittenKeys = _.intersection(Object.keys(caps), Object.keys(strippedAppiumOptions));
|
|
324
363
|
if (overwrittenKeys.length > 0) {
|
|
325
364
|
log.warn(
|
|
326
365
|
`Found capabilities inside ${PREFIXED_APPIUM_OPTS_CAP} that will overwrite ` +
|
|
@@ -329,7 +368,7 @@ function promoteAppiumOptions(originalCaps) {
|
|
|
329
368
|
}
|
|
330
369
|
|
|
331
370
|
// now just apply them to the main caps object
|
|
332
|
-
caps = {...caps, ...
|
|
371
|
+
caps = {...caps, ...strippedAppiumOptions};
|
|
333
372
|
|
|
334
373
|
// and remove all traces of the options cap
|
|
335
374
|
delete caps[APPIUM_OPTS_CAP];
|
|
@@ -351,12 +390,31 @@ export {
|
|
|
351
390
|
};
|
|
352
391
|
|
|
353
392
|
/**
|
|
354
|
-
* @typedef {import('@appium/types').W3CCapabilities} W3CCapabilities
|
|
355
393
|
* @typedef {import('@appium/types').Constraints} Constraints
|
|
356
|
-
* @typedef {import('@appium/types').
|
|
394
|
+
* @typedef {import('@appium/types').Constraint} Constraint
|
|
395
|
+
* @typedef {import('@appium/types').StringRecord} StringRecord
|
|
396
|
+
* @typedef {import('@appium/types').BaseDriverCapConstraints} BaseDriverCapConstraints
|
|
357
397
|
*/
|
|
358
398
|
|
|
359
399
|
/**
|
|
360
400
|
* @typedef ValidateCapsOpts
|
|
361
401
|
* @property {boolean} [skipPresenceConstraint] - if true, skip the presence constraint
|
|
362
402
|
*/
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
406
|
+
* @template {StringRecord|void} [Extra=void]
|
|
407
|
+
* @typedef {import('@appium/types').NSCapabilities<C, Extra>} NSCapabilities
|
|
408
|
+
*/
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
412
|
+
* @template {StringRecord|void} [Extra=void]
|
|
413
|
+
* @typedef {import('@appium/types').Capabilities<C, Extra>} Capabilities
|
|
414
|
+
*/
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
418
|
+
* @template {StringRecord|void} [Extra=void]
|
|
419
|
+
* @typedef {import('@appium/types').W3CCapabilities<C, Extra>} W3CCapabilities
|
|
420
|
+
*/
|
package/lib/basedriver/core.js
CHANGED
|
@@ -17,8 +17,10 @@ const {version: BASEDRIVER_VER} = fs.readPackageJsonFrom(__dirname);
|
|
|
17
17
|
const NEW_COMMAND_TIMEOUT_MS = 60 * 1000;
|
|
18
18
|
|
|
19
19
|
const ON_UNEXPECTED_SHUTDOWN_EVENT = 'onUnexpectedShutdown';
|
|
20
|
+
|
|
20
21
|
/**
|
|
21
|
-
* @
|
|
22
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
23
|
+
* @implements {Core<C>}
|
|
22
24
|
*/
|
|
23
25
|
class DriverCore {
|
|
24
26
|
/**
|
|
@@ -36,7 +38,7 @@ class DriverCore {
|
|
|
36
38
|
sessionId = null;
|
|
37
39
|
|
|
38
40
|
/**
|
|
39
|
-
* @type {import('@appium/types').DriverOpts}
|
|
41
|
+
* @type {import('@appium/types').DriverOpts<C>}
|
|
40
42
|
*/
|
|
41
43
|
opts;
|
|
42
44
|
|
|
@@ -45,16 +47,6 @@ class DriverCore {
|
|
|
45
47
|
*/
|
|
46
48
|
initialOpts;
|
|
47
49
|
|
|
48
|
-
/**
|
|
49
|
-
* @type {Capabilities}
|
|
50
|
-
*/
|
|
51
|
-
caps;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @type {W3CCapabilities}
|
|
55
|
-
*/
|
|
56
|
-
originalCaps;
|
|
57
|
-
|
|
58
50
|
helpers = helpers;
|
|
59
51
|
|
|
60
52
|
/**
|
|
@@ -126,7 +118,11 @@ class DriverCore {
|
|
|
126
118
|
*/
|
|
127
119
|
settings = new DeviceSettings();
|
|
128
120
|
|
|
129
|
-
|
|
121
|
+
/**
|
|
122
|
+
* @param {DriverOpts<C>} opts
|
|
123
|
+
* @param {boolean} [shouldValidateCaps]
|
|
124
|
+
*/
|
|
125
|
+
constructor(opts = /** @type {DriverOpts<C>} */ ({}), shouldValidateCaps = true) {
|
|
130
126
|
this._log = logger.getLogger(helpers.generateDriverLogPrefix(this));
|
|
131
127
|
|
|
132
128
|
// setup state
|
|
@@ -140,7 +136,7 @@ class DriverCore {
|
|
|
140
136
|
this.shouldValidateCaps = shouldValidateCaps;
|
|
141
137
|
|
|
142
138
|
// keeping track of initial opts
|
|
143
|
-
this.initialOpts = _.cloneDeep(
|
|
139
|
+
this.initialOpts = _.cloneDeep(opts);
|
|
144
140
|
|
|
145
141
|
this.sessionId = null;
|
|
146
142
|
}
|
|
@@ -240,7 +236,7 @@ class DriverCore {
|
|
|
240
236
|
* method required by MJSONWP in order to determine if the command should
|
|
241
237
|
* be proxied directly to the driver
|
|
242
238
|
* @param {string} sessionId
|
|
243
|
-
* @returns {Core | null}
|
|
239
|
+
* @returns {Core<C> | null}
|
|
244
240
|
*/
|
|
245
241
|
driverForSession(sessionId) {
|
|
246
242
|
return this;
|
|
@@ -422,12 +418,32 @@ class DriverCore {
|
|
|
422
418
|
export {DriverCore};
|
|
423
419
|
|
|
424
420
|
/**
|
|
425
|
-
* @typedef {import('@appium/types').Capabilities} Capabilities
|
|
426
|
-
* @typedef {import('@appium/types').W3CCapabilities} W3CCapabilities
|
|
427
421
|
* @typedef {import('@appium/types').Driver} Driver
|
|
428
|
-
* @typedef {import('@appium/types').
|
|
422
|
+
* @typedef {import('@appium/types').Constraints} Constraints
|
|
429
423
|
* @typedef {import('@appium/types').ExecuteMethodMap} ExecuteMethodMap
|
|
430
424
|
* @typedef {import('@appium/types').ServerArgs} ServerArgs
|
|
431
425
|
* @typedef {import('@appium/types').EventHistory} EventHistory
|
|
432
426
|
* @typedef {import('@appium/types').AppiumLogger} AppiumLogger
|
|
427
|
+
* @typedef {import('@appium/types').StringRecord} StringRecord
|
|
428
|
+
* @typedef {import('@appium/types').BaseDriverCapConstraints} BaseDriverCapConstraints
|
|
429
|
+
*/
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
433
|
+
* @template {StringRecord|void} [Extra=void]
|
|
434
|
+
* @typedef {import('@appium/types').Capabilities<C, Extra>} Capabilities
|
|
435
|
+
*/
|
|
436
|
+
/**
|
|
437
|
+
* @template {StringRecord} [T={}]
|
|
438
|
+
* @typedef {import('@appium/types').W3CCapabilities<T>} W3CCapabilities
|
|
439
|
+
*/
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* @template {Constraints} C
|
|
443
|
+
* @typedef {import('@appium/types').Core<C>} Core
|
|
444
|
+
*/
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* @template {Constraints} C
|
|
448
|
+
* @typedef {import('@appium/types').DriverOpts<C>} DriverOpts
|
|
433
449
|
*/
|
|
@@ -2,61 +2,11 @@ import log from './logger';
|
|
|
2
2
|
import _validator from 'validate.js';
|
|
3
3
|
import B from 'bluebird';
|
|
4
4
|
|
|
5
|
-
const validator =
|
|
5
|
+
export const validator =
|
|
6
6
|
/** @type {import('validate.js').ValidateJS & {promise: typeof import('bluebird')}} */ (
|
|
7
7
|
_validator
|
|
8
8
|
);
|
|
9
9
|
|
|
10
|
-
/** @type {import('@appium/types').Constraints} */
|
|
11
|
-
let desiredCapabilityConstraints = {
|
|
12
|
-
platformName: {
|
|
13
|
-
presence: true,
|
|
14
|
-
isString: true,
|
|
15
|
-
},
|
|
16
|
-
deviceName: {
|
|
17
|
-
isString: true,
|
|
18
|
-
},
|
|
19
|
-
platformVersion: {
|
|
20
|
-
isString: true,
|
|
21
|
-
},
|
|
22
|
-
newCommandTimeout: {
|
|
23
|
-
isNumber: true,
|
|
24
|
-
},
|
|
25
|
-
automationName: {
|
|
26
|
-
isString: true,
|
|
27
|
-
},
|
|
28
|
-
autoLaunch: {
|
|
29
|
-
isBoolean: true,
|
|
30
|
-
},
|
|
31
|
-
udid: {
|
|
32
|
-
isString: true,
|
|
33
|
-
},
|
|
34
|
-
orientation: {
|
|
35
|
-
inclusion: ['LANDSCAPE', 'PORTRAIT'],
|
|
36
|
-
},
|
|
37
|
-
autoWebview: {
|
|
38
|
-
isBoolean: true,
|
|
39
|
-
},
|
|
40
|
-
noReset: {
|
|
41
|
-
isBoolean: true,
|
|
42
|
-
},
|
|
43
|
-
fullReset: {
|
|
44
|
-
isBoolean: true,
|
|
45
|
-
},
|
|
46
|
-
language: {
|
|
47
|
-
isString: true,
|
|
48
|
-
},
|
|
49
|
-
locale: {
|
|
50
|
-
isString: true,
|
|
51
|
-
},
|
|
52
|
-
eventTimings: {
|
|
53
|
-
isBoolean: true,
|
|
54
|
-
},
|
|
55
|
-
printPageSourceOnFindFailure: {
|
|
56
|
-
isBoolean: true,
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
|
|
60
10
|
validator.validators.isString = function isString(value) {
|
|
61
11
|
if (typeof value === 'string') {
|
|
62
12
|
return null;
|
|
@@ -147,5 +97,3 @@ validator.promise = B;
|
|
|
147
97
|
validator.prettify = function prettify(val) {
|
|
148
98
|
return val;
|
|
149
99
|
};
|
|
150
|
-
|
|
151
|
-
export {desiredCapabilityConstraints, validator};
|