appium 2.0.0-beta.33 → 2.0.0-beta.37
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 +41 -52
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +32 -15
- package/build/lib/cli/args.d.ts +1 -1
- package/build/lib/cli/args.d.ts.map +1 -1
- package/build/lib/cli/args.js +1 -1
- package/build/lib/cli/driver-command.d.ts +5 -5
- package/build/lib/cli/driver-command.d.ts.map +1 -1
- package/build/lib/cli/driver-command.js +8 -8
- package/build/lib/cli/extension-command.d.ts +78 -51
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +135 -80
- package/build/lib/cli/extension.d.ts +9 -5
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +5 -7
- package/build/lib/cli/parser.d.ts +3 -3
- package/build/lib/cli/parser.d.ts.map +1 -1
- package/build/lib/cli/parser.js +1 -1
- package/build/lib/cli/plugin-command.d.ts +9 -15
- package/build/lib/cli/plugin-command.d.ts.map +1 -1
- package/build/lib/cli/plugin-command.js +8 -8
- package/build/lib/cli/utils.js +1 -1
- package/build/lib/config-file.d.ts.map +1 -1
- package/build/lib/config-file.js +1 -1
- package/build/lib/config.d.ts +4 -4
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +1 -1
- package/build/lib/constants.d.ts.map +1 -1
- package/build/lib/constants.js +1 -1
- package/build/lib/extension/driver-config.d.ts +29 -32
- package/build/lib/extension/driver-config.d.ts.map +1 -1
- package/build/lib/extension/driver-config.js +7 -20
- package/build/lib/extension/extension-config.d.ts +108 -36
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +199 -60
- package/build/lib/extension/index.d.ts +16 -7
- package/build/lib/extension/index.d.ts.map +1 -1
- package/build/lib/extension/index.js +15 -18
- package/build/lib/extension/manifest.d.ts +12 -12
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +13 -3
- package/build/lib/extension/package-changed.d.ts.map +1 -1
- package/build/lib/extension/package-changed.js +1 -1
- package/build/lib/extension/plugin-config.d.ts +19 -24
- package/build/lib/extension/plugin-config.d.ts.map +1 -1
- package/build/lib/extension/plugin-config.js +9 -18
- package/build/lib/grid-register.d.ts.map +1 -1
- package/build/lib/grid-register.js +1 -1
- package/build/lib/logger.d.ts +1 -1
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +1 -1
- package/build/lib/logsink.d.ts.map +1 -1
- package/build/lib/logsink.js +3 -2
- package/build/lib/main.d.ts +13 -12
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +4 -4
- package/build/lib/schema/arg-spec.d.ts +4 -4
- package/build/lib/schema/arg-spec.d.ts.map +1 -1
- package/build/lib/schema/arg-spec.js +1 -1
- package/build/lib/schema/cli-args.d.ts.map +1 -1
- package/build/lib/schema/cli-args.js +1 -1
- package/build/lib/schema/cli-transformers.d.ts.map +1 -1
- package/build/lib/schema/cli-transformers.js +1 -1
- package/build/lib/schema/index.js +1 -1
- package/build/lib/schema/keywords.d.ts.map +1 -1
- package/build/lib/schema/keywords.js +1 -1
- package/build/lib/schema/schema.d.ts +2 -2
- package/build/lib/schema/schema.d.ts.map +1 -1
- package/build/lib/schema/schema.js +1 -1
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/appium-manifest.d.ts +23 -4
- package/build/types/appium-manifest.d.ts.map +1 -1
- package/build/types/cli.d.ts.map +1 -1
- package/build/types/{external-manifest.d.ts → extension-manifest.d.ts} +15 -7
- package/build/types/extension-manifest.d.ts.map +1 -0
- package/build/types/index.d.ts +6 -5
- package/build/types/index.d.ts.map +1 -1
- package/driver.d.ts +1 -0
- package/driver.js +14 -0
- package/lib/appium.js +208 -124
- package/lib/cli/args.js +143 -93
- package/lib/cli/driver-command.js +46 -26
- package/lib/cli/extension-command.js +314 -157
- package/lib/cli/extension.js +15 -19
- package/lib/cli/parser.js +19 -31
- package/lib/cli/plugin-command.js +39 -24
- package/lib/cli/utils.js +8 -14
- package/lib/config-file.js +21 -25
- package/lib/config.js +82 -64
- package/lib/constants.js +4 -13
- package/lib/extension/driver-config.js +171 -171
- package/lib/extension/extension-config.js +347 -126
- package/lib/extension/index.js +72 -58
- package/lib/extension/manifest.js +48 -57
- package/lib/extension/package-changed.js +9 -8
- package/lib/extension/plugin-config.js +62 -62
- package/lib/grid-register.js +29 -18
- package/lib/logger.js +1 -2
- package/lib/logsink.js +29 -31
- package/lib/main.js +111 -73
- package/lib/schema/arg-spec.js +10 -13
- package/lib/schema/cli-args.js +14 -37
- package/lib/schema/cli-transformers.js +7 -14
- package/lib/schema/keywords.js +15 -13
- package/lib/schema/schema.js +58 -75
- package/lib/utils.js +50 -25
- package/package.json +27 -20
- package/plugin.d.ts +1 -0
- package/plugin.js +13 -0
- package/scripts/autoinstall-extensions.js +177 -0
- package/support.d.ts +1 -0
- package/support.js +13 -0
- package/types/appium-manifest.ts +27 -15
- package/types/cli.ts +2 -9
- package/types/{external-manifest.ts → extension-manifest.ts} +21 -15
- package/types/index.ts +12 -5
- package/build/types/extension.d.ts +0 -43
- package/build/types/extension.d.ts.map +0 -1
- package/build/types/external-manifest.d.ts.map +0 -1
- package/lib/appium-config.schema.json +0 -278
- package/scripts/postinstall.js +0 -71
- package/types/extension.ts +0 -56
package/lib/main.js
CHANGED
|
@@ -1,23 +1,31 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
import { init as logsinkInit } from './logsink'; // this import needs to come first since it sets up global npmlog
|
|
3
|
+
import {init as logsinkInit} from './logsink'; // this import needs to come first since it sets up global npmlog
|
|
5
4
|
import logger from './logger'; // logger needs to remain second
|
|
6
5
|
// @ts-ignore
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import {routeConfiguringFunction as makeRouter, server as baseServer} from '@appium/base-driver';
|
|
7
|
+
import {logger as logFactory, util, env} from '@appium/support';
|
|
8
|
+
import {asyncify} from 'asyncbox';
|
|
10
9
|
import _ from 'lodash';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
import {AppiumDriver} from './appium';
|
|
11
|
+
import {runExtensionCommand} from './cli/extension';
|
|
12
|
+
import {getParser} from './cli/parser';
|
|
13
|
+
import {
|
|
14
|
+
APPIUM_VER,
|
|
15
|
+
checkNodeOk,
|
|
16
|
+
getGitRev,
|
|
17
|
+
getNonDefaultServerArgs,
|
|
18
|
+
showConfig,
|
|
19
|
+
showBuildInfo,
|
|
20
|
+
validateTmpDir,
|
|
21
|
+
warnNodeDeprecations,
|
|
22
|
+
} from './config';
|
|
23
|
+
import {readConfigFile} from './config-file';
|
|
24
|
+
import {loadExtensions, getActivePlugins, getActiveDrivers} from './extension';
|
|
25
|
+
import {DRIVER_TYPE, PLUGIN_TYPE, SERVER_SUBCOMMAND} from './constants';
|
|
18
26
|
import registerNode from './grid-register';
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
27
|
+
import {getDefaultsForSchema, validate} from './schema/schema';
|
|
28
|
+
import {inspect} from './utils';
|
|
21
29
|
|
|
22
30
|
const {resolveAppiumHome} = env;
|
|
23
31
|
|
|
@@ -26,7 +34,7 @@ const {resolveAppiumHome} = env;
|
|
|
26
34
|
* @param {ParsedArgs} args
|
|
27
35
|
* @param {boolean} [throwInsteadOfExit]
|
|
28
36
|
*/
|
|
29
|
-
async function preflightChecks
|
|
37
|
+
async function preflightChecks(args, throwInsteadOfExit = false) {
|
|
30
38
|
try {
|
|
31
39
|
checkNodeOk();
|
|
32
40
|
if (args.longStacktrace) {
|
|
@@ -56,7 +64,7 @@ async function preflightChecks (args, throwInsteadOfExit = false) {
|
|
|
56
64
|
/**
|
|
57
65
|
* @param {Args} args
|
|
58
66
|
*/
|
|
59
|
-
function logNonDefaultArgsWarning
|
|
67
|
+
function logNonDefaultArgsWarning(args) {
|
|
60
68
|
logger.info('Non-default server args:');
|
|
61
69
|
inspect(args);
|
|
62
70
|
}
|
|
@@ -64,16 +72,18 @@ function logNonDefaultArgsWarning (args) {
|
|
|
64
72
|
/**
|
|
65
73
|
* @param {Args['defaultCapabilities']} caps
|
|
66
74
|
*/
|
|
67
|
-
function logDefaultCapabilitiesWarning
|
|
68
|
-
logger.info(
|
|
69
|
-
|
|
75
|
+
function logDefaultCapabilitiesWarning(caps) {
|
|
76
|
+
logger.info(
|
|
77
|
+
'Default capabilities, which will be added to each request ' +
|
|
78
|
+
'unless overridden by desired capabilities:'
|
|
79
|
+
);
|
|
70
80
|
inspect(caps);
|
|
71
81
|
}
|
|
72
82
|
|
|
73
83
|
/**
|
|
74
84
|
* @param {ParsedArgs} args
|
|
75
85
|
*/
|
|
76
|
-
async function logStartupInfo
|
|
86
|
+
async function logStartupInfo(args) {
|
|
77
87
|
let welcome = `Welcome to Appium v${APPIUM_VER}`;
|
|
78
88
|
let appiumRev = await getGitRev();
|
|
79
89
|
if (appiumRev) {
|
|
@@ -101,31 +111,33 @@ async function logStartupInfo (args) {
|
|
|
101
111
|
* @param {number} port - Port
|
|
102
112
|
* @returns {void}
|
|
103
113
|
*/
|
|
104
|
-
function logServerPort
|
|
105
|
-
let logMessage = `Appium REST http interface listener started on ` +
|
|
106
|
-
`${address}:${port}`;
|
|
114
|
+
function logServerPort(address, port) {
|
|
115
|
+
let logMessage = `Appium REST http interface listener started on ` + `${address}:${port}`;
|
|
107
116
|
logger.info(logMessage);
|
|
108
117
|
}
|
|
109
118
|
|
|
110
119
|
/**
|
|
111
120
|
* Gets a list of `updateServer` functions from all extensions
|
|
112
|
-
* @param {
|
|
113
|
-
* @param {
|
|
114
|
-
* @returns {import('@appium/
|
|
121
|
+
* @param {DriverNameMap} driverClasses
|
|
122
|
+
* @param {PluginNameMap} pluginClasses
|
|
123
|
+
* @returns {import('@appium/types').UpdateServerCallback[]}
|
|
115
124
|
*/
|
|
116
|
-
function getServerUpdaters
|
|
117
|
-
return _.compact(_.map([...driverClasses, ...pluginClasses], 'updateServer'));
|
|
125
|
+
function getServerUpdaters(driverClasses, pluginClasses) {
|
|
126
|
+
return _.compact(_.map([...driverClasses.keys(), ...pluginClasses.keys()], 'updateServer'));
|
|
118
127
|
}
|
|
119
128
|
|
|
120
129
|
/**
|
|
121
130
|
* Makes a big `MethodMap` from all the little `MethodMap`s in the extensions
|
|
122
|
-
* @param {
|
|
123
|
-
* @param {
|
|
131
|
+
* @param {DriverNameMap} driverClasses
|
|
132
|
+
* @param {PluginNameMap} pluginClasses
|
|
124
133
|
* @returns {import('@appium/types').MethodMap}
|
|
125
134
|
*/
|
|
126
|
-
function getExtraMethodMap
|
|
127
|
-
return [...driverClasses, ...pluginClasses].reduce(
|
|
128
|
-
(map, klass) => ({
|
|
135
|
+
function getExtraMethodMap(driverClasses, pluginClasses) {
|
|
136
|
+
return [...driverClasses.keys(), ...pluginClasses.keys()].reduce(
|
|
137
|
+
(map, klass) => ({
|
|
138
|
+
...map,
|
|
139
|
+
...(klass.newMethodMap ?? {}),
|
|
140
|
+
}),
|
|
129
141
|
{}
|
|
130
142
|
);
|
|
131
143
|
}
|
|
@@ -135,7 +147,7 @@ function getExtraMethodMap (driverClasses, pluginClasses) {
|
|
|
135
147
|
* @param {Args<T>} args
|
|
136
148
|
* @returns {args is Args<WithServerSubcommand>}
|
|
137
149
|
*/
|
|
138
|
-
function areServerCommandArgs
|
|
150
|
+
function areServerCommandArgs(args) {
|
|
139
151
|
return args.subcommand === SERVER_SUBCOMMAND;
|
|
140
152
|
}
|
|
141
153
|
|
|
@@ -155,8 +167,8 @@ function areServerCommandArgs (args) {
|
|
|
155
167
|
* await init(options);
|
|
156
168
|
* const schema = getSchema(); // entire config schema including plugins and drivers
|
|
157
169
|
*/
|
|
158
|
-
async function init
|
|
159
|
-
const appiumHome = args?.appiumHome ?? await resolveAppiumHome();
|
|
170
|
+
async function init(args) {
|
|
171
|
+
const appiumHome = args?.appiumHome ?? (await resolveAppiumHome());
|
|
160
172
|
|
|
161
173
|
const {driverConfig, pluginConfig} = await loadExtensions(appiumHome);
|
|
162
174
|
|
|
@@ -177,13 +189,17 @@ async function init (args) {
|
|
|
177
189
|
preConfigArgs = {...args, subcommand: args.subcommand ?? SERVER_SUBCOMMAND};
|
|
178
190
|
} else {
|
|
179
191
|
// otherwise parse from CLI
|
|
180
|
-
preConfigArgs = /** @type {Args<T>} */(parser.parseArgs());
|
|
192
|
+
preConfigArgs = /** @type {Args<T>} */ (parser.parseArgs());
|
|
181
193
|
}
|
|
182
194
|
|
|
183
195
|
const configResult = await readConfigFile(preConfigArgs.configFile);
|
|
184
196
|
|
|
185
197
|
if (!_.isEmpty(configResult.errors)) {
|
|
186
|
-
throw new Error(
|
|
198
|
+
throw new Error(
|
|
199
|
+
`Errors in config file ${configResult.filepath}:\n ${
|
|
200
|
+
configResult.reason ?? configResult.errors
|
|
201
|
+
}`
|
|
202
|
+
);
|
|
187
203
|
}
|
|
188
204
|
|
|
189
205
|
// merge config and apply defaults.
|
|
@@ -192,7 +208,6 @@ async function init (args) {
|
|
|
192
208
|
// 2. config file
|
|
193
209
|
// 3. defaults from config file.
|
|
194
210
|
if (!areServerCommandArgs(preConfigArgs)) {
|
|
195
|
-
|
|
196
211
|
// if the user has requested the 'driver' CLI, don't run the normal server,
|
|
197
212
|
// but instead pass control to the driver CLI
|
|
198
213
|
if (preConfigArgs.subcommand === DRIVER_TYPE) {
|
|
@@ -209,11 +224,7 @@ async function init (args) {
|
|
|
209
224
|
const defaults = getDefaultsForSchema(false);
|
|
210
225
|
|
|
211
226
|
/** @type {ParsedArgs} */
|
|
212
|
-
const serverArgs = _.defaultsDeep(
|
|
213
|
-
preConfigArgs,
|
|
214
|
-
configResult.config?.server,
|
|
215
|
-
defaults
|
|
216
|
-
);
|
|
227
|
+
const serverArgs = _.defaultsDeep(preConfigArgs, configResult.config?.server, defaults);
|
|
217
228
|
|
|
218
229
|
if (preConfigArgs.showConfig) {
|
|
219
230
|
showConfig(getNonDefaultServerArgs(preConfigArgs), configResult, defaults, serverArgs);
|
|
@@ -223,15 +234,25 @@ async function init (args) {
|
|
|
223
234
|
await logsinkInit(serverArgs);
|
|
224
235
|
|
|
225
236
|
if (serverArgs.logFilters) {
|
|
226
|
-
const {issues, rules} = await logFactory.loadSecureValuesPreprocessingRules(
|
|
237
|
+
const {issues, rules} = await logFactory.loadSecureValuesPreprocessingRules(
|
|
238
|
+
serverArgs.logFilters
|
|
239
|
+
);
|
|
227
240
|
if (!_.isEmpty(issues)) {
|
|
228
|
-
throw new Error(
|
|
229
|
-
|
|
241
|
+
throw new Error(
|
|
242
|
+
`The log filtering rules config '${serverArgs.logFilters}' has issues: ` +
|
|
243
|
+
JSON.stringify(issues, null, 2)
|
|
244
|
+
);
|
|
230
245
|
}
|
|
231
246
|
if (_.isEmpty(rules)) {
|
|
232
|
-
logger.warn(
|
|
247
|
+
logger.warn(
|
|
248
|
+
`Found no log filtering rules in '${serverArgs.logFilters}'. Is that expected?`
|
|
249
|
+
);
|
|
233
250
|
} else {
|
|
234
|
-
logger.info(
|
|
251
|
+
logger.info(
|
|
252
|
+
`Loaded ${util.pluralize('filtering rule', rules.length, true)} from '${
|
|
253
|
+
serverArgs.logFilters
|
|
254
|
+
}'`
|
|
255
|
+
);
|
|
235
256
|
}
|
|
236
257
|
}
|
|
237
258
|
|
|
@@ -240,7 +261,12 @@ async function init (args) {
|
|
|
240
261
|
appiumDriver.driverConfig = driverConfig;
|
|
241
262
|
await preflightChecks(serverArgs, throwInsteadOfExit);
|
|
242
263
|
|
|
243
|
-
return /** @type {ServerInitResult} */({
|
|
264
|
+
return /** @type {ServerInitResult} */ ({
|
|
265
|
+
appiumDriver,
|
|
266
|
+
parsedArgs: serverArgs,
|
|
267
|
+
driverConfig,
|
|
268
|
+
pluginConfig,
|
|
269
|
+
});
|
|
244
270
|
}
|
|
245
271
|
}
|
|
246
272
|
|
|
@@ -251,8 +277,10 @@ async function init (args) {
|
|
|
251
277
|
* @param {Args<T>} [args] - Arguments from CLI or otherwise
|
|
252
278
|
* @returns {Promise<import('@appium/types').AppiumServer|undefined>}
|
|
253
279
|
*/
|
|
254
|
-
async function main
|
|
255
|
-
const {appiumDriver, parsedArgs, pluginConfig, driverConfig} = /** @type {ServerInitResult} */
|
|
280
|
+
async function main(args) {
|
|
281
|
+
const {appiumDriver, parsedArgs, pluginConfig, driverConfig} = /** @type {ServerInitResult} */ (
|
|
282
|
+
await init(args)
|
|
283
|
+
);
|
|
256
284
|
|
|
257
285
|
if (!appiumDriver || !parsedArgs || !pluginConfig || !driverConfig) {
|
|
258
286
|
// if this branch is taken, we've run a different subcommand, so there's nothing
|
|
@@ -287,23 +315,32 @@ async function main (args) {
|
|
|
287
315
|
try {
|
|
288
316
|
server = await baseServer(serverOpts);
|
|
289
317
|
} catch (err) {
|
|
290
|
-
logger.error(
|
|
291
|
-
|
|
318
|
+
logger.error(
|
|
319
|
+
`Could not configure Appium server. It's possible that a driver or plugin tried ` +
|
|
320
|
+
`to update the server and failed. Original error: ${err.message}`
|
|
321
|
+
);
|
|
292
322
|
logger.debug(err.stack);
|
|
293
323
|
return process.exit(1);
|
|
294
324
|
}
|
|
295
325
|
|
|
296
326
|
if (parsedArgs.allowCors) {
|
|
297
|
-
logger.warn(
|
|
298
|
-
|
|
299
|
-
|
|
327
|
+
logger.warn(
|
|
328
|
+
'You have enabled CORS requests from any host. Be careful not ' +
|
|
329
|
+
'to visit sites which could maliciously try to start Appium ' +
|
|
330
|
+
'sessions on your machine'
|
|
331
|
+
);
|
|
300
332
|
}
|
|
301
333
|
appiumDriver.server = server;
|
|
302
334
|
try {
|
|
303
335
|
// configure as node on grid, if necessary
|
|
304
336
|
// falsy values should not cause this to run
|
|
305
337
|
if (parsedArgs.nodeconfig) {
|
|
306
|
-
await registerNode(
|
|
338
|
+
await registerNode(
|
|
339
|
+
parsedArgs.nodeconfig,
|
|
340
|
+
parsedArgs.address,
|
|
341
|
+
parsedArgs.port,
|
|
342
|
+
parsedArgs.basePath
|
|
343
|
+
);
|
|
307
344
|
}
|
|
308
345
|
} catch (err) {
|
|
309
346
|
await server.close();
|
|
@@ -311,7 +348,7 @@ async function main (args) {
|
|
|
311
348
|
}
|
|
312
349
|
|
|
313
350
|
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
314
|
-
process.once(signal, async function onSignal
|
|
351
|
+
process.once(signal, async function onSignal() {
|
|
315
352
|
logger.info(`Received ${signal} - shutting down`);
|
|
316
353
|
try {
|
|
317
354
|
await appiumDriver.deleteAllSessions({
|
|
@@ -329,7 +366,7 @@ async function main (args) {
|
|
|
329
366
|
|
|
330
367
|
logServerPort(parsedArgs.address, parsedArgs.port);
|
|
331
368
|
driverConfig.print();
|
|
332
|
-
pluginConfig.print(pluginClasses.
|
|
369
|
+
pluginConfig.print([...pluginClasses.values()]);
|
|
333
370
|
|
|
334
371
|
return server;
|
|
335
372
|
}
|
|
@@ -342,16 +379,18 @@ if (require.main === module) {
|
|
|
342
379
|
}
|
|
343
380
|
|
|
344
381
|
// everything below here is intended to be a public API.
|
|
345
|
-
export {
|
|
346
|
-
export {
|
|
347
|
-
export {
|
|
382
|
+
export {readConfigFile} from './config-file';
|
|
383
|
+
export {finalizeSchema, getSchema, validate} from './schema/schema';
|
|
384
|
+
export {main, init, resolveAppiumHome};
|
|
348
385
|
|
|
349
386
|
/**
|
|
350
|
-
* @typedef {import('
|
|
351
|
-
* @typedef {import('
|
|
352
|
-
* @typedef {import('
|
|
353
|
-
* @typedef {import('
|
|
354
|
-
* @typedef {import('
|
|
387
|
+
* @typedef {import('@appium/types').DriverType} DriverType
|
|
388
|
+
* @typedef {import('@appium/types').PluginType} PluginType
|
|
389
|
+
* @typedef {import('@appium/types').DriverClass} DriverClass
|
|
390
|
+
* @typedef {import('@appium/types').PluginClass} PluginClass
|
|
391
|
+
* @typedef {import('appium/types').WithServerSubcommand} WithServerSubcommand
|
|
392
|
+
* @typedef {import('./extension').DriverNameMap} DriverNameMap
|
|
393
|
+
* @typedef {import('./extension').PluginNameMap} PluginNameMap
|
|
355
394
|
*/
|
|
356
395
|
|
|
357
396
|
/**
|
|
@@ -361,8 +400,8 @@ export { main, init, resolveAppiumHome };
|
|
|
361
400
|
|
|
362
401
|
/**
|
|
363
402
|
* @typedef ServerInitData
|
|
364
|
-
* @property {AppiumDriver} appiumDriver - The Appium driver
|
|
365
|
-
* @property {import('
|
|
403
|
+
* @property {import('./appium').AppiumDriver} appiumDriver - The Appium driver
|
|
404
|
+
* @property {import('appium/types').ParsedArgs} parsedArgs - The parsed arguments
|
|
366
405
|
*/
|
|
367
406
|
|
|
368
407
|
/**
|
|
@@ -371,11 +410,10 @@ export { main, init, resolveAppiumHome };
|
|
|
371
410
|
|
|
372
411
|
/**
|
|
373
412
|
* @template [T=WithServerSubcommand]
|
|
374
|
-
* @typedef {import('
|
|
413
|
+
* @typedef {import('appium/types').Args<T>} Args
|
|
375
414
|
*/
|
|
376
415
|
|
|
377
416
|
/**
|
|
378
417
|
* @template [T=WithServerSubcommand]
|
|
379
|
-
* @typedef {import('
|
|
418
|
+
* @typedef {import('appium/types').ParsedArgs<T>} ParsedArgs
|
|
380
419
|
*/
|
|
381
|
-
|
package/lib/schema/arg-spec.js
CHANGED
|
@@ -96,7 +96,7 @@ export class ArgSpec {
|
|
|
96
96
|
* @param {string} name
|
|
97
97
|
* @param {ArgSpecOptions<D>} [opts]
|
|
98
98
|
*/
|
|
99
|
-
constructor
|
|
99
|
+
constructor(name, {extType, extName, dest, defaultValue} = {}) {
|
|
100
100
|
// we must normalize the extension name to fit into our convention for CLI
|
|
101
101
|
// args.
|
|
102
102
|
const arg = ArgSpec.toArg(name, extType, extName);
|
|
@@ -107,8 +107,7 @@ export class ArgSpec {
|
|
|
107
107
|
// to use bracket syntax when accessing props on the parsed args object.
|
|
108
108
|
const rawDest = _.camelCase(dest ?? name);
|
|
109
109
|
|
|
110
|
-
const destKeypath =
|
|
111
|
-
extType && extName ? [extType, extName, rawDest].join('.') : rawDest;
|
|
110
|
+
const destKeypath = extType && extName ? [extType, extName, rawDest].join('.') : rawDest;
|
|
112
111
|
|
|
113
112
|
this.defaultValue = defaultValue;
|
|
114
113
|
this.name = name;
|
|
@@ -129,7 +128,7 @@ export class ArgSpec {
|
|
|
129
128
|
* @param {string} [extName] - Extension name
|
|
130
129
|
* @returns {string} Schema ID
|
|
131
130
|
*/
|
|
132
|
-
static toSchemaRef
|
|
131
|
+
static toSchemaRef(name, extType, extName) {
|
|
133
132
|
const baseRef = ArgSpec.toSchemaBaseRef(extType, extName);
|
|
134
133
|
if (extType && extName) {
|
|
135
134
|
return [`${baseRef}#`, PROPERTIES, name].join('/');
|
|
@@ -142,7 +141,7 @@ export class ArgSpec {
|
|
|
142
141
|
* @param {ExtensionType} [extType] - Extension type
|
|
143
142
|
* @param {string} [extName] - Extension name
|
|
144
143
|
*/
|
|
145
|
-
static toSchemaBaseRef
|
|
144
|
+
static toSchemaBaseRef(extType, extName) {
|
|
146
145
|
if (extType && extName) {
|
|
147
146
|
return `${extType}-${ArgSpec.toNormalizedExtName(extName)}.json`;
|
|
148
147
|
}
|
|
@@ -156,7 +155,7 @@ export class ArgSpec {
|
|
|
156
155
|
* @param {string} [extName] - Extension name
|
|
157
156
|
* @returns {string} Unique ID
|
|
158
157
|
*/
|
|
159
|
-
static toArg
|
|
158
|
+
static toArg(name, extType, extName) {
|
|
160
159
|
const properName = _.kebabCase(name.replace(/^--?/, ''));
|
|
161
160
|
if (extType && extName) {
|
|
162
161
|
return [extType, _.kebabCase(extName), properName].join('-');
|
|
@@ -169,7 +168,7 @@ export class ArgSpec {
|
|
|
169
168
|
* @param {string} extName - Extension name
|
|
170
169
|
* @returns {string} Normalized extension name
|
|
171
170
|
*/
|
|
172
|
-
static toNormalizedExtName
|
|
171
|
+
static toNormalizedExtName(extName) {
|
|
173
172
|
return _.kebabCase(extName);
|
|
174
173
|
}
|
|
175
174
|
|
|
@@ -178,13 +177,11 @@ export class ArgSpec {
|
|
|
178
177
|
* @param {string} schemaId - Root schema ID
|
|
179
178
|
* @returns { {extType?: ExtensionType, normalizedExtName?: string} }
|
|
180
179
|
*/
|
|
181
|
-
static extensionInfoFromRootSchemaId
|
|
180
|
+
static extensionInfoFromRootSchemaId(schemaId) {
|
|
182
181
|
const matches = schemaId.match(SCHEMA_ID_REGEXP);
|
|
183
182
|
if (matches?.groups) {
|
|
184
183
|
const {extType, normalizedExtName} =
|
|
185
|
-
/** @type { {extType: ExtensionType, normalizedExtName: string} } */ (
|
|
186
|
-
matches.groups
|
|
187
|
-
);
|
|
184
|
+
/** @type { {extType: ExtensionType, normalizedExtName: string} } */ (matches.groups);
|
|
188
185
|
return {extType, normalizedExtName};
|
|
189
186
|
}
|
|
190
187
|
return {};
|
|
@@ -199,7 +196,7 @@ export class ArgSpec {
|
|
|
199
196
|
* @param {ArgSpecOptions<D>} [opts] - Options
|
|
200
197
|
* @returns {Readonly<ArgSpec>}
|
|
201
198
|
*/
|
|
202
|
-
static create
|
|
199
|
+
static create(name, opts) {
|
|
203
200
|
return Object.freeze(new ArgSpec(name, opts));
|
|
204
201
|
}
|
|
205
202
|
|
|
@@ -208,7 +205,7 @@ export class ArgSpec {
|
|
|
208
205
|
* @returns {string}
|
|
209
206
|
*/
|
|
210
207
|
/* istanbul ignore next */
|
|
211
|
-
toString
|
|
208
|
+
toString() {
|
|
212
209
|
let str = `[ArgSpec] ${this.name} (${this.ref})`;
|
|
213
210
|
if (this.extType && this.extName) {
|
|
214
211
|
str += ` (ext: ${this.extType}/${this.extName})`;
|
package/lib/schema/cli-args.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
1
|
import {ArgumentTypeError} from 'argparse';
|
|
3
2
|
import _ from 'lodash';
|
|
4
3
|
import {formatErrors as formatErrors} from '../config-file';
|
|
@@ -36,7 +35,7 @@ const SHORT_ARG_CUTOFF = 3;
|
|
|
36
35
|
* @param {string} [alias] - the alias to convert to a flag
|
|
37
36
|
* @returns {string} the flag
|
|
38
37
|
*/
|
|
39
|
-
function aliasToFlag
|
|
38
|
+
function aliasToFlag(argSpec, alias) {
|
|
40
39
|
const {extType, extName, name} = argSpec;
|
|
41
40
|
const arg = alias ?? name;
|
|
42
41
|
const isShort = arg.length < SHORT_ARG_CUTOFF;
|
|
@@ -64,7 +63,7 @@ const screamingSnakeCase = _.flow(_.snakeCase, _.toUpper);
|
|
|
64
63
|
* constructor options
|
|
65
64
|
* @returns
|
|
66
65
|
*/
|
|
67
|
-
function getSchemaValidator
|
|
66
|
+
function getSchemaValidator({ref: schemaId}, coerce = _.identity) {
|
|
68
67
|
/** @param {string} value */
|
|
69
68
|
return (value) => {
|
|
70
69
|
const coerced = coerce(value);
|
|
@@ -72,9 +71,7 @@ function getSchemaValidator ({ref: schemaId}, coerce = _.identity) {
|
|
|
72
71
|
if (_.isEmpty(errors)) {
|
|
73
72
|
return coerced;
|
|
74
73
|
}
|
|
75
|
-
throw new ArgumentTypeError(
|
|
76
|
-
'\n\n' + formatErrors(errors, value, {schemaId}),
|
|
77
|
-
);
|
|
74
|
+
throw new ArgumentTypeError('\n\n' + formatErrors(errors, value, {schemaId}));
|
|
78
75
|
};
|
|
79
76
|
}
|
|
80
77
|
|
|
@@ -83,7 +80,7 @@ function getSchemaValidator ({ref: schemaId}, coerce = _.identity) {
|
|
|
83
80
|
* @param {AppiumJSONSchema} schema
|
|
84
81
|
* @returns {string}
|
|
85
82
|
*/
|
|
86
|
-
function makeDescription
|
|
83
|
+
function makeDescription(schema) {
|
|
87
84
|
const {appiumCliDescription, description = '', appiumDeprecated} = schema;
|
|
88
85
|
let desc = appiumCliDescription ?? description;
|
|
89
86
|
if (appiumDeprecated) {
|
|
@@ -99,27 +96,20 @@ function makeDescription (schema) {
|
|
|
99
96
|
* @param {ArgSpec} argSpec - Argument spec tuple
|
|
100
97
|
* @returns {[string[], import('argparse').ArgumentOptions]} Tuple of flag and options
|
|
101
98
|
*/
|
|
102
|
-
function subSchemaToArgDef
|
|
103
|
-
let {
|
|
104
|
-
type,
|
|
105
|
-
appiumCliAliases,
|
|
106
|
-
appiumCliTransformer,
|
|
107
|
-
enum: enumValues,
|
|
108
|
-
} = subSchema;
|
|
99
|
+
function subSchemaToArgDef(subSchema, argSpec) {
|
|
100
|
+
let {type, appiumCliAliases, appiumCliTransformer, enum: enumValues} = subSchema;
|
|
109
101
|
|
|
110
102
|
const {name, arg} = argSpec;
|
|
111
103
|
|
|
112
104
|
const aliases = [
|
|
113
105
|
aliasToFlag(argSpec),
|
|
114
|
-
.../** @type {string[]} */ (appiumCliAliases ?? []).map((alias) =>
|
|
115
|
-
aliasToFlag(argSpec, alias),
|
|
116
|
-
),
|
|
106
|
+
.../** @type {string[]} */ (appiumCliAliases ?? []).map((alias) => aliasToFlag(argSpec, alias)),
|
|
117
107
|
];
|
|
118
108
|
|
|
119
109
|
/** @type {import('argparse').ArgumentOptions} */
|
|
120
110
|
let argOpts = {
|
|
121
111
|
required: false,
|
|
122
|
-
help: makeDescription(subSchema)
|
|
112
|
+
help: makeDescription(subSchema),
|
|
123
113
|
};
|
|
124
114
|
|
|
125
115
|
/**
|
|
@@ -182,9 +172,7 @@ function subSchemaToArgDef (subSchema, argSpec) {
|
|
|
182
172
|
case TYPENAMES.NULL:
|
|
183
173
|
// falls through
|
|
184
174
|
default: {
|
|
185
|
-
throw new TypeError(
|
|
186
|
-
`Schema property "${arg}": \`${type}\` type unknown or disallowed`,
|
|
187
|
-
);
|
|
175
|
+
throw new TypeError(`Schema property "${arg}": \`${type}\` type unknown or disallowed`);
|
|
188
176
|
}
|
|
189
177
|
}
|
|
190
178
|
|
|
@@ -198,15 +186,8 @@ function subSchemaToArgDef (subSchema, argSpec) {
|
|
|
198
186
|
// by ajv during schema validation in `finalizeSchema()`. the `array` &
|
|
199
187
|
// `object` types have already added a formatter (see above, so we don't do it
|
|
200
188
|
// twice).
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
type !== TYPENAMES.OBJECT &&
|
|
204
|
-
appiumCliTransformer
|
|
205
|
-
) {
|
|
206
|
-
argTypeFunction = _.flow(
|
|
207
|
-
argTypeFunction ?? _.identity,
|
|
208
|
-
transformers[appiumCliTransformer],
|
|
209
|
-
);
|
|
189
|
+
if (type !== TYPENAMES.ARRAY && type !== TYPENAMES.OBJECT && appiumCliTransformer) {
|
|
190
|
+
argTypeFunction = _.flow(argTypeFunction ?? _.identity, transformers[appiumCliTransformer]);
|
|
210
191
|
}
|
|
211
192
|
|
|
212
193
|
if (argTypeFunction) {
|
|
@@ -221,7 +202,7 @@ function subSchemaToArgDef (subSchema, argSpec) {
|
|
|
221
202
|
argOpts.choices = enumValues.map(String);
|
|
222
203
|
} else {
|
|
223
204
|
throw new TypeError(
|
|
224
|
-
`Problem with schema for ${arg}; \`enum\` is only supported for \`type: 'string'
|
|
205
|
+
`Problem with schema for ${arg}; \`enum\` is only supported for \`type: 'string'\``
|
|
225
206
|
);
|
|
226
207
|
}
|
|
227
208
|
}
|
|
@@ -237,13 +218,9 @@ function subSchemaToArgDef (subSchema, argSpec) {
|
|
|
237
218
|
* @returns {import('../cli/args').ArgumentDefinitions} A map of arryas of
|
|
238
219
|
* aliases to `argparse` arguments; empty if no schema found
|
|
239
220
|
*/
|
|
240
|
-
export function toParserArgs
|
|
221
|
+
export function toParserArgs() {
|
|
241
222
|
const flattened = flattenSchema().filter(({schema}) => !schema.appiumCliIgnored);
|
|
242
|
-
return new Map(
|
|
243
|
-
_.map(flattened, ({schema, argSpec}) =>
|
|
244
|
-
subSchemaToArgDef(schema, argSpec),
|
|
245
|
-
),
|
|
246
|
-
);
|
|
223
|
+
return new Map(_.map(flattened, ({schema, argSpec}) => subSchemaToArgDef(schema, argSpec)));
|
|
247
224
|
}
|
|
248
225
|
|
|
249
226
|
/**
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import { readFileSync } from 'fs';
|
|
1
|
+
import {ArgumentTypeError} from 'argparse';
|
|
2
|
+
import {readFileSync} from 'fs';
|
|
4
3
|
import _ from 'lodash';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -17,7 +16,7 @@ import _ from 'lodash';
|
|
|
17
16
|
* @param {string} value
|
|
18
17
|
* @returns {string[]}
|
|
19
18
|
*/
|
|
20
|
-
function parseCsvLine
|
|
19
|
+
function parseCsvLine(value) {
|
|
21
20
|
return value
|
|
22
21
|
.split(',')
|
|
23
22
|
.map((v) => v.trim())
|
|
@@ -29,7 +28,7 @@ function parseCsvLine (value) {
|
|
|
29
28
|
* @param {string} value
|
|
30
29
|
* @returns {string[]}
|
|
31
30
|
*/
|
|
32
|
-
function parseCsvFile
|
|
31
|
+
function parseCsvFile(value) {
|
|
33
32
|
return value
|
|
34
33
|
.split(/\r?\n/)
|
|
35
34
|
.map((v) => v.trim())
|
|
@@ -67,18 +66,14 @@ export const transformers = {
|
|
|
67
66
|
body = readFileSync(value, 'utf8');
|
|
68
67
|
} catch (err) {
|
|
69
68
|
if (err.code !== 'ENOENT') {
|
|
70
|
-
throw new ArgumentTypeError(
|
|
71
|
-
`Could not read file ${body}: ${err.message}`,
|
|
72
|
-
);
|
|
69
|
+
throw new ArgumentTypeError(`Could not read file ${body}: ${err.message}`);
|
|
73
70
|
}
|
|
74
71
|
}
|
|
75
72
|
|
|
76
73
|
try {
|
|
77
74
|
return body ? parseCsvFile(body) : parseCsvLine(value);
|
|
78
75
|
} catch (err) {
|
|
79
|
-
throw new ArgumentTypeError(
|
|
80
|
-
'Must be a comma-delimited string, e.g., "foo,bar,baz"',
|
|
81
|
-
);
|
|
76
|
+
throw new ArgumentTypeError('Must be a comma-delimited string, e.g., "foo,bar,baz"');
|
|
82
77
|
}
|
|
83
78
|
},
|
|
84
79
|
|
|
@@ -107,9 +102,7 @@ export const transformers = {
|
|
|
107
102
|
try {
|
|
108
103
|
const result = JSON.parse(json);
|
|
109
104
|
if (!_.isPlainObject(result)) {
|
|
110
|
-
throw new Error(
|
|
111
|
-
`'${_.truncate(result, {length: 100})}' is not an object`,
|
|
112
|
-
);
|
|
105
|
+
throw new Error(`'${_.truncate(result, {length: 100})}' is not an object`);
|
|
113
106
|
}
|
|
114
107
|
return result;
|
|
115
108
|
} catch (e) {
|