appium 2.0.0-beta.44 → 2.0.0-beta.45
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/appium.d.ts +137 -14
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +5 -5
- package/build/lib/appium.js.map +1 -0
- package/build/lib/cli/args.js +3 -3
- package/build/lib/cli/args.js.map +1 -0
- package/build/lib/cli/driver-command.js +3 -3
- package/build/lib/cli/driver-command.js.map +1 -0
- package/build/lib/cli/extension-command.js +3 -3
- package/build/lib/cli/extension-command.js.map +1 -0
- package/build/lib/cli/extension.js +3 -3
- package/build/lib/cli/extension.js.map +1 -0
- package/build/lib/cli/parser.js +3 -3
- package/build/lib/cli/parser.js.map +1 -0
- package/build/lib/cli/plugin-command.js +3 -3
- package/build/lib/cli/plugin-command.js.map +1 -0
- package/build/lib/cli/utils.js +3 -3
- package/build/lib/cli/utils.js.map +1 -0
- package/build/lib/config-file.js +3 -3
- package/build/lib/config-file.js.map +1 -0
- package/build/lib/config.js +3 -3
- package/build/lib/config.js.map +1 -0
- package/build/lib/constants.js +3 -3
- package/build/lib/constants.js.map +1 -0
- package/build/lib/extension/driver-config.d.ts +3 -2
- package/build/lib/extension/driver-config.d.ts.map +1 -1
- package/build/lib/extension/driver-config.js +3 -3
- package/build/lib/extension/driver-config.js.map +1 -0
- package/build/lib/extension/extension-config.js +3 -3
- package/build/lib/extension/extension-config.js.map +1 -0
- package/build/lib/extension/index.js +3 -3
- package/build/lib/extension/index.js.map +1 -0
- package/build/lib/extension/manifest.d.ts +1 -2
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +35 -30
- package/build/lib/extension/manifest.js.map +1 -0
- package/build/lib/extension/package-changed.js +3 -3
- package/build/lib/extension/package-changed.js.map +1 -0
- package/build/lib/extension/plugin-config.js +3 -3
- package/build/lib/extension/plugin-config.js.map +1 -0
- package/build/lib/grid-register.js +3 -3
- package/build/lib/grid-register.js.map +1 -0
- package/build/lib/logger.js.map +1 -0
- package/build/lib/logsink.js +3 -3
- package/build/lib/logsink.js.map +1 -0
- package/build/lib/main.js +3 -3
- package/build/lib/main.js.map +1 -0
- package/build/lib/schema/arg-spec.js +3 -3
- package/build/lib/schema/arg-spec.js.map +1 -0
- package/build/lib/schema/cli-args.js +3 -3
- package/build/lib/schema/cli-args.js.map +1 -0
- package/build/lib/schema/cli-transformers.d.ts +1 -1
- package/build/lib/schema/cli-transformers.d.ts.map +1 -1
- package/build/lib/schema/cli-transformers.js +23 -18
- package/build/lib/schema/cli-transformers.js.map +1 -0
- package/build/lib/schema/index.js.map +1 -0
- package/build/lib/schema/keywords.js.map +1 -0
- package/build/lib/schema/schema.js +3 -3
- package/build/lib/schema/schema.js.map +1 -0
- package/build/lib/utils.d.ts +288 -27
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +7 -35
- package/build/lib/utils.js.map +1 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/lib/appium.js +27 -18
- package/lib/extension/driver-config.js +2 -1
- package/lib/extension/manifest.js +49 -32
- package/lib/schema/cli-transformers.js +27 -24
- package/lib/utils.js +87 -66
- package/package.json +16 -15
package/lib/appium.js
CHANGED
|
@@ -14,13 +14,9 @@ import AsyncLock from 'async-lock';
|
|
|
14
14
|
import {parseCapsForInnerDriver, pullSettings} from './utils';
|
|
15
15
|
import {util, node, logger} from '@appium/support';
|
|
16
16
|
import {getDefaultsForExtension} from './schema';
|
|
17
|
-
import {DRIVER_TYPE
|
|
17
|
+
import {DRIVER_TYPE} from './constants';
|
|
18
18
|
|
|
19
|
-
/**
|
|
20
|
-
* Invariant set of base constraints
|
|
21
|
-
* @type {Readonly<Constraints>}
|
|
22
|
-
*/
|
|
23
|
-
const desiredCapabilityConstraints = Object.freeze({
|
|
19
|
+
const desiredCapabilityConstraints = /** @type {const} */ ({
|
|
24
20
|
automationName: {
|
|
25
21
|
presence: true,
|
|
26
22
|
isString: true,
|
|
@@ -30,6 +26,9 @@ const desiredCapabilityConstraints = Object.freeze({
|
|
|
30
26
|
isString: true,
|
|
31
27
|
},
|
|
32
28
|
});
|
|
29
|
+
/**
|
|
30
|
+
* @typedef {typeof desiredCapabilityConstraints} AppiumDriverConstraints
|
|
31
|
+
*/
|
|
33
32
|
|
|
34
33
|
const sessionsListGuard = new AsyncLock();
|
|
35
34
|
const pendingDriversGuard = new AsyncLock();
|
|
@@ -181,10 +180,10 @@ class AppiumDriver extends DriverCore {
|
|
|
181
180
|
/**
|
|
182
181
|
* Retrieves all CLI arguments for a specific plugin.
|
|
183
182
|
* @param {string} extName - Plugin name
|
|
184
|
-
* @returns {
|
|
183
|
+
* @returns {StringRecord} Arguments object. If none, an empty object.
|
|
185
184
|
*/
|
|
186
185
|
getCliArgsForPlugin(extName) {
|
|
187
|
-
return /** @type {
|
|
186
|
+
return /** @type {StringRecord} */ (this.args.plugin?.[extName] ?? {});
|
|
188
187
|
}
|
|
189
188
|
|
|
190
189
|
/**
|
|
@@ -194,12 +193,10 @@ class AppiumDriver extends DriverCore {
|
|
|
194
193
|
*
|
|
195
194
|
* _Note that this behavior currently (May 18 2022) differs from how plugins are handled_ (see {@linkcode AppiumDriver.getCliArgsForPlugin}).
|
|
196
195
|
* @param {string} extName - Driver name
|
|
197
|
-
* @returns {
|
|
196
|
+
* @returns {StringRecord|undefined} Arguments object. If none, `undefined`
|
|
198
197
|
*/
|
|
199
198
|
getCliArgsForDriver(extName) {
|
|
200
|
-
const allCliArgsForExt = /** @type {
|
|
201
|
-
this.args.driver?.[extName]
|
|
202
|
-
);
|
|
199
|
+
const allCliArgsForExt = /** @type {StringRecord|undefined} */ (this.args.driver?.[extName]);
|
|
203
200
|
|
|
204
201
|
if (!_.isEmpty(allCliArgsForExt)) {
|
|
205
202
|
const defaults = getDefaultsForExtension(DRIVER_TYPE, extName);
|
|
@@ -214,9 +211,9 @@ class AppiumDriver extends DriverCore {
|
|
|
214
211
|
|
|
215
212
|
/**
|
|
216
213
|
* Create a new session
|
|
217
|
-
* @param {W3CCapabilities} jsonwpCaps JSONWP formatted desired capabilities
|
|
218
|
-
* @param {W3CCapabilities} reqCaps Required capabilities (JSONWP standard)
|
|
219
|
-
* @param {W3CCapabilities} w3cCapabilities W3C capabilities
|
|
214
|
+
* @param {W3CCapabilities<AppiumDriverConstraints>} jsonwpCaps JSONWP formatted desired capabilities
|
|
215
|
+
* @param {W3CCapabilities<AppiumDriverConstraints>} reqCaps Required capabilities (JSONWP standard)
|
|
216
|
+
* @param {W3CCapabilities<AppiumDriverConstraints>} w3cCapabilities W3C capabilities
|
|
220
217
|
* @param {DriverData[]} [driverData]
|
|
221
218
|
*/
|
|
222
219
|
async createSession(jsonwpCaps, reqCaps, w3cCapabilities, driverData) {
|
|
@@ -249,9 +246,11 @@ class AppiumDriver extends DriverCore {
|
|
|
249
246
|
);
|
|
250
247
|
|
|
251
248
|
const {desiredCaps, processedJsonwpCapabilities, processedW3CCapabilities} =
|
|
252
|
-
/** @type {import('./utils').ParsedDriverCaps} */ (parsedCaps);
|
|
249
|
+
/** @type {import('./utils').ParsedDriverCaps<AppiumDriverConstraints>} */ (parsedCaps);
|
|
253
250
|
protocol = parsedCaps.protocol;
|
|
254
|
-
const error = /** @type {import('./utils').InvalidCaps} */ (
|
|
251
|
+
const error = /** @type {import('./utils').InvalidCaps<AppiumDriverConstraints>} */ (
|
|
252
|
+
parsedCaps
|
|
253
|
+
).error;
|
|
255
254
|
// If the parsing of the caps produced an error, throw it in here
|
|
256
255
|
if (error) {
|
|
257
256
|
throw error;
|
|
@@ -831,7 +830,6 @@ export {AppiumDriver};
|
|
|
831
830
|
* @typedef {import('@appium/types').ExternalDriver} ExternalDriver
|
|
832
831
|
* @typedef {import('@appium/types').Driver} Driver
|
|
833
832
|
* @typedef {import('@appium/types').DriverClass} DriverClass
|
|
834
|
-
* @typedef {import('@appium/types').W3CCapabilities} W3CCapabilities
|
|
835
833
|
* @typedef {import('@appium/types').DriverData} DriverData
|
|
836
834
|
* @typedef {import('@appium/types').ServerArgs} DriverOpts
|
|
837
835
|
* @typedef {import('@appium/types').Constraints} Constraints
|
|
@@ -842,6 +840,7 @@ export {AppiumDriver};
|
|
|
842
840
|
* @typedef {import('@appium/types').PluginClass} PluginClass
|
|
843
841
|
* @typedef {import('@appium/types').PluginType} PluginType
|
|
844
842
|
* @typedef {import('@appium/types').DriverType} DriverType
|
|
843
|
+
* @typedef {import('@appium/types').StringRecord} StringRecord
|
|
845
844
|
* @typedef {import('@appium/types').SessionHandler<SessionHandlerResult<any[]>,SessionHandlerResult<void>>} SessionHandler
|
|
846
845
|
*/
|
|
847
846
|
|
|
@@ -854,3 +853,13 @@ export {AppiumDriver};
|
|
|
854
853
|
* @property {Error} [error]
|
|
855
854
|
* @property {string} [protocol]
|
|
856
855
|
*/
|
|
856
|
+
|
|
857
|
+
/**
|
|
858
|
+
* @template {Constraints} C
|
|
859
|
+
* @typedef {import('@appium/types').W3CCapabilities<C>} W3CCapabilities
|
|
860
|
+
*/
|
|
861
|
+
|
|
862
|
+
/**
|
|
863
|
+
* @template {Constraints} C
|
|
864
|
+
* @typedef {import('@appium/types').Capabilities<C>} Capabilities
|
|
865
|
+
*/
|
|
@@ -133,7 +133,8 @@ export class DriverConfig extends ExtensionConfig {
|
|
|
133
133
|
|
|
134
134
|
/**
|
|
135
135
|
* Given capabilities, find a matching driver within the config. Load its class and return it along with version and driver name.
|
|
136
|
-
* @
|
|
136
|
+
* @template {import('@appium/types').StringRecord} C
|
|
137
|
+
* @param {C} caps
|
|
137
138
|
* @returns {MatchedDriver}
|
|
138
139
|
*/
|
|
139
140
|
findMatchingDriver({automationName, platformName}) {
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* Module containing {@link Manifest} which handles reading & writing of extension config files.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import B from 'bluebird';
|
|
6
|
+
import glob from 'glob';
|
|
5
7
|
import {env, fs} from '@appium/support';
|
|
6
8
|
import _ from 'lodash';
|
|
7
9
|
import path from 'path';
|
|
@@ -11,23 +13,6 @@ import log from '../logger';
|
|
|
11
13
|
import {INSTALL_TYPE_NPM} from './extension-config';
|
|
12
14
|
import {packageDidChange} from './package-changed';
|
|
13
15
|
|
|
14
|
-
/**
|
|
15
|
-
* Default depth to search in directory tree for whatever it is we're looking for.
|
|
16
|
-
*
|
|
17
|
-
* It's 4 because smaller numbers didn't work.
|
|
18
|
-
*/
|
|
19
|
-
const DEFAULT_SEARCH_DEPTH = 4;
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Default options for {@link findExtensions}.
|
|
23
|
-
* @type {Readonly<import('klaw').Options>}
|
|
24
|
-
*/
|
|
25
|
-
const DEFAULT_FIND_EXTENSIONS_OPTS = Object.freeze({
|
|
26
|
-
depthLimit: DEFAULT_SEARCH_DEPTH,
|
|
27
|
-
/* istanbul ignore next */
|
|
28
|
-
filter: (filepath) => !path.basename(filepath).startsWith('.'),
|
|
29
|
-
});
|
|
30
|
-
|
|
31
16
|
/**
|
|
32
17
|
* Current configuration schema revision!
|
|
33
18
|
*/
|
|
@@ -175,26 +160,58 @@ export class Manifest {
|
|
|
175
160
|
|
|
176
161
|
/**
|
|
177
162
|
* Searches `APPIUM_HOME` for installed extensions and adds them to the manifest.
|
|
178
|
-
* @param {SyncWithInstalledExtensionsOpts} opts
|
|
179
163
|
* @returns {Promise<boolean>} `true` if any extensions were added, `false` otherwise.
|
|
180
164
|
*/
|
|
181
|
-
async syncWithInstalledExtensions(
|
|
182
|
-
const walkOpts = _.defaults({depthLimit}, DEFAULT_FIND_EXTENSIONS_OPTS);
|
|
165
|
+
async syncWithInstalledExtensions() {
|
|
183
166
|
// this could be parallelized, but we can't use fs.walk as an async iterator
|
|
184
167
|
let didChange = false;
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Listener for the `match` event of a `glob` instance
|
|
171
|
+
* @param {string} filepath - Path to a `package.json`
|
|
172
|
+
* @returns {Promise<void>}
|
|
173
|
+
*/
|
|
174
|
+
const onMatch = async (filepath) => {
|
|
175
|
+
try {
|
|
176
|
+
const pkg = JSON.parse(await fs.readFile(filepath, 'utf8'));
|
|
177
|
+
if (isDriver(pkg) || isPlugin(pkg)) {
|
|
178
|
+
const changed = this.addExtensionFromPackage(pkg, filepath);
|
|
179
|
+
didChange = didChange || changed;
|
|
180
|
+
}
|
|
181
|
+
} catch {}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* A list of `Promise`s which read `package.json` files looking for Appium extensions.
|
|
186
|
+
* @type {Promise<void>[]}
|
|
187
|
+
*/
|
|
188
|
+
const queue = [
|
|
189
|
+
// look at `package.json` in `APPIUM_HOME` only
|
|
190
|
+
onMatch(path.join(this._appiumHome, 'package.json')),
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
// add dependencies to the queue
|
|
194
|
+
await new B((resolve, reject) => {
|
|
195
|
+
glob(
|
|
196
|
+
'node_modules/{*,@*/*}/package.json',
|
|
197
|
+
{cwd: this._appiumHome, silent: true, absolute: true},
|
|
198
|
+
// eslint-disable-next-line promise/prefer-await-to-callbacks
|
|
199
|
+
(err) => {
|
|
200
|
+
if (err) {
|
|
201
|
+
reject(err);
|
|
194
202
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
203
|
+
resolve();
|
|
204
|
+
}
|
|
205
|
+
)
|
|
206
|
+
.on('error', reject)
|
|
207
|
+
.on('match', (filepath) => {
|
|
208
|
+
queue.push(onMatch(filepath));
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// wait for everything to finish
|
|
213
|
+
await B.all(queue);
|
|
214
|
+
|
|
198
215
|
return didChange;
|
|
199
216
|
}
|
|
200
217
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {ArgumentTypeError} from 'argparse';
|
|
2
|
-
import {readFileSync} from 'fs';
|
|
2
|
+
import {readFileSync, existsSync} from 'fs';
|
|
3
3
|
import _ from 'lodash';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -55,25 +55,30 @@ export const transformers = {
|
|
|
55
55
|
/**
|
|
56
56
|
* Given a CSV-style string or pathname, parse it into an array.
|
|
57
57
|
* The file can also be split on newlines.
|
|
58
|
-
* @param {string}
|
|
58
|
+
* @param {string} csvOrPath
|
|
59
59
|
* @returns {string[]}
|
|
60
60
|
*/
|
|
61
|
-
csv: (
|
|
62
|
-
let
|
|
61
|
+
csv: (csvOrPath) => {
|
|
62
|
+
let csv = csvOrPath;
|
|
63
|
+
let loadedFromFile = false;
|
|
63
64
|
// since this value could be a single string (no commas) _or_ a pathname, we will need
|
|
64
65
|
// to attempt to parse it as a file _first_.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
throw new ArgumentTypeError(`Could not read file ${
|
|
66
|
+
if (existsSync(csvOrPath)) {
|
|
67
|
+
try {
|
|
68
|
+
csv = readFileSync(csvOrPath, 'utf8');
|
|
69
|
+
} catch (err) {
|
|
70
|
+
throw new ArgumentTypeError(`Could not read file '${csvOrPath}': ${err.message}`);
|
|
70
71
|
}
|
|
72
|
+
loadedFromFile = true;
|
|
71
73
|
}
|
|
72
74
|
|
|
73
75
|
try {
|
|
74
|
-
return
|
|
76
|
+
return loadedFromFile ? parseCsvFile(csv) : parseCsvLine(csv);
|
|
75
77
|
} catch (err) {
|
|
76
|
-
|
|
78
|
+
const msg = loadedFromFile
|
|
79
|
+
? `The provided value of '${csvOrPath}' must be a valid CSV`
|
|
80
|
+
: `Must be a comma-delimited string, e.g., "foo,bar,baz"`;
|
|
81
|
+
throw new TypeError(`${msg}. Original error: ${err.message}`);
|
|
77
82
|
}
|
|
78
83
|
},
|
|
79
84
|
|
|
@@ -85,20 +90,18 @@ export const transformers = {
|
|
|
85
90
|
json: (jsonOrPath) => {
|
|
86
91
|
let json = jsonOrPath;
|
|
87
92
|
let loadedFromFile = false;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
// also `ENAMETOOLONG` can happen if we try to open a file that's a huge JSON string.
|
|
99
|
-
if (err.code !== 'ENOENT' && err.code !== 'ENAMETOOLONG') {
|
|
100
|
-
throw err;
|
|
93
|
+
if (existsSync(jsonOrPath)) {
|
|
94
|
+
try {
|
|
95
|
+
// use synchronous file access, as `argparse` provides no way of either
|
|
96
|
+
// awaiting or using callbacks. This step happens in startup, in what is
|
|
97
|
+
// effectively command-line code, so nothing is blocked in terms of
|
|
98
|
+
// sessions, so holding up the event loop does not incur the usual
|
|
99
|
+
// drawbacks.
|
|
100
|
+
json = readFileSync(jsonOrPath, 'utf8');
|
|
101
|
+
} catch (err) {
|
|
102
|
+
throw new ArgumentTypeError(`Could not read file '${jsonOrPath}': ${err.message}`);
|
|
101
103
|
}
|
|
104
|
+
loadedFromFile = true;
|
|
102
105
|
}
|
|
103
106
|
try {
|
|
104
107
|
const result = JSON.parse(json);
|
package/lib/utils.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
2
|
import logger from './logger';
|
|
3
|
-
import {processCapabilities, PROTOCOLS} from '@appium/base-driver';
|
|
3
|
+
import {processCapabilities, PROTOCOLS, STANDARD_CAPS} from '@appium/base-driver';
|
|
4
4
|
import {inspect as dump} from 'util';
|
|
5
5
|
import {node} from '@appium/support';
|
|
6
6
|
import path from 'path';
|
|
7
7
|
|
|
8
8
|
const W3C_APPIUM_PREFIX = 'appium';
|
|
9
|
+
const STANDARD_CAPS_LOWERCASE = new Set([...STANDARD_CAPS].map((cap) => cap.toLowerCase()));
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
*
|
|
@@ -35,16 +36,18 @@ const inspect = _.flow(
|
|
|
35
36
|
* Takes the caps that were provided in the request and translates them
|
|
36
37
|
* into caps that can be used by the inner drivers.
|
|
37
38
|
*
|
|
38
|
-
* @
|
|
39
|
-
* @
|
|
40
|
-
* @param {
|
|
41
|
-
* @param {
|
|
42
|
-
* @
|
|
39
|
+
* @template {Constraints} C
|
|
40
|
+
* @template [J=any]
|
|
41
|
+
* @param {J} jsonwpCapabilities
|
|
42
|
+
* @param {W3CCapabilities<C>} w3cCapabilities
|
|
43
|
+
* @param {C} constraints
|
|
44
|
+
* @param {NSCapabilities<C>} [defaultCapabilities]
|
|
45
|
+
* @returns {ParsedDriverCaps<C,J>|InvalidCaps<C,J>}
|
|
43
46
|
*/
|
|
44
47
|
function parseCapsForInnerDriver(
|
|
45
48
|
jsonwpCapabilities,
|
|
46
49
|
w3cCapabilities,
|
|
47
|
-
constraints = {},
|
|
50
|
+
constraints = /** @type {C} */ ({}),
|
|
48
51
|
defaultCapabilities = {}
|
|
49
52
|
) {
|
|
50
53
|
// Check if the caller sent JSONWP caps, W3C caps, or both
|
|
@@ -52,14 +55,14 @@ function parseCapsForInnerDriver(
|
|
|
52
55
|
_.isPlainObject(w3cCapabilities) &&
|
|
53
56
|
(_.has(w3cCapabilities, 'alwaysMatch') || _.has(w3cCapabilities, 'firstMatch'));
|
|
54
57
|
const hasJSONWPCaps = _.isPlainObject(jsonwpCapabilities);
|
|
55
|
-
let desiredCaps = /** @type {ParsedDriverCaps['desiredCaps']} */ ({});
|
|
56
|
-
/** @type {ParsedDriverCaps['processedW3CCapabilities']} */
|
|
58
|
+
let desiredCaps = /** @type {ParsedDriverCaps<C>['desiredCaps']} */ ({});
|
|
59
|
+
/** @type {ParsedDriverCaps<C>['processedW3CCapabilities']} */
|
|
57
60
|
let processedW3CCapabilities;
|
|
58
|
-
/** @type {ParsedDriverCaps['processedJsonwpCapabilities']} */
|
|
61
|
+
/** @type {ParsedDriverCaps<C>['processedJsonwpCapabilities']} */
|
|
59
62
|
let processedJsonwpCapabilities;
|
|
60
63
|
|
|
61
64
|
if (!hasW3CCaps) {
|
|
62
|
-
return /** @type {InvalidCaps} */ ({
|
|
65
|
+
return /** @type {InvalidCaps<C>} */ ({
|
|
63
66
|
protocol: PROTOCOLS.W3C,
|
|
64
67
|
error: new Error('W3C capabilities should be provided'),
|
|
65
68
|
});
|
|
@@ -78,7 +81,7 @@ function parseCapsForInnerDriver(
|
|
|
78
81
|
for (const [defaultCapKey, defaultCapValue] of _.toPairs(defaultCapabilities)) {
|
|
79
82
|
let isCapAlreadySet = false;
|
|
80
83
|
// Check if the key is already present in firstMatch entries
|
|
81
|
-
for (const firstMatchEntry of w3cCapabilities.firstMatch
|
|
84
|
+
for (const firstMatchEntry of w3cCapabilities.firstMatch ?? []) {
|
|
82
85
|
if (
|
|
83
86
|
_.isPlainObject(firstMatchEntry) &&
|
|
84
87
|
_.has(removeAppiumPrefixes(firstMatchEntry), removeAppiumPrefix(defaultCapKey))
|
|
@@ -102,7 +105,9 @@ function parseCapsForInnerDriver(
|
|
|
102
105
|
|
|
103
106
|
// Only add the default capability if it is not overridden
|
|
104
107
|
if (_.isEmpty(w3cCapabilities.firstMatch)) {
|
|
105
|
-
w3cCapabilities.firstMatch =
|
|
108
|
+
w3cCapabilities.firstMatch = /** @type {W3CCapabilities<C>['firstMatch']} */ ([
|
|
109
|
+
{[defaultCapKey]: defaultCapValue},
|
|
110
|
+
]);
|
|
106
111
|
} else {
|
|
107
112
|
w3cCapabilities.firstMatch[0][defaultCapKey] = defaultCapValue;
|
|
108
113
|
}
|
|
@@ -129,7 +134,7 @@ function parseCapsForInnerDriver(
|
|
|
129
134
|
desiredCaps = processCapabilities(w3cCapabilities, constraints, true);
|
|
130
135
|
} catch (error) {
|
|
131
136
|
logger.info(`Could not parse W3C capabilities: ${error.message}`);
|
|
132
|
-
return /** @type {InvalidCaps} */ ({
|
|
137
|
+
return /** @type {InvalidCaps<C,J>} */ ({
|
|
133
138
|
desiredCaps,
|
|
134
139
|
processedJsonwpCapabilities,
|
|
135
140
|
processedW3CCapabilities,
|
|
@@ -145,7 +150,7 @@ function parseCapsForInnerDriver(
|
|
|
145
150
|
};
|
|
146
151
|
}
|
|
147
152
|
|
|
148
|
-
return /** @type {ParsedDriverCaps} */ ({
|
|
153
|
+
return /** @type {ParsedDriverCaps<C,J>} */ ({
|
|
149
154
|
desiredCaps,
|
|
150
155
|
processedJsonwpCapabilities,
|
|
151
156
|
processedW3CCapabilities,
|
|
@@ -155,57 +160,43 @@ function parseCapsForInnerDriver(
|
|
|
155
160
|
|
|
156
161
|
/**
|
|
157
162
|
* Takes a capabilities objects and prefixes capabilities with `appium:`
|
|
158
|
-
* @
|
|
159
|
-
* @
|
|
163
|
+
* @template {Constraints} [C={}]
|
|
164
|
+
* @param {Capabilities<C>} caps - Desired capabilities object
|
|
165
|
+
* @returns {NSCapabilities<C>}
|
|
160
166
|
*/
|
|
161
167
|
function insertAppiumPrefixes(caps) {
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
'proxy',
|
|
170
|
-
'setWindowRect',
|
|
171
|
-
'timeouts',
|
|
172
|
-
'unhandledPromptBehavior',
|
|
173
|
-
];
|
|
174
|
-
|
|
175
|
-
let prefixedCaps = {};
|
|
176
|
-
for (let [name, value] of _.toPairs(caps)) {
|
|
177
|
-
if (STANDARD_CAPS.includes(name) || name.includes(':')) {
|
|
178
|
-
prefixedCaps[name] = value;
|
|
179
|
-
} else {
|
|
180
|
-
prefixedCaps[`${W3C_APPIUM_PREFIX}:${name}`] = value;
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return prefixedCaps;
|
|
168
|
+
return /** @type {NSCapabilities<C>} */ (
|
|
169
|
+
_.mapKeys(caps, (_, key) =>
|
|
170
|
+
STANDARD_CAPS_LOWERCASE.has(key.toLowerCase()) || key.includes(':')
|
|
171
|
+
? key
|
|
172
|
+
: `${W3C_APPIUM_PREFIX}:${key}`
|
|
173
|
+
)
|
|
174
|
+
);
|
|
184
175
|
}
|
|
185
176
|
|
|
186
177
|
/**
|
|
187
|
-
*
|
|
188
|
-
* @param {
|
|
189
|
-
* @returns {Capabilities}
|
|
178
|
+
* @template {Constraints} [C={}]
|
|
179
|
+
* @param {NSCapabilities<C>} caps
|
|
180
|
+
* @returns {Capabilities<C>}
|
|
190
181
|
*/
|
|
191
182
|
function removeAppiumPrefixes(caps) {
|
|
192
|
-
|
|
193
|
-
return caps;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/** @type {Capabilities} */
|
|
197
|
-
const fixedCaps = {};
|
|
198
|
-
for (let [name, value] of _.toPairs(caps)) {
|
|
199
|
-
fixedCaps[removeAppiumPrefix(name)] = value;
|
|
200
|
-
}
|
|
201
|
-
return fixedCaps;
|
|
183
|
+
return /** @type {Capabilities<C>} */ (_.mapKeys(caps, (_, key) => removeAppiumPrefix(key)));
|
|
202
184
|
}
|
|
203
185
|
|
|
186
|
+
/**
|
|
187
|
+
* @param {string} key
|
|
188
|
+
* @returns {string}
|
|
189
|
+
*/
|
|
204
190
|
function removeAppiumPrefix(key) {
|
|
205
191
|
const prefix = `${W3C_APPIUM_PREFIX}:`;
|
|
206
192
|
return _.startsWith(key, prefix) ? key.substring(prefix.length) : key;
|
|
207
193
|
}
|
|
208
194
|
|
|
195
|
+
/**
|
|
196
|
+
*
|
|
197
|
+
* @param {string} pkgName
|
|
198
|
+
* @returns {string|undefined}
|
|
199
|
+
*/
|
|
209
200
|
function getPackageVersion(pkgName) {
|
|
210
201
|
const pkgInfo = require(`${pkgName}/package.json`) || {};
|
|
211
202
|
return pkgInfo.version;
|
|
@@ -235,7 +226,6 @@ function adjustNodePath() {
|
|
|
235
226
|
require('module').Module._initPaths();
|
|
236
227
|
return true;
|
|
237
228
|
} catch (e) {
|
|
238
|
-
logger.info(`Module init paths cannot be refreshed. Original error: ${e.message}`);
|
|
239
229
|
return false;
|
|
240
230
|
}
|
|
241
231
|
};
|
|
@@ -243,7 +233,6 @@ function adjustNodePath() {
|
|
|
243
233
|
if (!process.env.NODE_PATH) {
|
|
244
234
|
process.env.NODE_PATH = nodeModulesRoot;
|
|
245
235
|
if (refreshRequirePaths()) {
|
|
246
|
-
logger.info(`Setting NODE_PATH to '${nodeModulesRoot}'`);
|
|
247
236
|
process.env.APPIUM_OMIT_PEER_DEPS = '1';
|
|
248
237
|
} else {
|
|
249
238
|
delete process.env.NODE_PATH;
|
|
@@ -253,7 +242,6 @@ function adjustNodePath() {
|
|
|
253
242
|
|
|
254
243
|
const nodePathParts = process.env.NODE_PATH.split(path.delimiter);
|
|
255
244
|
if (nodePathParts.includes(nodeModulesRoot)) {
|
|
256
|
-
logger.info(`NODE_PATH already includes '${nodeModulesRoot}'`);
|
|
257
245
|
process.env.APPIUM_OMIT_PEER_DEPS = '1';
|
|
258
246
|
return;
|
|
259
247
|
}
|
|
@@ -261,7 +249,6 @@ function adjustNodePath() {
|
|
|
261
249
|
nodePathParts.push(nodeModulesRoot);
|
|
262
250
|
process.env.NODE_PATH = nodePathParts.join(path.delimiter);
|
|
263
251
|
if (refreshRequirePaths()) {
|
|
264
|
-
logger.info(`Adding '${nodeModulesRoot}' to NODE_PATH`);
|
|
265
252
|
process.env.APPIUM_OMIT_PEER_DEPS = '1';
|
|
266
253
|
} else {
|
|
267
254
|
process.env.NODE_PATH = _.without(nodePathParts, nodeModulesRoot).join(path.delimiter);
|
|
@@ -313,26 +300,60 @@ export {
|
|
|
313
300
|
};
|
|
314
301
|
|
|
315
302
|
/**
|
|
316
|
-
* @
|
|
303
|
+
* @typedef {import('@appium/types').StringRecord} StringRecord
|
|
304
|
+
* @typedef {import('@appium/types').BaseDriverCapConstraints} BaseDriverCapConstraints
|
|
305
|
+
*/
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
309
|
+
* @template [J=any]
|
|
317
310
|
* @typedef ParsedDriverCaps
|
|
318
|
-
* @property {Capabilities} desiredCaps
|
|
311
|
+
* @property {Capabilities<C>} desiredCaps
|
|
319
312
|
* @property {string} protocol
|
|
320
|
-
* @property {
|
|
321
|
-
* @property {W3CCapabilities} [processedW3CCapabilities]
|
|
313
|
+
* @property {J} [processedJsonwpCapabilities]
|
|
314
|
+
* @property {W3CCapabilities<C>} [processedW3CCapabilities]
|
|
322
315
|
*/
|
|
323
316
|
|
|
324
317
|
/**
|
|
325
318
|
* @todo protocol is more specific
|
|
319
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
320
|
+
* @template [J=any]
|
|
326
321
|
* @typedef InvalidCaps
|
|
327
322
|
* @property {Error} error
|
|
328
323
|
* @property {string} protocol
|
|
329
|
-
* @property {Capabilities} [desiredCaps]
|
|
330
|
-
* @property {
|
|
331
|
-
* @property {W3CCapabilities} [processedW3CCapabilities]
|
|
324
|
+
* @property {Capabilities<C>} [desiredCaps]
|
|
325
|
+
* @property {J} [processedJsonwpCapabilities]
|
|
326
|
+
* @property {W3CCapabilities<C>} [processedW3CCapabilities]
|
|
327
|
+
*/
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
331
|
+
* @template {StringRecord|void} [Extra=void]
|
|
332
|
+
* @typedef {import('@appium/types').Capabilities<C, Extra>} Capabilities
|
|
333
|
+
*/
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
337
|
+
* @template {StringRecord|void} [Extra=void]
|
|
338
|
+
* @typedef {import('@appium/types').W3CCapabilities<C, Extra>} W3CCapabilities
|
|
339
|
+
*/
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* @template {Constraints} [C=BaseDriverCapConstraints]
|
|
343
|
+
* @template {StringRecord|void} [Extra=void]
|
|
344
|
+
* @typedef {import('@appium/types').NSCapabilities<C, Extra>} NSCapabilities
|
|
345
|
+
*/
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* @template {Constraints} C
|
|
349
|
+
* @typedef {import('@appium/types').ConstraintsToCaps<C>} ConstraintsToCaps
|
|
350
|
+
*/
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* @template T
|
|
354
|
+
* @typedef {import('type-fest').StringKeyOf<T>} StringKeyOf
|
|
332
355
|
*/
|
|
333
356
|
|
|
334
357
|
/**
|
|
335
|
-
* @typedef {import('@appium/types').
|
|
336
|
-
* @typedef {import('@appium/types').Capabilities} Capabilities
|
|
337
|
-
* @typedef {import('@appium/types').AppiumW3CCapabilities} AppiumW3CCapabilities
|
|
358
|
+
* @typedef {import('@appium/types').Constraints} Constraints
|
|
338
359
|
*/
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.45",
|
|
4
4
|
"description": "Automation for Apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -43,6 +43,7 @@
|
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "babel lib --root-mode=upward --out-dir=build/lib",
|
|
45
45
|
"build:docs": "node docs/scripts/build-docs.js",
|
|
46
|
+
"build:docs:cli": "node docs/scripts/gen-cli-args-docs.js",
|
|
46
47
|
"build:docs:assets": "node docs/scripts/copy-assets.js",
|
|
47
48
|
"dev": "npm run build -- --watch",
|
|
48
49
|
"dev:docs": "npm run build:docs:assets && npm run dev:docs:en",
|
|
@@ -60,16 +61,15 @@
|
|
|
60
61
|
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
|
61
62
|
},
|
|
62
63
|
"dependencies": {
|
|
63
|
-
"@appium/base-driver": "^8.7.
|
|
64
|
-
"@appium/base-plugin": "^1.10.
|
|
65
|
-
"@appium/docutils": "^0.0.
|
|
64
|
+
"@appium/base-driver": "^8.7.2",
|
|
65
|
+
"@appium/base-plugin": "^1.10.4",
|
|
66
|
+
"@appium/docutils": "^0.0.12",
|
|
66
67
|
"@appium/schema": "^0.0.9",
|
|
67
|
-
"@appium/support": "^2.
|
|
68
|
-
"@appium/types": "^0.
|
|
69
|
-
"@
|
|
70
|
-
"@sidvind/better-ajv-errors": "2.0.0",
|
|
68
|
+
"@appium/support": "^2.61.0",
|
|
69
|
+
"@appium/types": "^0.5.0",
|
|
70
|
+
"@sidvind/better-ajv-errors": "2.1.0",
|
|
71
71
|
"@types/argparse": "2.0.10",
|
|
72
|
-
"@types/bluebird": "3.5.
|
|
72
|
+
"@types/bluebird": "3.5.37",
|
|
73
73
|
"@types/fancy-log": "2.0.0",
|
|
74
74
|
"@types/semver": "7.3.12",
|
|
75
75
|
"@types/teen_process": "1.16.1",
|
|
@@ -83,6 +83,7 @@
|
|
|
83
83
|
"bluebird": "3.7.2",
|
|
84
84
|
"cross-env": "7.0.3",
|
|
85
85
|
"find-up": "5.0.0",
|
|
86
|
+
"glob": "8.0.3",
|
|
86
87
|
"lilconfig": "2.0.6",
|
|
87
88
|
"lodash": "4.17.21",
|
|
88
89
|
"longjohn": "0.2.12",
|
|
@@ -90,13 +91,13 @@
|
|
|
90
91
|
"ora": "5.4.1",
|
|
91
92
|
"package-changed": "1.9.0",
|
|
92
93
|
"resolve-from": "5.0.0",
|
|
93
|
-
"semver": "7.3.
|
|
94
|
+
"semver": "7.3.8",
|
|
94
95
|
"source-map-support": "0.5.21",
|
|
95
|
-
"teen_process": "
|
|
96
|
-
"type-fest": "
|
|
97
|
-
"winston": "3.8.
|
|
96
|
+
"teen_process": "2.0.2",
|
|
97
|
+
"type-fest": "3.1.0",
|
|
98
|
+
"winston": "3.8.2",
|
|
98
99
|
"wrap-ansi": "7.0.0",
|
|
99
|
-
"yaml": "2.1.
|
|
100
|
+
"yaml": "2.1.3"
|
|
100
101
|
},
|
|
101
102
|
"engines": {
|
|
102
103
|
"node": ">=14",
|
|
@@ -106,5 +107,5 @@
|
|
|
106
107
|
"access": "public",
|
|
107
108
|
"tag": "next"
|
|
108
109
|
},
|
|
109
|
-
"gitHead": "
|
|
110
|
+
"gitHead": "f545a6cde58d83f3289072f8957468793947ba66"
|
|
110
111
|
}
|