appium 2.0.0-beta.18 → 2.0.0-beta.21
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-config.schema.json +0 -0
- package/build/lib/appium.js +84 -69
- package/build/lib/cli/argparse-actions.js +1 -1
- package/build/lib/cli/args.js +87 -223
- package/build/lib/cli/extension-command.js +2 -2
- package/build/lib/cli/extension.js +14 -6
- package/build/lib/cli/parser.js +142 -106
- package/build/lib/cli/utils.js +1 -1
- package/build/lib/config-file.js +141 -0
- package/build/lib/config.js +42 -64
- package/build/lib/driver-config.js +41 -20
- package/build/lib/drivers.js +1 -1
- package/build/lib/ext-config-io.js +165 -0
- package/build/lib/extension-config.js +110 -60
- package/build/lib/grid-register.js +19 -21
- package/build/lib/logsink.js +1 -1
- package/build/lib/main.js +135 -72
- package/build/lib/plugin-config.js +17 -8
- package/build/lib/schema/appium-config-schema.js +252 -0
- package/build/lib/schema/arg-spec.js +120 -0
- package/build/lib/schema/cli-args.js +173 -0
- package/build/lib/schema/cli-transformers.js +76 -0
- package/build/lib/schema/index.js +36 -0
- package/build/lib/schema/keywords.js +62 -0
- package/build/lib/schema/schema.js +357 -0
- package/build/lib/utils.js +26 -35
- package/lib/appium-config.schema.json +277 -0
- package/lib/appium.js +99 -75
- package/lib/cli/args.js +138 -335
- package/lib/cli/extension-command.js +7 -6
- package/lib/cli/extension.js +12 -4
- package/lib/cli/parser.js +248 -96
- package/lib/config-file.js +227 -0
- package/lib/config.js +71 -61
- package/lib/driver-config.js +66 -11
- package/lib/ext-config-io.js +287 -0
- package/lib/extension-config.js +209 -66
- package/lib/grid-register.js +24 -21
- package/lib/main.js +139 -68
- package/lib/plugin-config.js +32 -2
- package/lib/schema/appium-config-schema.js +286 -0
- package/lib/schema/arg-spec.js +218 -0
- package/lib/schema/cli-args.js +273 -0
- package/lib/schema/cli-transformers.js +123 -0
- package/lib/schema/index.js +2 -0
- package/lib/schema/keywords.js +119 -0
- package/lib/schema/schema.js +577 -0
- package/lib/utils.js +29 -52
- package/package.json +17 -11
- package/types/appium-config.d.ts +197 -0
- package/types/types.d.ts +201 -0
- package/LICENSE +0 -201
- package/build/lib/cli/parser-helpers.js +0 -106
- package/lib/cli/parser-helpers.js +0 -106
package/lib/main.js
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
|
|
2
3
|
// transpile:main
|
|
4
|
+
// @ts-check
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
import
|
|
6
|
-
import _ from 'lodash';
|
|
7
|
-
import { server as baseServer, routeConfiguringFunction as makeRouter } from '@appium/base-driver';
|
|
8
|
-
import { asyncify } from 'asyncbox';
|
|
9
|
-
import { default as getParser, getDefaultServerArgs } from './cli/parser';
|
|
10
|
-
import { USE_ALL_PLUGINS } from './cli/args';
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
import { routeConfiguringFunction as makeRouter, server as baseServer } from '@appium/base-driver';
|
|
11
8
|
import { logger as logFactory, util } from '@appium/support';
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
warnNodeDeprecations, validateTmpDir, getNonDefaultArgs,
|
|
15
|
-
getGitRev, APPIUM_VER
|
|
16
|
-
} from './config';
|
|
17
|
-
import DriverConfig from './driver-config';
|
|
18
|
-
import PluginConfig from './plugin-config';
|
|
19
|
-
import { DRIVER_TYPE, PLUGIN_TYPE } from './extension-config';
|
|
20
|
-
import { runExtensionCommand } from './cli/extension';
|
|
9
|
+
import { asyncify } from 'asyncbox';
|
|
10
|
+
import _ from 'lodash';
|
|
21
11
|
import { AppiumDriver } from './appium';
|
|
12
|
+
import { driverConfig, pluginConfig, USE_ALL_PLUGINS } from './cli/args';
|
|
13
|
+
import { runExtensionCommand } from './cli/extension';
|
|
14
|
+
import { default as getParser, SERVER_SUBCOMMAND } from './cli/parser';
|
|
15
|
+
import { APPIUM_VER, checkNodeOk, getGitRev, getNonDefaultServerArgs, showConfig, validateTmpDir, warnNodeDeprecations } from './config';
|
|
16
|
+
import { readConfigFile } from './config-file';
|
|
17
|
+
import { DRIVER_TYPE, PLUGIN_TYPE } from './extension-config';
|
|
22
18
|
import registerNode from './grid-register';
|
|
19
|
+
import logger from './logger'; // logger needs to remain first of imports
|
|
20
|
+
import { init as logsinkInit } from './logsink';
|
|
21
|
+
import { getDefaultsFromSchema, validate } from './schema/schema';
|
|
23
22
|
import { inspectObject } from './utils';
|
|
24
23
|
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
/**
|
|
25
|
+
*
|
|
26
|
+
* @param {ParsedArgs} args
|
|
27
|
+
* @param {boolean} [throwInsteadOfExit]
|
|
28
|
+
*/
|
|
29
|
+
async function preflightChecks (args, throwInsteadOfExit = false) {
|
|
27
30
|
try {
|
|
28
31
|
checkNodeOk();
|
|
29
32
|
if (args.longStacktrace) {
|
|
@@ -34,9 +37,9 @@ async function preflightChecks ({parser, args, driverConfig, pluginConfig, throw
|
|
|
34
37
|
process.exit(0);
|
|
35
38
|
}
|
|
36
39
|
warnNodeDeprecations();
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
+
|
|
41
|
+
validate(args);
|
|
42
|
+
|
|
40
43
|
if (args.tmpDir) {
|
|
41
44
|
await validateTmpDir(args.tmpDir);
|
|
42
45
|
}
|
|
@@ -69,7 +72,7 @@ async function logStartupInfo (parser, args) {
|
|
|
69
72
|
}
|
|
70
73
|
logger.info(welcome);
|
|
71
74
|
|
|
72
|
-
let showArgs =
|
|
75
|
+
let showArgs = getNonDefaultServerArgs(parser, args);
|
|
73
76
|
if (_.size(showArgs)) {
|
|
74
77
|
logNonDefaultArgsWarning(showArgs);
|
|
75
78
|
}
|
|
@@ -96,25 +99,26 @@ function logServerPort (address, port) {
|
|
|
96
99
|
* wrap command execution
|
|
97
100
|
*
|
|
98
101
|
* @param {Object} args - argparser parsed dict
|
|
99
|
-
* @param {
|
|
102
|
+
* @param {import('./plugin-config').default} pluginConfig - a plugin extension config
|
|
103
|
+
* @returns {({pluginName: string} & ((...args: any[]) => unknown))[]}
|
|
100
104
|
*/
|
|
101
105
|
function getActivePlugins (args, pluginConfig) {
|
|
102
|
-
return Object.keys(pluginConfig.installedExtensions).filter((pluginName) =>
|
|
103
|
-
_.includes(args.
|
|
104
|
-
(args.
|
|
106
|
+
return _.compact(Object.keys(pluginConfig.installedExtensions).filter((pluginName) =>
|
|
107
|
+
_.includes(args.usePlugins, pluginName) ||
|
|
108
|
+
(args.usePlugins.length === 1 && args.usePlugins[0] === USE_ALL_PLUGINS)
|
|
105
109
|
).map((pluginName) => {
|
|
106
110
|
try {
|
|
107
111
|
logger.info(`Attempting to load plugin ${pluginName}...`);
|
|
108
|
-
const PluginClass = pluginConfig.require(pluginName);
|
|
112
|
+
const PluginClass = /** @type {{pluginName: string} & ((...args: any[]) => unknown)} */(pluginConfig.require(pluginName));
|
|
113
|
+
|
|
109
114
|
PluginClass.pluginName = pluginName; // store the plugin name on the class so it can be used later
|
|
110
115
|
return PluginClass;
|
|
111
116
|
} catch (err) {
|
|
112
117
|
logger.error(`Could not load plugin '${pluginName}', so it will not be available. Error ` +
|
|
113
118
|
`in loading the plugin was: ${err.message}`);
|
|
114
119
|
logger.debug(err.stack);
|
|
115
|
-
return false;
|
|
116
120
|
}
|
|
117
|
-
})
|
|
121
|
+
}));
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
/**
|
|
@@ -123,11 +127,11 @@ function getActivePlugins (args, pluginConfig) {
|
|
|
123
127
|
* If the --drivers flag was given, this method only loads the given drivers.
|
|
124
128
|
*
|
|
125
129
|
* @param {Object} args - argparser parsed dict
|
|
126
|
-
* @param {
|
|
130
|
+
* @param {import('./driver-config').default} driverConfig - a driver extension config
|
|
127
131
|
*/
|
|
128
132
|
function getActiveDrivers (args, driverConfig) {
|
|
129
|
-
return Object.keys(driverConfig.installedExtensions).filter((driverName) =>
|
|
130
|
-
_.includes(args.
|
|
133
|
+
return _.compact(Object.keys(driverConfig.installedExtensions).filter((driverName) =>
|
|
134
|
+
_.includes(args.useDrivers, driverName) || args.useDrivers.length === 0
|
|
131
135
|
).map((driverName) => {
|
|
132
136
|
try {
|
|
133
137
|
logger.info(`Attempting to load driver ${driverName}...`);
|
|
@@ -136,9 +140,8 @@ function getActiveDrivers (args, driverConfig) {
|
|
|
136
140
|
logger.error(`Could not load driver '${driverName}', so it will not be available. Error ` +
|
|
137
141
|
`in loading the driver was: ${err.message}`);
|
|
138
142
|
logger.debug(err.stack);
|
|
139
|
-
return false;
|
|
140
143
|
}
|
|
141
|
-
})
|
|
144
|
+
}));
|
|
142
145
|
}
|
|
143
146
|
|
|
144
147
|
function getServerUpdaters (driverClasses, pluginClasses) {
|
|
@@ -152,14 +155,25 @@ function getExtraMethodMap (driverClasses, pluginClasses) {
|
|
|
152
155
|
);
|
|
153
156
|
}
|
|
154
157
|
|
|
155
|
-
|
|
156
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Initializes Appium, but does not start the server.
|
|
160
|
+
*
|
|
161
|
+
* Use this to get at the configuration schema.
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* import {init, getSchema} from 'appium';
|
|
165
|
+
* const options = {}; // config object
|
|
166
|
+
* await init(options);
|
|
167
|
+
* const schema = getSchema(); // entire config schema including plugins and drivers
|
|
168
|
+
* @param {ParsedArgs} [args] - Parsed args
|
|
169
|
+
* @returns {Promise<{parser: import('./cli/parser').ArgParser} & Partial<{appiumDriver: AppiumDriver, parsedArgs: ParsedArgs}>>}
|
|
170
|
+
*/
|
|
171
|
+
async function init (args) {
|
|
172
|
+
const parser = await getParser();
|
|
157
173
|
let throwInsteadOfExit = false;
|
|
174
|
+
/** @type {ParsedArgs} */
|
|
175
|
+
let parsedArgs;
|
|
158
176
|
if (args) {
|
|
159
|
-
// a containing package passed in their own args, let's fill them out
|
|
160
|
-
// with defaults
|
|
161
|
-
args = Object.assign({}, getDefaultServerArgs(), args);
|
|
162
|
-
|
|
163
177
|
// if we have a containing package instead of running as a CLI process,
|
|
164
178
|
// that package might not appreciate us calling 'process.exit' willy-
|
|
165
179
|
// nilly, so give it the option to have us throw instead of exit
|
|
@@ -168,59 +182,106 @@ async function main (args = null) {
|
|
|
168
182
|
// but remove it since it's not a real server arg per se
|
|
169
183
|
delete args.throwInsteadOfExit;
|
|
170
184
|
}
|
|
185
|
+
parsedArgs = {...args, subcommand: args.subcommand ?? SERVER_SUBCOMMAND};
|
|
171
186
|
} else {
|
|
172
187
|
// otherwise parse from CLI
|
|
173
|
-
|
|
188
|
+
parsedArgs = parser.parseArgs();
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const configResult = await readConfigFile(parsedArgs.configFile);
|
|
192
|
+
|
|
193
|
+
if (!_.isEmpty(configResult.errors)) {
|
|
194
|
+
throw new Error(`Errors in config file ${configResult.filepath}:\n ${configResult.reason ?? configResult.errors}`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// merge config and apply defaults.
|
|
198
|
+
// the order of precendece is:
|
|
199
|
+
// 1. command line args
|
|
200
|
+
// 2. config file
|
|
201
|
+
// 3. defaults from config file.
|
|
202
|
+
if (parsedArgs.subcommand === SERVER_SUBCOMMAND) {
|
|
203
|
+
parsedArgs = _.defaultsDeep(
|
|
204
|
+
parsedArgs,
|
|
205
|
+
configResult.config?.server,
|
|
206
|
+
getDefaultsFromSchema()
|
|
207
|
+
);
|
|
174
208
|
}
|
|
175
|
-
|
|
209
|
+
|
|
210
|
+
parsedArgs = _.defaultsDeep(
|
|
211
|
+
parsedArgs,
|
|
212
|
+
configResult.config ?? {},
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
await logsinkInit(parsedArgs);
|
|
176
216
|
|
|
177
217
|
// if the user has requested the 'driver' CLI, don't run the normal server,
|
|
178
218
|
// but instead pass control to the driver CLI
|
|
179
|
-
if (
|
|
180
|
-
await runExtensionCommand(
|
|
181
|
-
|
|
219
|
+
if (parsedArgs.subcommand === DRIVER_TYPE) {
|
|
220
|
+
await runExtensionCommand(parsedArgs, parsedArgs.subcommand, driverConfig);
|
|
221
|
+
return {parser};
|
|
222
|
+
}
|
|
223
|
+
if (parsedArgs.subcommand === PLUGIN_TYPE) {
|
|
224
|
+
await runExtensionCommand(parsedArgs, parsedArgs.subcommand, pluginConfig);
|
|
225
|
+
return {parser};
|
|
182
226
|
}
|
|
183
227
|
|
|
184
|
-
if (
|
|
185
|
-
const {issues, rules} = await logFactory.loadSecureValuesPreprocessingRules(
|
|
228
|
+
if (parsedArgs.logFilters) {
|
|
229
|
+
const {issues, rules} = await logFactory.loadSecureValuesPreprocessingRules(parsedArgs.logFilters);
|
|
186
230
|
if (!_.isEmpty(issues)) {
|
|
187
|
-
throw new Error(`The log filtering rules config '${
|
|
231
|
+
throw new Error(`The log filtering rules config '${parsedArgs.logFilters}' has issues: ` +
|
|
188
232
|
JSON.stringify(issues, null, 2));
|
|
189
233
|
}
|
|
190
234
|
if (_.isEmpty(rules)) {
|
|
191
|
-
logger.warn(`Found no log filtering rules in '${
|
|
235
|
+
logger.warn(`Found no log filtering rules in '${parsedArgs.logFilters}'. Is that expected?`);
|
|
192
236
|
} else {
|
|
193
|
-
logger.info(`Loaded ${util.pluralize('filtering rule', rules.length, true)} from '${
|
|
237
|
+
logger.info(`Loaded ${util.pluralize('filtering rule', rules.length, true)} from '${parsedArgs.logFilters}'`);
|
|
194
238
|
}
|
|
195
239
|
}
|
|
196
240
|
|
|
197
|
-
|
|
198
|
-
const driverConfig = new DriverConfig(args.appiumHome);
|
|
241
|
+
const appiumDriver = new AppiumDriver(parsedArgs);
|
|
199
242
|
// set the config on the umbrella driver so it can match drivers to caps
|
|
200
243
|
appiumDriver.driverConfig = driverConfig;
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
244
|
+
await preflightChecks(parsedArgs, throwInsteadOfExit);
|
|
245
|
+
|
|
246
|
+
return {parser, appiumDriver, parsedArgs};
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
*
|
|
251
|
+
* @param {ParsedArgs} [args]
|
|
252
|
+
* @returns
|
|
253
|
+
*/
|
|
254
|
+
async function main (args) {
|
|
255
|
+
const {parser, appiumDriver, parsedArgs} = await init(args);
|
|
256
|
+
|
|
257
|
+
if (!appiumDriver || !parsedArgs) {
|
|
258
|
+
// if this branch is taken, we've run a different subcommand, so there's nothing
|
|
259
|
+
// left to do here.
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const pluginClasses = getActivePlugins(parsedArgs, pluginConfig);
|
|
204
264
|
// set the active plugins on the umbrella driver so it can use them for commands
|
|
205
265
|
appiumDriver.pluginClasses = pluginClasses;
|
|
206
|
-
|
|
266
|
+
|
|
267
|
+
await logStartupInfo(parser, parsedArgs);
|
|
207
268
|
let routeConfiguringFunction = makeRouter(appiumDriver);
|
|
208
269
|
|
|
209
|
-
const driverClasses = getActiveDrivers(
|
|
270
|
+
const driverClasses = getActiveDrivers(parsedArgs, driverConfig);
|
|
210
271
|
const serverUpdaters = getServerUpdaters(driverClasses, pluginClasses);
|
|
211
272
|
const extraMethodMap = getExtraMethodMap(driverClasses, pluginClasses);
|
|
212
273
|
|
|
213
274
|
const serverOpts = {
|
|
214
275
|
routeConfiguringFunction,
|
|
215
|
-
port:
|
|
216
|
-
hostname:
|
|
217
|
-
allowCors:
|
|
218
|
-
basePath:
|
|
276
|
+
port: parsedArgs.port,
|
|
277
|
+
hostname: parsedArgs.address,
|
|
278
|
+
allowCors: parsedArgs.allowCors,
|
|
279
|
+
basePath: parsedArgs.basePath,
|
|
219
280
|
serverUpdaters,
|
|
220
281
|
extraMethodMap,
|
|
221
282
|
};
|
|
222
|
-
if (
|
|
223
|
-
serverOpts.keepAliveTimeout =
|
|
283
|
+
if (parsedArgs.keepAliveTimeout) {
|
|
284
|
+
serverOpts.keepAliveTimeout = parsedArgs.keepAliveTimeout * 1000;
|
|
224
285
|
}
|
|
225
286
|
let server;
|
|
226
287
|
try {
|
|
@@ -232,16 +293,18 @@ async function main (args = null) {
|
|
|
232
293
|
return process.exit(1);
|
|
233
294
|
}
|
|
234
295
|
|
|
235
|
-
if (
|
|
296
|
+
if (parsedArgs.allowCors) {
|
|
236
297
|
logger.warn('You have enabled CORS requests from any host. Be careful not ' +
|
|
237
298
|
'to visit sites which could maliciously try to start Appium ' +
|
|
238
299
|
'sessions on your machine');
|
|
239
300
|
}
|
|
301
|
+
// @ts-ignore
|
|
240
302
|
appiumDriver.server = server;
|
|
241
303
|
try {
|
|
242
304
|
// configure as node on grid, if necessary
|
|
243
|
-
|
|
244
|
-
|
|
305
|
+
// falsy values should not cause this to run
|
|
306
|
+
if (parsedArgs.nodeconfig) {
|
|
307
|
+
await registerNode(parsedArgs.nodeconfig, parsedArgs.address, parsedArgs.port, parsedArgs.basePath);
|
|
245
308
|
}
|
|
246
309
|
} catch (err) {
|
|
247
310
|
await server.close();
|
|
@@ -265,7 +328,7 @@ async function main (args = null) {
|
|
|
265
328
|
});
|
|
266
329
|
}
|
|
267
330
|
|
|
268
|
-
logServerPort(
|
|
331
|
+
logServerPort(parsedArgs.address, parsedArgs.port);
|
|
269
332
|
driverConfig.print();
|
|
270
333
|
pluginConfig.print(pluginClasses.map((p) => p.pluginName));
|
|
271
334
|
|
|
@@ -276,4 +339,12 @@ if (require.main === module) {
|
|
|
276
339
|
asyncify(main);
|
|
277
340
|
}
|
|
278
341
|
|
|
279
|
-
|
|
342
|
+
// everything below here is intended to be a public API.
|
|
343
|
+
export { main, init };
|
|
344
|
+
export { APPIUM_HOME } from './extension-config';
|
|
345
|
+
export { getSchema, validate, finalizeSchema } from './schema/schema';
|
|
346
|
+
export { readConfigFile } from './config-file';
|
|
347
|
+
|
|
348
|
+
/**
|
|
349
|
+
* @typedef {import('../types/types').ParsedArgs} ParsedArgs
|
|
350
|
+
*/
|
package/lib/plugin-config.js
CHANGED
|
@@ -1,12 +1,42 @@
|
|
|
1
1
|
import _ from 'lodash';
|
|
2
|
-
import ExtensionConfig
|
|
2
|
+
import ExtensionConfig from './extension-config';
|
|
3
|
+
import { PLUGIN_TYPE } from './ext-config-io';
|
|
3
4
|
import log from './logger';
|
|
4
5
|
|
|
5
6
|
export default class PluginConfig extends ExtensionConfig {
|
|
6
|
-
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* A mapping of `APPIUM_HOME` values to {@link PluginConfig} instances.
|
|
10
|
+
* Each `APPIUM_HOME` should only have one associated `PluginConfig` instance.
|
|
11
|
+
* @type {Record<string,PluginConfig>}
|
|
12
|
+
* @private
|
|
13
|
+
*/
|
|
14
|
+
static _instances = {};
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Call {@link PluginConfig.getInstance} instead.
|
|
18
|
+
*
|
|
19
|
+
* Just calls the superclass' constructor with the correct extension type
|
|
20
|
+
* @private
|
|
21
|
+
* @param {string} appiumHome - `APPIUM_HOME` path
|
|
22
|
+
* @param {(...args: any[]) => void)} [logFn] - Optional logging function
|
|
23
|
+
*/
|
|
24
|
+
constructor (appiumHome, logFn) {
|
|
7
25
|
super(appiumHome, PLUGIN_TYPE, logFn);
|
|
8
26
|
}
|
|
9
27
|
|
|
28
|
+
/**
|
|
29
|
+
* Creates or gets an instance of {@link PluginConfig} based value of `appiumHome`
|
|
30
|
+
* @param {string} appiumHome - `APPIUM_HOME` path
|
|
31
|
+
* @param {(...args: any[]) => void} [logFn] - Optional logging function
|
|
32
|
+
* @returns {PluginConfig}
|
|
33
|
+
*/
|
|
34
|
+
static getInstance (appiumHome, logFn) {
|
|
35
|
+
const instance = PluginConfig._instances[appiumHome] ?? new PluginConfig(appiumHome, logFn);
|
|
36
|
+
PluginConfig._instances[appiumHome] = instance;
|
|
37
|
+
return instance;
|
|
38
|
+
}
|
|
39
|
+
|
|
10
40
|
extensionDesc (pluginName, {version}) {
|
|
11
41
|
return `${pluginName}@${version}`;
|
|
12
42
|
}
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
const schema = /** @type {const} */ ({
|
|
4
|
+
$schema: 'http://json-schema.org/draft-07/schema',
|
|
5
|
+
additionalProperties: false,
|
|
6
|
+
description: 'A schema for Appium configuration files',
|
|
7
|
+
properties: {
|
|
8
|
+
server: {
|
|
9
|
+
additionalProperties: false,
|
|
10
|
+
description: 'Configuration when running Appium as a server',
|
|
11
|
+
properties: {
|
|
12
|
+
address: {
|
|
13
|
+
$comment:
|
|
14
|
+
'I think hostname covers both DNS and IPv4...could be wrong',
|
|
15
|
+
appiumCliAliases: ['a'],
|
|
16
|
+
default: '0.0.0.0',
|
|
17
|
+
description: 'IP address to listen on',
|
|
18
|
+
format: 'hostname',
|
|
19
|
+
title: 'address config',
|
|
20
|
+
type: 'string',
|
|
21
|
+
},
|
|
22
|
+
'allow-cors': {
|
|
23
|
+
description:
|
|
24
|
+
'Whether the Appium server should allow web browser connections from any host',
|
|
25
|
+
title: 'allow-cors config',
|
|
26
|
+
type: 'boolean',
|
|
27
|
+
default: false,
|
|
28
|
+
},
|
|
29
|
+
'allow-insecure': {
|
|
30
|
+
appiumCliTransformer: 'csv',
|
|
31
|
+
default: [],
|
|
32
|
+
description:
|
|
33
|
+
'Set which insecure features are allowed to run in this server\'s sessions. Features are defined on a driver level; see documentation for more details. Note that features defined via "deny-insecure" will be disabled, even if also listed here. If string, a path to a text file containing policy or a comma-delimited list.',
|
|
34
|
+
items: {
|
|
35
|
+
type: 'string',
|
|
36
|
+
},
|
|
37
|
+
title: 'allow-insecure config',
|
|
38
|
+
type: 'array',
|
|
39
|
+
uniqueItems: true,
|
|
40
|
+
},
|
|
41
|
+
'base-path': {
|
|
42
|
+
appiumCliAliases: ['pa'],
|
|
43
|
+
default: '',
|
|
44
|
+
description:
|
|
45
|
+
'Base path to use as the prefix for all webdriver routes running on the server',
|
|
46
|
+
title: 'base-path config',
|
|
47
|
+
type: 'string',
|
|
48
|
+
},
|
|
49
|
+
'callback-address': {
|
|
50
|
+
appiumCliAliases: ['ca'],
|
|
51
|
+
description: 'Callback IP address (default: same as "address")',
|
|
52
|
+
title: 'callback-address config',
|
|
53
|
+
type: 'string',
|
|
54
|
+
},
|
|
55
|
+
'callback-port': {
|
|
56
|
+
appiumCliAliases: ['cp'],
|
|
57
|
+
default: 4723,
|
|
58
|
+
description: 'Callback port (default: same as "port")',
|
|
59
|
+
maximum: 65535,
|
|
60
|
+
minimum: 1,
|
|
61
|
+
title: 'callback-port config',
|
|
62
|
+
type: 'integer',
|
|
63
|
+
},
|
|
64
|
+
'debug-log-spacing': {
|
|
65
|
+
default: false,
|
|
66
|
+
description:
|
|
67
|
+
'Add exaggerated spacing in logs to help with visual inspection',
|
|
68
|
+
title: 'debug-log-spacing config',
|
|
69
|
+
type: 'boolean',
|
|
70
|
+
},
|
|
71
|
+
'default-capabilities': {
|
|
72
|
+
$comment: 'TODO',
|
|
73
|
+
appiumCliAliases: ['dc'],
|
|
74
|
+
description:
|
|
75
|
+
'Set the default desired capabilities, which will be set on each session unless overridden by received capabilities. If a string, a path to a JSON file containing the capabilities, or raw JSON.',
|
|
76
|
+
title: 'default-capabilities config',
|
|
77
|
+
type: 'object',
|
|
78
|
+
},
|
|
79
|
+
'deny-insecure': {
|
|
80
|
+
$comment: 'Allowed values are defined by drivers',
|
|
81
|
+
appiumCliTransformer: 'csv',
|
|
82
|
+
default: [],
|
|
83
|
+
description:
|
|
84
|
+
'Set which insecure features are not allowed to run in this server\'s sessions. Features are defined on a driver level; see documentation for more details. Features listed here will not be enabled even if also listed in "allow-insecure", and even if "relaxed-security" is enabled. If string, a path to a text file containing policy or a comma-delimited list.',
|
|
85
|
+
items: {
|
|
86
|
+
type: 'string',
|
|
87
|
+
},
|
|
88
|
+
title: 'deny-insecure config',
|
|
89
|
+
type: 'array',
|
|
90
|
+
uniqueItems: true,
|
|
91
|
+
},
|
|
92
|
+
driver: {
|
|
93
|
+
description:
|
|
94
|
+
'Driver-specific configuration. Keys should correspond to driver package names',
|
|
95
|
+
properties: {},
|
|
96
|
+
title: 'driver config',
|
|
97
|
+
type: 'object',
|
|
98
|
+
},
|
|
99
|
+
'keep-alive-timeout': {
|
|
100
|
+
appiumCliAliases: ['ka'],
|
|
101
|
+
default: 600,
|
|
102
|
+
description:
|
|
103
|
+
'Number of seconds the Appium server should apply as both the keep-alive timeout and the connection timeout for all requests. A value of 0 disables the timeout.',
|
|
104
|
+
minimum: 0,
|
|
105
|
+
title: 'keep-alive-timeout config',
|
|
106
|
+
type: 'integer',
|
|
107
|
+
},
|
|
108
|
+
'local-timezone': {
|
|
109
|
+
default: false,
|
|
110
|
+
description: 'Use local timezone for timestamps',
|
|
111
|
+
title: 'local-timezone config',
|
|
112
|
+
type: 'boolean',
|
|
113
|
+
},
|
|
114
|
+
log: {
|
|
115
|
+
appiumCliAliases: ['g'],
|
|
116
|
+
appiumCliDest: 'logFile',
|
|
117
|
+
description: 'Also send log output to this file',
|
|
118
|
+
title: 'log config',
|
|
119
|
+
type: 'string',
|
|
120
|
+
},
|
|
121
|
+
'log-filters': {
|
|
122
|
+
$comment: 'TODO',
|
|
123
|
+
description: 'One or more log filtering rules',
|
|
124
|
+
items: {
|
|
125
|
+
type: 'string',
|
|
126
|
+
},
|
|
127
|
+
title: 'log-filters config',
|
|
128
|
+
type: 'array',
|
|
129
|
+
},
|
|
130
|
+
'log-level': {
|
|
131
|
+
appiumCliDest: 'loglevel',
|
|
132
|
+
default: 'debug',
|
|
133
|
+
description: 'Log level (console[:file])',
|
|
134
|
+
enum: [
|
|
135
|
+
'info',
|
|
136
|
+
'info:debug',
|
|
137
|
+
'info:info',
|
|
138
|
+
'info:warn',
|
|
139
|
+
'info:error',
|
|
140
|
+
'warn',
|
|
141
|
+
'warn:debug',
|
|
142
|
+
'warn:info',
|
|
143
|
+
'warn:warn',
|
|
144
|
+
'warn:error',
|
|
145
|
+
'error',
|
|
146
|
+
'error:debug',
|
|
147
|
+
'error:info',
|
|
148
|
+
'error:warn',
|
|
149
|
+
'error:error',
|
|
150
|
+
'debug',
|
|
151
|
+
'debug:debug',
|
|
152
|
+
'debug:info',
|
|
153
|
+
'debug:warn',
|
|
154
|
+
'debug:error',
|
|
155
|
+
],
|
|
156
|
+
title: 'log-level config',
|
|
157
|
+
type: 'string',
|
|
158
|
+
},
|
|
159
|
+
'log-no-colors': {
|
|
160
|
+
default: false,
|
|
161
|
+
description: 'Do not use color in console output',
|
|
162
|
+
title: 'log-no-colors config',
|
|
163
|
+
type: 'boolean',
|
|
164
|
+
},
|
|
165
|
+
'log-timestamp': {
|
|
166
|
+
default: false,
|
|
167
|
+
description: 'Show timestamps in console output',
|
|
168
|
+
title: 'log-timestamp config',
|
|
169
|
+
type: 'boolean',
|
|
170
|
+
},
|
|
171
|
+
'long-stacktrace': {
|
|
172
|
+
default: false,
|
|
173
|
+
description:
|
|
174
|
+
'Add long stack traces to log entries. Recommended for debugging only.',
|
|
175
|
+
title: 'long-stacktrace config',
|
|
176
|
+
type: 'boolean',
|
|
177
|
+
},
|
|
178
|
+
'no-perms-check': {
|
|
179
|
+
default: false,
|
|
180
|
+
description:
|
|
181
|
+
'Do not check that needed files are readable and/or writable',
|
|
182
|
+
title: 'no-perms-check config',
|
|
183
|
+
type: 'boolean',
|
|
184
|
+
},
|
|
185
|
+
nodeconfig: {
|
|
186
|
+
$comment:
|
|
187
|
+
'Selenium Grid 3 is unmaintained and Selenium Grid 4 no longer supports this file.',
|
|
188
|
+
description:
|
|
189
|
+
'Path to configuration JSON file to register Appium as a node with Selenium Grid 3; otherwise the configuration itself',
|
|
190
|
+
title: 'nodeconfig config',
|
|
191
|
+
type: 'object',
|
|
192
|
+
},
|
|
193
|
+
plugin: {
|
|
194
|
+
description:
|
|
195
|
+
'Plugin-specific configuration. Keys should correspond to plugin package names',
|
|
196
|
+
properties: {},
|
|
197
|
+
title: 'plugin config',
|
|
198
|
+
type: 'object',
|
|
199
|
+
},
|
|
200
|
+
port: {
|
|
201
|
+
appiumCliAliases: ['p'],
|
|
202
|
+
default: 4723,
|
|
203
|
+
description: 'Port to listen on',
|
|
204
|
+
maximum: 65535,
|
|
205
|
+
minimum: 1,
|
|
206
|
+
title: 'port config',
|
|
207
|
+
type: 'integer',
|
|
208
|
+
},
|
|
209
|
+
'relaxed-security': {
|
|
210
|
+
default: false,
|
|
211
|
+
description:
|
|
212
|
+
'Disable additional security checks, so it is possible to use some advanced features, provided by drivers supporting this option. Only enable it if all the clients are in the trusted network and it\'s not the case if a client could potentially break out of the session sandbox. Specific features can be overridden by using "deny-insecure"',
|
|
213
|
+
title: 'relaxed-security config',
|
|
214
|
+
type: 'boolean',
|
|
215
|
+
},
|
|
216
|
+
'session-override': {
|
|
217
|
+
default: false,
|
|
218
|
+
description: 'Enables session override (clobbering)',
|
|
219
|
+
title: 'session-override config',
|
|
220
|
+
type: 'boolean',
|
|
221
|
+
},
|
|
222
|
+
'strict-caps': {
|
|
223
|
+
default: false,
|
|
224
|
+
description:
|
|
225
|
+
'Cause sessions to fail if desired caps are sent in that Appium does not recognize as valid for the selected device',
|
|
226
|
+
title: 'strict-caps config',
|
|
227
|
+
type: 'boolean',
|
|
228
|
+
},
|
|
229
|
+
tmp: {
|
|
230
|
+
appiumCliDest: 'tmpDir',
|
|
231
|
+
description:
|
|
232
|
+
'Absolute path to directory Appium can use to manage temp files. Defaults to C:\\Windows\\Temp on Windows and /tmp otherwise.',
|
|
233
|
+
title: 'tmp config',
|
|
234
|
+
type: 'string',
|
|
235
|
+
},
|
|
236
|
+
'trace-dir': {
|
|
237
|
+
description:
|
|
238
|
+
'Absolute path to directory Appium can use to save iOS instrument traces; defaults to <tmp>/appium-instruments',
|
|
239
|
+
title: 'trace-dir config',
|
|
240
|
+
type: 'string',
|
|
241
|
+
},
|
|
242
|
+
'use-drivers': {
|
|
243
|
+
appiumCliDescription:
|
|
244
|
+
'A list of drivers to activate. Can be a comma-delimited string or path to CSV file. By default, all installed drivers will be activated.',
|
|
245
|
+
default: [],
|
|
246
|
+
description:
|
|
247
|
+
'A list of drivers to activate. By default, all installed drivers will be activated.',
|
|
248
|
+
items: {
|
|
249
|
+
type: 'string',
|
|
250
|
+
},
|
|
251
|
+
title: 'use-drivers config',
|
|
252
|
+
type: 'array',
|
|
253
|
+
uniqueItems: true,
|
|
254
|
+
},
|
|
255
|
+
'use-plugins': {
|
|
256
|
+
appiumCliDescription:
|
|
257
|
+
'A list of plugins to activate. Can be a comma-delimited string, path to CSV file, or the string "all" to use all installed plugins.',
|
|
258
|
+
default: [],
|
|
259
|
+
description:
|
|
260
|
+
'A list of plugins to activate. To activate all plugins, the value should be an array with a single item "all".',
|
|
261
|
+
items: {
|
|
262
|
+
type: 'string',
|
|
263
|
+
},
|
|
264
|
+
title: 'use-plugins config',
|
|
265
|
+
type: 'array',
|
|
266
|
+
uniqueItems: true,
|
|
267
|
+
},
|
|
268
|
+
webhook: {
|
|
269
|
+
$comment:
|
|
270
|
+
'This should probably use a uri-template format to restrict the protocol to http/https',
|
|
271
|
+
appiumCliAliases: ['G'],
|
|
272
|
+
description: 'Also send log output to this http listener',
|
|
273
|
+
format: 'uri',
|
|
274
|
+
title: 'webhook config',
|
|
275
|
+
type: 'string',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
title: 'server config',
|
|
279
|
+
type: 'object',
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
title: 'Appium Configuration',
|
|
283
|
+
type: 'object',
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
export default schema;
|