@appium/base-driver 9.3.2 → 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/LICENSE +1 -1
- 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 +5 -9
- package/build/lib/basedriver/commands/event.d.ts.map +1 -1
- package/build/lib/basedriver/commands/event.js +28 -49
- package/build/lib/basedriver/commands/event.js.map +1 -1
- package/build/lib/basedriver/commands/execute.d.ts +5 -11
- package/build/lib/basedriver/commands/execute.d.ts.map +1 -1
- package/build/lib/basedriver/commands/execute.js +15 -39
- package/build/lib/basedriver/commands/execute.js.map +1 -1
- package/build/lib/basedriver/commands/find.d.ts +5 -12
- package/build/lib/basedriver/commands/find.d.ts.map +1 -1
- package/build/lib/basedriver/commands/find.js +38 -98
- package/build/lib/basedriver/commands/find.js.map +1 -1
- package/build/lib/basedriver/commands/index.d.ts +7 -3
- package/build/lib/basedriver/commands/index.d.ts.map +1 -1
- package/build/lib/basedriver/commands/index.js +7 -28
- package/build/lib/basedriver/commands/index.js.map +1 -1
- package/build/lib/basedriver/commands/log.d.ts +5 -10
- package/build/lib/basedriver/commands/log.d.ts.map +1 -1
- package/build/lib/basedriver/commands/log.js +17 -50
- package/build/lib/basedriver/commands/log.js.map +1 -1
- package/build/lib/basedriver/commands/mixin.d.ts +12 -0
- package/build/lib/basedriver/commands/mixin.d.ts.map +1 -0
- package/build/lib/basedriver/commands/mixin.js +18 -0
- package/build/lib/basedriver/commands/mixin.js.map +1 -0
- package/build/lib/basedriver/commands/session.d.ts +5 -11
- package/build/lib/basedriver/commands/session.d.ts.map +1 -1
- package/build/lib/basedriver/commands/session.js +18 -53
- package/build/lib/basedriver/commands/session.js.map +1 -1
- package/build/lib/basedriver/commands/settings.d.ts +5 -9
- package/build/lib/basedriver/commands/settings.d.ts.map +1 -1
- package/build/lib/basedriver/commands/settings.js +14 -34
- package/build/lib/basedriver/commands/settings.js.map +1 -1
- package/build/lib/basedriver/commands/timeout.d.ts +5 -9
- package/build/lib/basedriver/commands/timeout.d.ts.map +1 -1
- package/build/lib/basedriver/commands/timeout.js +107 -129
- package/build/lib/basedriver/commands/timeout.js.map +1 -1
- package/build/lib/basedriver/core.d.ts +14 -20
- package/build/lib/basedriver/core.d.ts.map +1 -1
- package/build/lib/basedriver/core.js +32 -22
- 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 +38 -135
- 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 -15
- 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 +49 -0
- package/lib/basedriver/commands/execute.ts +40 -0
- package/lib/basedriver/commands/find.ts +80 -0
- package/lib/basedriver/commands/index.ts +7 -0
- package/lib/basedriver/commands/log.ts +34 -0
- package/lib/basedriver/commands/mixin.ts +15 -0
- package/lib/basedriver/commands/session.ts +36 -0
- package/lib/basedriver/commands/settings.ts +26 -0
- package/lib/basedriver/commands/timeout.ts +155 -0
- package/lib/basedriver/core.js +11 -28
- package/lib/basedriver/device-settings.js +9 -11
- package/lib/basedriver/{driver.js → driver.ts} +71 -180
- 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 +11 -7
- package/lib/basedriver/commands/event.js +0 -63
- package/lib/basedriver/commands/execute.js +0 -45
- package/lib/basedriver/commands/find.js +0 -108
- package/lib/basedriver/commands/index.js +0 -35
- package/lib/basedriver/commands/log.js +0 -64
- package/lib/basedriver/commands/session.js +0 -57
- package/lib/basedriver/commands/settings.js +0 -38
- package/lib/basedriver/commands/timeout.js +0 -168
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import {waitForCondition} from 'asyncbox';
|
|
2
|
+
import _ from 'lodash';
|
|
3
|
+
import {util} from '@appium/support';
|
|
4
|
+
import {errors} from '../../protocol';
|
|
5
|
+
import {BaseDriver} from '../driver';
|
|
6
|
+
import {Constraints, ITimeoutCommands} from '@appium/types';
|
|
7
|
+
import {mixin} from './mixin';
|
|
8
|
+
|
|
9
|
+
declare module '../driver' {
|
|
10
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
11
|
+
interface BaseDriver<C extends Constraints> extends ITimeoutCommands {}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const MIN_TIMEOUT = 0;
|
|
15
|
+
|
|
16
|
+
const TimeoutCommands: ITimeoutCommands = {
|
|
17
|
+
async timeouts<C extends Constraints>(this: BaseDriver<C>, type, ms, script, pageLoad, implicit) {
|
|
18
|
+
if (util.hasValue(type) && util.hasValue(ms)) {
|
|
19
|
+
this.log.debug(`MJSONWP timeout arguments: ${JSON.stringify({type, ms})}}`);
|
|
20
|
+
|
|
21
|
+
switch (type) {
|
|
22
|
+
case 'command':
|
|
23
|
+
await this.newCommandTimeout(ms);
|
|
24
|
+
return;
|
|
25
|
+
case 'implicit':
|
|
26
|
+
await this.implicitWaitMJSONWP(ms);
|
|
27
|
+
return;
|
|
28
|
+
case 'page load':
|
|
29
|
+
await this.pageLoadTimeoutMJSONWP(ms);
|
|
30
|
+
return;
|
|
31
|
+
case 'script':
|
|
32
|
+
await this.scriptTimeoutMJSONWP(ms);
|
|
33
|
+
return;
|
|
34
|
+
default:
|
|
35
|
+
throw new Error(`'${type}' type is not supported for MJSONWP timeout`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Otherwise assume it is W3C protocol
|
|
40
|
+
this.log.debug(
|
|
41
|
+
`W3C timeout argument: ${JSON.stringify({
|
|
42
|
+
script,
|
|
43
|
+
pageLoad,
|
|
44
|
+
implicit,
|
|
45
|
+
})}}`
|
|
46
|
+
);
|
|
47
|
+
if (util.hasValue(script)) {
|
|
48
|
+
await this.scriptTimeoutW3C(script);
|
|
49
|
+
}
|
|
50
|
+
if (util.hasValue(pageLoad)) {
|
|
51
|
+
await this.pageLoadTimeoutW3C(pageLoad);
|
|
52
|
+
}
|
|
53
|
+
if (util.hasValue(implicit)) {
|
|
54
|
+
await this.implicitWaitW3C(implicit);
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
async getTimeouts() {
|
|
59
|
+
return {
|
|
60
|
+
command: this.newCommandTimeoutMs,
|
|
61
|
+
implicit: this.implicitWaitMs,
|
|
62
|
+
};
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
// implicit
|
|
66
|
+
async implicitWaitW3C<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
67
|
+
await this.implicitWait(ms);
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
async implicitWaitMJSONWP<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
71
|
+
await this.implicitWait(ms);
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
async implicitWait<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
75
|
+
this.setImplicitWait(this.parseTimeoutArgument(ms));
|
|
76
|
+
},
|
|
77
|
+
|
|
78
|
+
// pageLoad
|
|
79
|
+
async pageLoadTimeoutW3C<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
80
|
+
throw new errors.NotImplementedError('Not implemented yet for pageLoad.');
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
async pageLoadTimeoutMJSONWP<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
84
|
+
throw new errors.NotImplementedError('Not implemented yet for pageLoad.');
|
|
85
|
+
},
|
|
86
|
+
|
|
87
|
+
// script
|
|
88
|
+
async scriptTimeoutW3C<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
89
|
+
throw new errors.NotImplementedError('Not implemented yet for script.');
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
async scriptTimeoutMJSONWP<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
93
|
+
throw new errors.NotImplementedError('Not implemented yet for script.');
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
// command
|
|
97
|
+
async newCommandTimeout<C extends Constraints>(this: BaseDriver<C>, ms) {
|
|
98
|
+
this.setNewCommandTimeout(this.parseTimeoutArgument(ms));
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
setImplicitWait<C extends Constraints>(this: BaseDriver<C>, ms: number) {
|
|
102
|
+
// eslint-disable-line require-await
|
|
103
|
+
this.implicitWaitMs = ms;
|
|
104
|
+
this.log.debug(`Set implicit wait to ${ms}ms`);
|
|
105
|
+
if (this.managedDrivers && this.managedDrivers.length) {
|
|
106
|
+
this.log.debug('Setting implicit wait on managed drivers');
|
|
107
|
+
for (const driver of this.managedDrivers) {
|
|
108
|
+
if (_.isFunction(driver.setImplicitWait)) {
|
|
109
|
+
driver.setImplicitWait(ms);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
setNewCommandTimeout<C extends Constraints>(this: BaseDriver<C>, ms: number) {
|
|
116
|
+
this.newCommandTimeoutMs = ms;
|
|
117
|
+
this.log.debug(`Set new command timeout to ${ms}ms`);
|
|
118
|
+
if (this.managedDrivers && this.managedDrivers.length) {
|
|
119
|
+
this.log.debug('Setting new command timeout on managed drivers');
|
|
120
|
+
for (const driver of this.managedDrivers) {
|
|
121
|
+
if (_.isFunction(driver.setNewCommandTimeout)) {
|
|
122
|
+
driver.setNewCommandTimeout(ms);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
|
|
128
|
+
async implicitWaitForCondition<C extends Constraints>(
|
|
129
|
+
this: BaseDriver<C>,
|
|
130
|
+
condFn: (...args: any[]) => Promise<any>
|
|
131
|
+
) {
|
|
132
|
+
this.log.debug(`Waiting up to ${this.implicitWaitMs} ms for condition`);
|
|
133
|
+
const wrappedCondFn = async (...args: any[]) => {
|
|
134
|
+
// reset command timeout
|
|
135
|
+
await this.clearNewCommandTimeout();
|
|
136
|
+
|
|
137
|
+
return await condFn(...args);
|
|
138
|
+
};
|
|
139
|
+
return await waitForCondition(wrappedCondFn, {
|
|
140
|
+
waitMs: this.implicitWaitMs,
|
|
141
|
+
intervalMs: 500,
|
|
142
|
+
logger: this.log,
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
parseTimeoutArgument<C extends Constraints>(this: BaseDriver<C>, ms: number | string) {
|
|
147
|
+
const duration = parseInt(String(ms), 10);
|
|
148
|
+
if (_.isNaN(duration) || duration < MIN_TIMEOUT) {
|
|
149
|
+
throw new errors.UnknownError(`Invalid timeout value '${ms}'`);
|
|
150
|
+
}
|
|
151
|
+
return duration;
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
mixin(TimeoutCommands);
|
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
|
/**
|
|
@@ -29,9 +27,6 @@ class DriverCore {
|
|
|
29
27
|
*/
|
|
30
28
|
static baseVersion = BASEDRIVER_VER;
|
|
31
29
|
|
|
32
|
-
/** @type {import('@appium/types').ExecuteMethodMap<DriverCore>} */
|
|
33
|
-
static executeMethodMap = {};
|
|
34
|
-
|
|
35
30
|
/**
|
|
36
31
|
* @type {string?}
|
|
37
32
|
*/
|
|
@@ -43,7 +38,7 @@ class DriverCore {
|
|
|
43
38
|
opts;
|
|
44
39
|
|
|
45
40
|
/**
|
|
46
|
-
* @type {
|
|
41
|
+
* @type {import('@appium/types').DriverOpts<C>}
|
|
47
42
|
*/
|
|
48
43
|
initialOpts;
|
|
49
44
|
|
|
@@ -101,7 +96,6 @@ class DriverCore {
|
|
|
101
96
|
_log;
|
|
102
97
|
|
|
103
98
|
/**
|
|
104
|
-
* @protected
|
|
105
99
|
* @type {boolean}
|
|
106
100
|
*/
|
|
107
101
|
shutdownUnexpectedly;
|
|
@@ -122,7 +116,7 @@ class DriverCore {
|
|
|
122
116
|
* we set it to an empty DeviceSettings instance here to make sure that the
|
|
123
117
|
* default settings are applied even if an extending driver doesn't utilize
|
|
124
118
|
* the settings functionality itself
|
|
125
|
-
* @type {DeviceSettings}
|
|
119
|
+
* @type {DeviceSettings<Settings>}
|
|
126
120
|
*/
|
|
127
121
|
settings;
|
|
128
122
|
|
|
@@ -187,11 +181,9 @@ class DriverCore {
|
|
|
187
181
|
* specific driver sessions. This data can be later used to adjust
|
|
188
182
|
* properties for driver instances running in parallel.
|
|
189
183
|
* Override it in inherited driver classes if necessary.
|
|
190
|
-
*
|
|
191
|
-
* @return {Record<string,unknown>} Driver properties mapping
|
|
192
184
|
*/
|
|
193
185
|
get driverData() {
|
|
194
|
-
return {};
|
|
186
|
+
return /** @type {import('@appium/types').DriverData} */ ({});
|
|
195
187
|
}
|
|
196
188
|
|
|
197
189
|
/**
|
|
@@ -263,7 +255,7 @@ class DriverCore {
|
|
|
263
255
|
* @returns {Core<C> | null}
|
|
264
256
|
*/
|
|
265
257
|
driverForSession(sessionId) {
|
|
266
|
-
return this;
|
|
258
|
+
return /** @type {Core<C> | null} */ (this);
|
|
267
259
|
}
|
|
268
260
|
|
|
269
261
|
isMjsonwpProtocol() {
|
|
@@ -451,19 +443,10 @@ export {DriverCore};
|
|
|
451
443
|
* @typedef {import('@appium/types').BaseDriverCapConstraints} BaseDriverCapConstraints
|
|
452
444
|
*/
|
|
453
445
|
|
|
454
|
-
/**
|
|
455
|
-
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
456
|
-
* @template {StringRecord|void} [Extra=void]
|
|
457
|
-
* @typedef {import('@appium/types').Capabilities<C, Extra>} Capabilities
|
|
458
|
-
*/
|
|
459
|
-
/**
|
|
460
|
-
* @template {StringRecord} [T={}]
|
|
461
|
-
* @typedef {import('@appium/types').W3CCapabilities<T>} W3CCapabilities
|
|
462
|
-
*/
|
|
463
|
-
|
|
464
446
|
/**
|
|
465
447
|
* @template {Constraints} C
|
|
466
|
-
* @
|
|
448
|
+
* @template {StringRecord} [S=StringRecord]
|
|
449
|
+
* @typedef {import('@appium/types').Core<C, S>} Core
|
|
467
450
|
*/
|
|
468
451
|
|
|
469
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
|
*/
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
/* eslint-disable require-await */
|
|
2
|
-
/* eslint-disable no-unused-vars */
|
|
3
|
-
|
|
4
1
|
import {validateCaps, processCapabilities} from './capabilities';
|
|
5
2
|
import {DriverCore} from './core';
|
|
6
3
|
import {util} from '@appium/support';
|
|
@@ -8,9 +5,22 @@ import B from 'bluebird';
|
|
|
8
5
|
import _ from 'lodash';
|
|
9
6
|
import {fixCaps, isW3cCaps} from '../helpers/capabilities';
|
|
10
7
|
import {DELETE_SESSION_COMMAND, determineProtocol, errors} from '../protocol';
|
|
11
|
-
import {createBaseDriverClass} from './commands';
|
|
12
8
|
import helpers from './helpers';
|
|
13
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
AppiumServer,
|
|
11
|
+
BaseDriverCapConstraints,
|
|
12
|
+
BASE_DESIRED_CAP_CONSTRAINTS,
|
|
13
|
+
Capabilities,
|
|
14
|
+
Constraints,
|
|
15
|
+
DefaultCreateSessionResult,
|
|
16
|
+
Driver,
|
|
17
|
+
DriverCaps,
|
|
18
|
+
DriverData,
|
|
19
|
+
DriverOpts,
|
|
20
|
+
ServerArgs,
|
|
21
|
+
StringRecord,
|
|
22
|
+
W3CDriverCaps,
|
|
23
|
+
} from '@appium/types';
|
|
14
24
|
|
|
15
25
|
const EVENT_SESSION_INIT = 'newSessionRequested';
|
|
16
26
|
const EVENT_SESSION_START = 'newSessionStarted';
|
|
@@ -18,55 +28,31 @@ const EVENT_SESSION_QUIT_START = 'quitSessionRequested';
|
|
|
18
28
|
const EVENT_SESSION_QUIT_DONE = 'quitSessionFinished';
|
|
19
29
|
const ON_UNEXPECTED_SHUTDOWN_EVENT = 'onUnexpectedShutdown';
|
|
20
30
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
originalCaps;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* @type {C}
|
|
45
|
-
*/
|
|
46
|
-
desiredCapConstraints;
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @type {DriverOpts<C> & DriverOpts<BaseDriverCapConstraints>}
|
|
50
|
-
*/
|
|
51
|
-
opts;
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
* @param {DriverOpts<C>} opts
|
|
56
|
-
* @param {boolean} shouldValidateCaps
|
|
57
|
-
*/
|
|
58
|
-
constructor(opts = /** @type {DriverOpts<C>} */ ({}), shouldValidateCaps = true) {
|
|
31
|
+
export class BaseDriver<
|
|
32
|
+
C extends Constraints,
|
|
33
|
+
CArgs extends StringRecord = StringRecord,
|
|
34
|
+
Settings extends StringRecord = StringRecord
|
|
35
|
+
>
|
|
36
|
+
extends DriverCore<C, Settings>
|
|
37
|
+
implements Driver<C, CArgs>
|
|
38
|
+
{
|
|
39
|
+
cliArgs: CArgs & ServerArgs;
|
|
40
|
+
|
|
41
|
+
caps: DriverCaps<C>;
|
|
42
|
+
originalCaps: W3CDriverCaps<C>;
|
|
43
|
+
desiredCapConstraints: C;
|
|
44
|
+
opts: DriverOpts<C>;
|
|
45
|
+
server?: AppiumServer;
|
|
46
|
+
serverHost?: string;
|
|
47
|
+
serverPort?: number;
|
|
48
|
+
serverPath?: string;
|
|
49
|
+
|
|
50
|
+
constructor(opts: DriverOpts<C>, shouldValidateCaps = true) {
|
|
59
51
|
super(opts, shouldValidateCaps);
|
|
60
52
|
|
|
61
|
-
|
|
62
|
-
* This must be assigned here because the declaration of {@linkcode BaseDriverCore.opts} above
|
|
63
|
-
* blows away {@linkcode DriverCore.opts}.
|
|
64
|
-
*/
|
|
65
|
-
this.opts = opts;
|
|
66
|
-
|
|
67
|
-
this.caps = {};
|
|
53
|
+
this.caps = {} as DriverCaps<C>;
|
|
68
54
|
|
|
69
|
-
this.cliArgs =
|
|
55
|
+
this.cliArgs = {} as CArgs & ServerArgs;
|
|
70
56
|
}
|
|
71
57
|
|
|
72
58
|
/**
|
|
@@ -75,25 +61,20 @@ export class BaseDriverCore extends DriverCore {
|
|
|
75
61
|
* Subclasses _shouldn't_ need to use this. If you need to use this, please create
|
|
76
62
|
* an issue:
|
|
77
63
|
* @see https://github.com/appium/appium/issues/new
|
|
78
|
-
* @type {Readonly<BaseDriverCapConstraints & C>}
|
|
79
|
-
* @protected
|
|
80
64
|
*/
|
|
81
|
-
get _desiredCapConstraints() {
|
|
65
|
+
protected get _desiredCapConstraints(): Readonly<BaseDriverCapConstraints & C> {
|
|
82
66
|
return Object.freeze(_.merge({}, BASE_DESIRED_CAP_CONSTRAINTS, this.desiredCapConstraints));
|
|
83
67
|
}
|
|
84
68
|
|
|
85
|
-
// This is the main command handler for the driver. It wraps command
|
|
86
|
-
// execution with timeout logic, checking that we have a valid session,
|
|
87
|
-
// and ensuring that we execute commands one at a time. This method is called
|
|
88
|
-
// by MJSONWP's express router.
|
|
89
69
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
70
|
+
* This is the main command handler for the driver. It wraps command
|
|
71
|
+
* execution with timeout logic, checking that we have a valid session,
|
|
72
|
+
* and ensuring that we execute commands one at a time. This method is called
|
|
73
|
+
* by MJSONWP's express router.
|
|
93
74
|
*/
|
|
94
|
-
async executeCommand(cmd, ...args) {
|
|
75
|
+
async executeCommand<T = unknown>(cmd: string, ...args: any[]): Promise<T> {
|
|
95
76
|
// get start time for this command, and log in special cases
|
|
96
|
-
|
|
77
|
+
const startTime = Date.now();
|
|
97
78
|
|
|
98
79
|
if (cmd === 'createSession') {
|
|
99
80
|
// If creating a session determine if W3C or MJSONWP protocol was requested and remember the choice
|
|
@@ -161,12 +142,8 @@ export class BaseDriverCore extends DriverCore {
|
|
|
161
142
|
return res;
|
|
162
143
|
}
|
|
163
144
|
|
|
164
|
-
/**
|
|
165
|
-
*
|
|
166
|
-
* @param {Error|import('../protocol/errors').NoSuchDriverError} err
|
|
167
|
-
*/
|
|
168
145
|
async startUnexpectedShutdown(
|
|
169
|
-
err = new errors.NoSuchDriverError('The driver was unexpectedly shut down!')
|
|
146
|
+
err: Error = new errors.NoSuchDriverError('The driver was unexpectedly shut down!')
|
|
170
147
|
) {
|
|
171
148
|
this.eventEmitter.emit(ON_UNEXPECTED_SHUTDOWN_EVENT, err); // allow others to listen for this
|
|
172
149
|
this.shutdownUnexpectedly = true;
|
|
@@ -200,14 +177,7 @@ export class BaseDriverCore extends DriverCore {
|
|
|
200
177
|
}, this.newCommandTimeoutMs);
|
|
201
178
|
}
|
|
202
179
|
|
|
203
|
-
|
|
204
|
-
*
|
|
205
|
-
* @param {import('@appium/types').AppiumServer} server
|
|
206
|
-
* @param {string} host
|
|
207
|
-
* @param {number} port
|
|
208
|
-
* @param {string} path
|
|
209
|
-
*/
|
|
210
|
-
assignServer(server, host, port, path) {
|
|
180
|
+
assignServer(server: AppiumServer, host: string, port: number, path: string) {
|
|
211
181
|
this.server = server;
|
|
212
182
|
this.serverHost = host;
|
|
213
183
|
this.serverPort = port;
|
|
@@ -223,8 +193,8 @@ export class BaseDriverCore extends DriverCore {
|
|
|
223
193
|
this.log.debug('Running generic full reset');
|
|
224
194
|
|
|
225
195
|
// preserving state
|
|
226
|
-
|
|
227
|
-
for (
|
|
196
|
+
const currentConfig = {};
|
|
197
|
+
for (const property of [
|
|
228
198
|
'implicitWaitMs',
|
|
229
199
|
'newCommandTimeoutMs',
|
|
230
200
|
'sessionId',
|
|
@@ -233,9 +203,6 @@ export class BaseDriverCore extends DriverCore {
|
|
|
233
203
|
currentConfig[property] = this[property];
|
|
234
204
|
}
|
|
235
205
|
|
|
236
|
-
// We also need to preserve the unexpected shutdown, and make sure it is not cancelled during reset.
|
|
237
|
-
this.resetOnUnexpectedShutdown = () => {};
|
|
238
|
-
|
|
239
206
|
try {
|
|
240
207
|
if (this.sessionId !== null) {
|
|
241
208
|
await this.deleteSession(this.sessionId);
|
|
@@ -244,7 +211,7 @@ export class BaseDriverCore extends DriverCore {
|
|
|
244
211
|
await this.createSession(this.originalCaps);
|
|
245
212
|
} finally {
|
|
246
213
|
// always restore state.
|
|
247
|
-
for (
|
|
214
|
+
for (const [key, value] of _.toPairs(currentConfig)) {
|
|
248
215
|
this[key] = value;
|
|
249
216
|
}
|
|
250
217
|
}
|
|
@@ -257,13 +224,14 @@ export class BaseDriverCore extends DriverCore {
|
|
|
257
224
|
* Appium 2 has dropped the support of these, so now we only accept capability
|
|
258
225
|
* objects in W3C format and thus allow any of the three arguments to represent
|
|
259
226
|
* the latter.
|
|
260
|
-
* @param {W3CCapabilities<C>} w3cCapabilities1
|
|
261
|
-
* @param {W3CCapabilities<C>} [w3cCapabilities2]
|
|
262
|
-
* @param {W3CCapabilities<C>} [w3cCapabilities]
|
|
263
|
-
* @param {DriverData[]} [driverData]
|
|
264
|
-
* @returns {Promise<[string,Capabilities<C>]>}
|
|
265
227
|
*/
|
|
266
|
-
async createSession(
|
|
228
|
+
async createSession(
|
|
229
|
+
w3cCapabilities1: W3CDriverCaps<C>,
|
|
230
|
+
w3cCapabilities2?: W3CDriverCaps<C>,
|
|
231
|
+
w3cCapabilities?: W3CDriverCaps<C>,
|
|
232
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
233
|
+
driverData?: DriverData[]
|
|
234
|
+
): Promise<DefaultCreateSessionResult<C>> {
|
|
267
235
|
if (this.sessionId !== null) {
|
|
268
236
|
throw new errors.SessionNotCreatedError(
|
|
269
237
|
'Cannot create a new session while one is in progress'
|
|
@@ -289,15 +257,14 @@ export class BaseDriverCore extends DriverCore {
|
|
|
289
257
|
`Creating session with W3C capabilities: ${JSON.stringify(originalCaps, null, 2)}`
|
|
290
258
|
);
|
|
291
259
|
|
|
292
|
-
|
|
293
|
-
let caps;
|
|
260
|
+
let caps: DriverCaps<C>;
|
|
294
261
|
try {
|
|
295
262
|
caps = processCapabilities(
|
|
296
263
|
originalCaps,
|
|
297
264
|
this._desiredCapConstraints,
|
|
298
265
|
this.shouldValidateCaps
|
|
299
|
-
)
|
|
300
|
-
caps = fixCaps(caps, this._desiredCapConstraints, this.log)
|
|
266
|
+
) as DriverCaps<C>;
|
|
267
|
+
caps = fixCaps(caps, this._desiredCapConstraints, this.log) as DriverCaps<C>;
|
|
301
268
|
} catch (e) {
|
|
302
269
|
throw new errors.SessionNotCreatedError(e.message);
|
|
303
270
|
}
|
|
@@ -334,7 +301,7 @@ export class BaseDriverCore extends DriverCore {
|
|
|
334
301
|
}
|
|
335
302
|
|
|
336
303
|
if (!_.isUndefined(this.caps.newCommandTimeout)) {
|
|
337
|
-
this.newCommandTimeoutMs =
|
|
304
|
+
this.newCommandTimeoutMs = (this.caps.newCommandTimeout as number) * 1000;
|
|
338
305
|
}
|
|
339
306
|
|
|
340
307
|
this._log.prefix = helpers.generateDriverLogPrefix(this, this.sessionId);
|
|
@@ -344,32 +311,23 @@ export class BaseDriverCore extends DriverCore {
|
|
|
344
311
|
return [this.sessionId, caps];
|
|
345
312
|
}
|
|
346
313
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
* @param {string} [sessionId]
|
|
350
|
-
* @param {DriverData[]} [driverData]
|
|
351
|
-
* @returns {Promise<void>}
|
|
352
|
-
*/
|
|
353
|
-
async deleteSession(sessionId, driverData) {
|
|
314
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
315
|
+
async deleteSession(sessionId?: string | null) {
|
|
354
316
|
await this.clearNewCommandTimeout();
|
|
355
317
|
if (this.isCommandsQueueEnabled && this.commandsQueueGuard.isBusy()) {
|
|
356
318
|
// simple hack to release pending commands if they exist
|
|
357
|
-
// @ts-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
319
|
+
// @ts-expect-error private API
|
|
320
|
+
const queues = this.commandsQueueGuard.queues;
|
|
321
|
+
for (const key of _.keys(queues)) {
|
|
322
|
+
queues[key] = [];
|
|
361
323
|
}
|
|
362
324
|
}
|
|
363
325
|
this.sessionId = null;
|
|
364
326
|
this._log.prefix = helpers.generateDriverLogPrefix(this);
|
|
365
327
|
}
|
|
366
328
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
* @param {Capabilities<C>} caps
|
|
370
|
-
*/
|
|
371
|
-
logExtraCaps(caps) {
|
|
372
|
-
let extraCaps = _.difference(_.keys(caps), _.keys(this._desiredCapConstraints));
|
|
329
|
+
logExtraCaps(caps: Capabilities<C>) {
|
|
330
|
+
const extraCaps = _.difference(_.keys(caps), _.keys(this._desiredCapConstraints));
|
|
373
331
|
if (extraCaps.length) {
|
|
374
332
|
this.log.warn(
|
|
375
333
|
`The following capabilities were provided, but are not ` + `recognized by Appium:`
|
|
@@ -380,12 +338,7 @@ export class BaseDriverCore extends DriverCore {
|
|
|
380
338
|
}
|
|
381
339
|
}
|
|
382
340
|
|
|
383
|
-
|
|
384
|
-
*
|
|
385
|
-
* @param {Capabilities<C>} caps
|
|
386
|
-
* @returns {boolean}
|
|
387
|
-
*/
|
|
388
|
-
validateDesiredCaps(caps) {
|
|
341
|
+
validateDesiredCaps(caps: any): caps is DriverCaps<C> {
|
|
389
342
|
if (!this.shouldValidateCaps) {
|
|
390
343
|
return true;
|
|
391
344
|
}
|
|
@@ -407,68 +360,6 @@ export class BaseDriverCore extends DriverCore {
|
|
|
407
360
|
}
|
|
408
361
|
}
|
|
409
362
|
|
|
410
|
-
|
|
411
|
-
* This ensures that all of the mixins correctly implement the interface described in {@linkcode Driver}.
|
|
412
|
-
* @template {Constraints} [C={}]
|
|
413
|
-
* @implements {Driver<C>}
|
|
414
|
-
*/
|
|
415
|
-
export class BaseDriver extends createBaseDriverClass(BaseDriverCore) {}
|
|
416
|
-
export default BaseDriver;
|
|
363
|
+
export * from './commands';
|
|
417
364
|
|
|
418
|
-
|
|
419
|
-
* @typedef {import('@appium/types').HTTPMethod} HTTPMethod
|
|
420
|
-
* @typedef {import('@appium/types').DriverData} DriverData
|
|
421
|
-
* @typedef {import('@appium/types').Constraints} Constraints
|
|
422
|
-
* @typedef {import('@appium/types').Constraint} Constraint
|
|
423
|
-
* @typedef {import('@appium/types').StringRecord} StringRecord
|
|
424
|
-
* @typedef {import('@appium/types').BaseDriverCapConstraints} BaseDriverCapConstraints
|
|
425
|
-
* @typedef {import('@appium/types').ServerArgs} ServerArgs
|
|
426
|
-
*/
|
|
427
|
-
|
|
428
|
-
/**
|
|
429
|
-
* @callback UpdateServerCallback
|
|
430
|
-
* @param {import('express').Express} app - Express app
|
|
431
|
-
* @param {import('@appium/types').AppiumServer} httpServer - HTTP server
|
|
432
|
-
* @returns {import('type-fest').Promisable<void>}
|
|
433
|
-
*/
|
|
434
|
-
|
|
435
|
-
/**
|
|
436
|
-
* This is used to extend {@linkcode BaseDriverCore} by the mixins and also external drivers.
|
|
437
|
-
* @template {Constraints} C
|
|
438
|
-
* @template [Proto={}]
|
|
439
|
-
* @template [Static={}]
|
|
440
|
-
* @typedef {import('@appium/types').Class<BaseDriverCore<C> & Proto,import('@appium/types').DriverStatic & Static>} BaseDriverBase
|
|
441
|
-
*/
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
445
|
-
* @typedef {import('@appium/types').SessionHandler<[string, object],void, C>} SessionHandler
|
|
446
|
-
*/
|
|
447
|
-
|
|
448
|
-
/**
|
|
449
|
-
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
450
|
-
* @template {StringRecord|void} [Extra=void]
|
|
451
|
-
* @typedef {import('@appium/types').Capabilities<C, Extra>} Capabilities
|
|
452
|
-
*/
|
|
453
|
-
|
|
454
|
-
/**
|
|
455
|
-
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
456
|
-
* @template {StringRecord|void} [Extra=void]
|
|
457
|
-
* @typedef {import('@appium/types').W3CCapabilities<C, Extra>} W3CCapabilities
|
|
458
|
-
*/
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
462
|
-
* @template {StringRecord} [CArgs=StringRecord]
|
|
463
|
-
* @typedef {import('@appium/types').Driver<C, CArgs>} Driver
|
|
464
|
-
*/
|
|
465
|
-
|
|
466
|
-
/**
|
|
467
|
-
* @template {Constraints} C
|
|
468
|
-
* @typedef {import('@appium/types').ExternalDriver<C>} ExternalDriver
|
|
469
|
-
*/
|
|
470
|
-
|
|
471
|
-
/**
|
|
472
|
-
* @template {Constraints} C
|
|
473
|
-
* @typedef {import('@appium/types').DriverOpts<C>} DriverOpts
|
|
474
|
-
*/
|
|
365
|
+
export default BaseDriver;
|