appium 2.0.0-beta.2 → 2.0.0-beta.23
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/README.md +9 -9
- package/build/check-npm-pack-files.js +23 -0
- package/build/commands-yml/parse.js +319 -0
- package/build/commands-yml/validator.js +130 -0
- package/build/index.js +19 -0
- package/build/lib/appium-config.schema.json +0 -0
- package/build/lib/appium.js +160 -53
- package/build/lib/cli/args.js +115 -279
- package/build/lib/cli/driver-command.js +11 -1
- package/build/lib/cli/extension-command.js +60 -8
- package/build/lib/cli/extension.js +30 -7
- package/build/lib/cli/npm.js +43 -29
- package/build/lib/cli/parser.js +156 -89
- package/build/lib/cli/plugin-command.js +11 -1
- package/build/lib/cli/utils.js +29 -3
- package/build/lib/config-file.js +141 -0
- package/build/lib/config.js +53 -65
- package/build/lib/driver-config.js +42 -19
- package/build/lib/drivers.js +8 -4
- package/build/lib/ext-config-io.js +165 -0
- package/build/lib/extension-config.js +130 -61
- package/build/lib/grid-register.js +22 -24
- package/build/lib/logger.js +3 -3
- package/build/lib/logsink.js +11 -13
- package/build/lib/main.js +197 -77
- package/build/lib/plugin-config.js +21 -11
- package/build/lib/plugins.js +4 -2
- package/build/lib/schema/appium-config-schema.js +253 -0
- package/build/lib/schema/arg-spec.js +120 -0
- package/build/lib/schema/cli-args.js +188 -0
- package/build/lib/schema/cli-transformers.js +76 -0
- package/build/lib/schema/index.js +36 -0
- package/build/lib/schema/keywords.js +72 -0
- package/build/lib/schema/schema.js +357 -0
- package/build/lib/utils.js +44 -99
- package/build/postinstall.js +90 -0
- package/build/test/cli/cli-e2e-specs.js +221 -0
- package/build/test/cli/cli-helpers.js +86 -0
- package/build/test/cli/cli-specs.js +71 -0
- package/build/test/cli/fixtures/test-driver/package.json +27 -0
- package/build/test/cli/schema-args-specs.js +48 -0
- package/build/test/cli/schema-e2e-specs.js +47 -0
- package/build/test/config-e2e-specs.js +112 -0
- package/build/test/config-file-e2e-specs.js +209 -0
- package/build/test/config-file-specs.js +281 -0
- package/build/test/config-specs.js +159 -0
- package/build/test/driver-e2e-specs.js +435 -0
- package/build/test/driver-specs.js +321 -0
- package/build/test/ext-config-io-specs.js +181 -0
- package/build/test/extension-config-specs.js +365 -0
- package/build/test/fixtures/allow-feat.txt +5 -0
- package/build/test/fixtures/caps.json +3 -0
- package/build/test/fixtures/config/allow-insecure.txt +3 -0
- package/build/test/fixtures/config/appium.config.bad-nodeconfig.json +5 -0
- package/build/test/fixtures/config/appium.config.bad.json +32 -0
- package/build/test/fixtures/config/appium.config.ext-good.json +9 -0
- package/build/test/fixtures/config/appium.config.ext-unknown-props.json +10 -0
- package/build/test/fixtures/config/appium.config.good.js +40 -0
- package/build/test/fixtures/config/appium.config.good.json +33 -0
- package/build/test/fixtures/config/appium.config.good.yaml +30 -0
- package/build/test/fixtures/config/appium.config.invalid.json +31 -0
- package/build/test/fixtures/config/appium.config.security-array.json +5 -0
- package/build/test/fixtures/config/appium.config.security-delimited.json +5 -0
- package/build/test/fixtures/config/appium.config.security-path.json +5 -0
- package/build/test/fixtures/config/driver-fake.config.json +8 -0
- package/build/test/fixtures/config/nodeconfig.json +3 -0
- package/build/test/fixtures/config/plugin-fake.config.json +0 -0
- package/build/test/fixtures/default-args.js +35 -0
- package/build/test/fixtures/deny-feat.txt +5 -0
- package/build/test/fixtures/driver.schema.js +20 -0
- package/build/test/fixtures/extensions.yaml +27 -0
- package/build/test/fixtures/flattened-schema.js +504 -0
- package/build/test/fixtures/plugin.schema.js +20 -0
- package/build/test/fixtures/schema-with-extensions.js +28 -0
- package/build/test/grid-register-specs.js +74 -0
- package/build/test/helpers.js +75 -0
- package/build/test/logger-specs.js +76 -0
- package/build/test/npm-specs.js +20 -0
- package/build/test/parser-specs.js +314 -0
- package/build/test/plugin-e2e-specs.js +316 -0
- package/build/test/schema/arg-spec-specs.js +70 -0
- package/build/test/schema/cli-args-specs.js +431 -0
- package/build/test/schema/schema-specs.js +389 -0
- package/build/test/utils-specs.js +266 -0
- package/index.js +11 -0
- package/lib/appium-config.schema.json +278 -0
- package/lib/appium.js +207 -65
- package/lib/cli/args.js +174 -375
- package/lib/cli/driver-command.js +4 -0
- package/lib/cli/extension-command.js +70 -5
- package/lib/cli/extension.js +25 -5
- package/lib/cli/npm.js +86 -18
- package/lib/cli/parser.js +257 -79
- package/lib/cli/plugin-command.js +4 -0
- package/lib/cli/utils.js +21 -1
- package/lib/config-file.js +227 -0
- package/lib/config.js +84 -63
- package/lib/driver-config.js +66 -11
- package/lib/drivers.js +4 -1
- package/lib/ext-config-io.js +287 -0
- package/lib/extension-config.js +225 -67
- package/lib/grid-register.js +27 -24
- package/lib/logger.js +1 -1
- package/lib/logsink.js +10 -7
- package/lib/main.js +214 -77
- package/lib/plugin-config.js +35 -6
- package/lib/plugins.js +1 -0
- package/lib/schema/appium-config-schema.js +287 -0
- package/lib/schema/arg-spec.js +222 -0
- package/lib/schema/cli-args.js +285 -0
- package/lib/schema/cli-transformers.js +123 -0
- package/lib/schema/index.js +2 -0
- package/lib/schema/keywords.js +135 -0
- package/lib/schema/schema.js +577 -0
- package/lib/utils.js +42 -88
- package/package.json +55 -84
- package/postinstall.js +71 -0
- package/types/appium-config.d.ts +197 -0
- package/types/types.d.ts +201 -0
- package/CHANGELOG.md +0 -3515
- package/build/lib/cli/parser-helpers.js +0 -82
- package/lib/cli/parser-helpers.js +0 -79
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
|
|
7
|
-
import { server as baseServer, routeConfiguringFunction as makeRouter } from 'appium-base-driver';
|
|
6
|
+
// @ts-ignore
|
|
7
|
+
import { routeConfiguringFunction as makeRouter, server as baseServer } from '@appium/base-driver';
|
|
8
|
+
import { logger as logFactory, util } from '@appium/support';
|
|
8
9
|
import { asyncify } from 'asyncbox';
|
|
9
|
-
import
|
|
10
|
-
import { USE_ALL_PLUGINS } from './cli/args';
|
|
11
|
-
import { logger as logFactory, util } from 'appium-support';
|
|
12
|
-
import {
|
|
13
|
-
showConfig, checkNodeOk, validateServerArgs,
|
|
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';
|
|
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
|
}
|
|
@@ -89,14 +92,88 @@ function logServerPort (address, port) {
|
|
|
89
92
|
logger.info(logMessage);
|
|
90
93
|
}
|
|
91
94
|
|
|
92
|
-
|
|
93
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Find any plugin name which has been installed, and which has been requested for activation by
|
|
97
|
+
* using the --use-plugins flag, and turn each one into its class, so we can send them as objects
|
|
98
|
+
* to the server init. We also want to send/assign them to the umbrella driver so it can use them
|
|
99
|
+
* to wrap command execution
|
|
100
|
+
*
|
|
101
|
+
* @param {Object} args - argparser parsed dict
|
|
102
|
+
* @param {import('./plugin-config').default} pluginConfig - a plugin extension config
|
|
103
|
+
* @returns {({pluginName: string} & ((...args: any[]) => unknown))[]}
|
|
104
|
+
*/
|
|
105
|
+
function getActivePlugins (args, pluginConfig) {
|
|
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)
|
|
109
|
+
).map((pluginName) => {
|
|
110
|
+
try {
|
|
111
|
+
logger.info(`Attempting to load plugin ${pluginName}...`);
|
|
112
|
+
const PluginClass = /** @type {{pluginName: string} & ((...args: any[]) => unknown)} */(pluginConfig.require(pluginName));
|
|
113
|
+
|
|
114
|
+
PluginClass.pluginName = pluginName; // store the plugin name on the class so it can be used later
|
|
115
|
+
return PluginClass;
|
|
116
|
+
} catch (err) {
|
|
117
|
+
logger.error(`Could not load plugin '${pluginName}', so it will not be available. Error ` +
|
|
118
|
+
`in loading the plugin was: ${err.message}`);
|
|
119
|
+
logger.debug(err.stack);
|
|
120
|
+
}
|
|
121
|
+
}));
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Find any driver name which has been installed, and turn each one into its class, so we can send
|
|
126
|
+
* them as objects to the server init in case they need to add methods/routes or update the server.
|
|
127
|
+
* If the --drivers flag was given, this method only loads the given drivers.
|
|
128
|
+
*
|
|
129
|
+
* @param {Object} args - argparser parsed dict
|
|
130
|
+
* @param {import('./driver-config').default} driverConfig - a driver extension config
|
|
131
|
+
*/
|
|
132
|
+
function getActiveDrivers (args, driverConfig) {
|
|
133
|
+
return _.compact(Object.keys(driverConfig.installedExtensions).filter((driverName) =>
|
|
134
|
+
_.includes(args.useDrivers, driverName) || args.useDrivers.length === 0
|
|
135
|
+
).map((driverName) => {
|
|
136
|
+
try {
|
|
137
|
+
logger.info(`Attempting to load driver ${driverName}...`);
|
|
138
|
+
return driverConfig.require(driverName);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
logger.error(`Could not load driver '${driverName}', so it will not be available. Error ` +
|
|
141
|
+
`in loading the driver was: ${err.message}`);
|
|
142
|
+
logger.debug(err.stack);
|
|
143
|
+
}
|
|
144
|
+
}));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function getServerUpdaters (driverClasses, pluginClasses) {
|
|
148
|
+
return [...driverClasses, ...pluginClasses].map((klass) => klass.updateServer).filter(Boolean);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function getExtraMethodMap (driverClasses, pluginClasses) {
|
|
152
|
+
return [...driverClasses, ...pluginClasses].reduce(
|
|
153
|
+
(map, klass) => ({...map, ...klass.newMethodMap}),
|
|
154
|
+
{}
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
|
|
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();
|
|
94
173
|
let throwInsteadOfExit = false;
|
|
174
|
+
/** @type {ParsedArgs} */
|
|
175
|
+
let parsedArgs;
|
|
95
176
|
if (args) {
|
|
96
|
-
// a containing package passed in their own args, let's fill them out
|
|
97
|
-
// with defaults
|
|
98
|
-
args = Object.assign({}, getDefaultServerArgs(), args);
|
|
99
|
-
|
|
100
177
|
// if we have a containing package instead of running as a CLI process,
|
|
101
178
|
// that package might not appreciate us calling 'process.exit' willy-
|
|
102
179
|
// nilly, so give it the option to have us throw instead of exit
|
|
@@ -105,80 +182,129 @@ async function main (args = null) {
|
|
|
105
182
|
// but remove it since it's not a real server arg per se
|
|
106
183
|
delete args.throwInsteadOfExit;
|
|
107
184
|
}
|
|
185
|
+
parsedArgs = {...args, subcommand: args.subcommand ?? SERVER_SUBCOMMAND};
|
|
108
186
|
} else {
|
|
109
187
|
// otherwise parse from CLI
|
|
110
|
-
|
|
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
|
+
);
|
|
111
208
|
}
|
|
112
|
-
|
|
209
|
+
|
|
210
|
+
parsedArgs = _.defaultsDeep(
|
|
211
|
+
parsedArgs,
|
|
212
|
+
configResult.config ?? {},
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
await logsinkInit(parsedArgs);
|
|
113
216
|
|
|
114
217
|
// if the user has requested the 'driver' CLI, don't run the normal server,
|
|
115
218
|
// but instead pass control to the driver CLI
|
|
116
|
-
if (
|
|
117
|
-
await runExtensionCommand(
|
|
118
|
-
|
|
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};
|
|
119
226
|
}
|
|
120
227
|
|
|
121
|
-
if (
|
|
122
|
-
const {issues, rules} = await logFactory.loadSecureValuesPreprocessingRules(
|
|
228
|
+
if (parsedArgs.logFilters) {
|
|
229
|
+
const {issues, rules} = await logFactory.loadSecureValuesPreprocessingRules(parsedArgs.logFilters);
|
|
123
230
|
if (!_.isEmpty(issues)) {
|
|
124
|
-
throw new Error(`The log filtering rules config '${
|
|
231
|
+
throw new Error(`The log filtering rules config '${parsedArgs.logFilters}' has issues: ` +
|
|
125
232
|
JSON.stringify(issues, null, 2));
|
|
126
233
|
}
|
|
127
234
|
if (_.isEmpty(rules)) {
|
|
128
|
-
logger.warn(`Found no log filtering rules in '${
|
|
235
|
+
logger.warn(`Found no log filtering rules in '${parsedArgs.logFilters}'. Is that expected?`);
|
|
129
236
|
} else {
|
|
130
|
-
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}'`);
|
|
131
238
|
}
|
|
132
239
|
}
|
|
133
240
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
const pluginConfig = new PluginConfig(args.appiumHome);
|
|
241
|
+
const appiumDriver = new AppiumDriver(parsedArgs);
|
|
242
|
+
// set the config on the umbrella driver so it can match drivers to caps
|
|
137
243
|
appiumDriver.driverConfig = driverConfig;
|
|
138
|
-
await preflightChecks(
|
|
139
|
-
|
|
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);
|
|
264
|
+
// set the active plugins on the umbrella driver so it can use them for commands
|
|
265
|
+
appiumDriver.pluginClasses = pluginClasses;
|
|
266
|
+
|
|
267
|
+
await logStartupInfo(parser, parsedArgs);
|
|
140
268
|
let routeConfiguringFunction = makeRouter(appiumDriver);
|
|
141
269
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
// it can use them to wrap command execution
|
|
146
|
-
const plugins = Object.keys(pluginConfig.installedExtensions).filter((pluginName) =>
|
|
147
|
-
_.includes(args.plugins, pluginName) ||
|
|
148
|
-
(args.plugins.length === 1 && args.plugins[0] === USE_ALL_PLUGINS)
|
|
149
|
-
).map((pluginName) => {
|
|
150
|
-
try {
|
|
151
|
-
const PluginClass = pluginConfig.require(pluginName);
|
|
152
|
-
return new PluginClass(pluginName);
|
|
153
|
-
} catch (err) {
|
|
154
|
-
logger.error(`Could not load plugin '${pluginName}', so it will not be available. Error ` +
|
|
155
|
-
`in loading the plugin was: ${err}`);
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
}).filter(Boolean);
|
|
159
|
-
appiumDriver.plugins = plugins;
|
|
270
|
+
const driverClasses = getActiveDrivers(parsedArgs, driverConfig);
|
|
271
|
+
const serverUpdaters = getServerUpdaters(driverClasses, pluginClasses);
|
|
272
|
+
const extraMethodMap = getExtraMethodMap(driverClasses, pluginClasses);
|
|
160
273
|
|
|
161
|
-
|
|
274
|
+
const serverOpts = {
|
|
162
275
|
routeConfiguringFunction,
|
|
163
|
-
port:
|
|
164
|
-
hostname:
|
|
165
|
-
allowCors:
|
|
166
|
-
basePath:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
276
|
+
port: parsedArgs.port,
|
|
277
|
+
hostname: parsedArgs.address,
|
|
278
|
+
allowCors: parsedArgs.allowCors,
|
|
279
|
+
basePath: parsedArgs.basePath,
|
|
280
|
+
serverUpdaters,
|
|
281
|
+
extraMethodMap,
|
|
282
|
+
};
|
|
283
|
+
if (parsedArgs.keepAliveTimeout) {
|
|
284
|
+
serverOpts.keepAliveTimeout = parsedArgs.keepAliveTimeout * 1000;
|
|
285
|
+
}
|
|
286
|
+
let server;
|
|
287
|
+
try {
|
|
288
|
+
server = await baseServer(serverOpts);
|
|
289
|
+
} catch (err) {
|
|
290
|
+
logger.error(`Could not configure Appium server. It's possible that a driver or plugin tried ` +
|
|
291
|
+
`to update the server and failed. Original error: ${err.message}`);
|
|
292
|
+
logger.debug(err.stack);
|
|
293
|
+
return process.exit(1);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
if (parsedArgs.allowCors) {
|
|
170
297
|
logger.warn('You have enabled CORS requests from any host. Be careful not ' +
|
|
171
298
|
'to visit sites which could maliciously try to start Appium ' +
|
|
172
299
|
'sessions on your machine');
|
|
173
300
|
}
|
|
301
|
+
// @ts-ignore
|
|
174
302
|
appiumDriver.server = server;
|
|
175
303
|
try {
|
|
176
|
-
// TODO prelaunch if args.launch is set
|
|
177
|
-
// TODO: startAlertSocket(server, appiumServer);
|
|
178
|
-
|
|
179
304
|
// configure as node on grid, if necessary
|
|
180
|
-
|
|
181
|
-
|
|
305
|
+
// falsy values should not cause this to run
|
|
306
|
+
if (parsedArgs.nodeconfig) {
|
|
307
|
+
await registerNode(parsedArgs.nodeconfig, parsedArgs.address, parsedArgs.port, parsedArgs.basePath);
|
|
182
308
|
}
|
|
183
309
|
} catch (err) {
|
|
184
310
|
await server.close();
|
|
@@ -202,15 +328,26 @@ async function main (args = null) {
|
|
|
202
328
|
});
|
|
203
329
|
}
|
|
204
330
|
|
|
205
|
-
logServerPort(
|
|
331
|
+
logServerPort(parsedArgs.address, parsedArgs.port);
|
|
206
332
|
driverConfig.print();
|
|
207
|
-
pluginConfig.print(
|
|
333
|
+
pluginConfig.print(pluginClasses.map((p) => p.pluginName));
|
|
208
334
|
|
|
209
335
|
return server;
|
|
210
336
|
}
|
|
211
337
|
|
|
338
|
+
// NOTE: this is here for backwards compat for any scripts referencing `main.js` directly
|
|
339
|
+
// (more specifically, `build/lib/main.js`)
|
|
340
|
+
// the executable is now `../index.js`, so that module will typically be `require.main`.
|
|
212
341
|
if (require.main === module) {
|
|
213
342
|
asyncify(main);
|
|
214
343
|
}
|
|
215
344
|
|
|
216
|
-
|
|
345
|
+
// everything below here is intended to be a public API.
|
|
346
|
+
export { main, init };
|
|
347
|
+
export { APPIUM_HOME } from './extension-config';
|
|
348
|
+
export { getSchema, validate, finalizeSchema } from './schema/schema';
|
|
349
|
+
export { readConfigFile } from './config-file';
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* @typedef {import('../types/types').ParsedArgs} ParsedArgs
|
|
353
|
+
*/
|
package/lib/plugin-config.js
CHANGED
|
@@ -1,19 +1,48 @@
|
|
|
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
|
}
|
|
13
43
|
|
|
14
|
-
print (
|
|
44
|
+
print (activeNames) {
|
|
15
45
|
const pluginNames = Object.keys(this.installedExtensions);
|
|
16
|
-
const activeNames = activePlugins.map((p) => p.name);
|
|
17
46
|
|
|
18
47
|
if (_.isEmpty(pluginNames)) {
|
|
19
48
|
log.info(`No plugins have been installed. Use the "appium plugin" ` +
|
|
@@ -27,8 +56,8 @@ export default class PluginConfig extends ExtensionConfig {
|
|
|
27
56
|
log.info(` - ${this.extensionDesc(pluginName, pluginData)}${activeTxt}`);
|
|
28
57
|
}
|
|
29
58
|
|
|
30
|
-
if (_.isEmpty(
|
|
31
|
-
log.info('No plugins activated. Use the --plugins flag with names of plugins to activate');
|
|
59
|
+
if (_.isEmpty(activeNames)) {
|
|
60
|
+
log.info('No plugins activated. Use the --use-plugins flag with names of plugins to activate');
|
|
32
61
|
}
|
|
33
62
|
}
|
|
34
63
|
}
|