appium 3.3.0 → 3.3.1
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 +147 -205
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +169 -282
- package/build/lib/appium.js.map +1 -1
- package/build/lib/bidi-commands.d.ts.map +1 -1
- package/build/lib/bidi-commands.js +11 -11
- package/build/lib/bidi-commands.js.map +1 -1
- package/build/lib/bootstrap/appium-initializer.d.ts +21 -0
- package/build/lib/bootstrap/appium-initializer.d.ts.map +1 -0
- package/build/lib/bootstrap/appium-initializer.js +146 -0
- package/build/lib/bootstrap/appium-initializer.js.map +1 -0
- package/build/lib/bootstrap/appium-main-runner.d.ts +22 -0
- package/build/lib/bootstrap/appium-main-runner.d.ts.map +1 -0
- package/build/lib/bootstrap/appium-main-runner.js +109 -0
- package/build/lib/bootstrap/appium-main-runner.js.map +1 -0
- package/build/lib/bootstrap/config-file.d.ts +37 -0
- package/build/lib/bootstrap/config-file.d.ts.map +1 -0
- package/build/lib/{config-file.js → bootstrap/config-file.js} +9 -26
- package/build/lib/bootstrap/config-file.js.map +1 -0
- package/build/lib/bootstrap/grid-v3-register.d.ts +20 -0
- package/build/lib/bootstrap/grid-v3-register.d.ts.map +1 -0
- package/build/lib/{grid-register.js → bootstrap/grid-v3-register.js} +28 -13
- package/build/lib/bootstrap/grid-v3-register.js.map +1 -0
- package/build/lib/bootstrap/init-types.d.ts +16 -0
- package/build/lib/bootstrap/init-types.d.ts.map +1 -0
- package/build/lib/bootstrap/init-types.js +3 -0
- package/build/lib/bootstrap/init-types.js.map +1 -0
- package/build/lib/bootstrap/main-helpers.d.ts +55 -0
- package/build/lib/bootstrap/main-helpers.d.ts.map +1 -0
- package/build/lib/bootstrap/main-helpers.js +187 -0
- package/build/lib/bootstrap/main-helpers.js.map +1 -0
- package/build/lib/bootstrap/node-helpers.d.ts +32 -0
- package/build/lib/bootstrap/node-helpers.d.ts.map +1 -0
- package/build/lib/bootstrap/node-helpers.js +201 -0
- package/build/lib/bootstrap/node-helpers.js.map +1 -0
- package/build/lib/bootstrap/startup-config.d.ts +22 -0
- package/build/lib/bootstrap/startup-config.d.ts.map +1 -0
- package/build/lib/bootstrap/startup-config.js +111 -0
- package/build/lib/bootstrap/startup-config.js.map +1 -0
- package/build/lib/cli/args.d.ts.map +1 -1
- package/build/lib/cli/args.js +9 -9
- package/build/lib/cli/args.js.map +1 -1
- package/build/lib/cli/extension-command.d.ts +95 -95
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +18 -18
- package/build/lib/cli/extension-command.js.map +1 -1
- package/build/lib/cli/extension.d.ts +1 -1
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +5 -5
- package/build/lib/cli/extension.js.map +1 -1
- package/build/lib/cli/parser.d.ts +8 -8
- package/build/lib/cli/parser.d.ts.map +1 -1
- package/build/lib/cli/parser.js +49 -49
- package/build/lib/cli/parser.js.map +1 -1
- package/build/lib/cli/setup-command.js +6 -6
- package/build/lib/cli/setup-command.js.map +1 -1
- package/build/lib/cli/utils.d.ts +17 -17
- package/build/lib/cli/utils.d.ts.map +1 -1
- package/build/lib/cli/utils.js +29 -29
- package/build/lib/cli/utils.js.map +1 -1
- package/build/lib/doctor/doctor.d.ts +2 -2
- package/build/lib/doctor/doctor.d.ts.map +1 -1
- package/build/lib/doctor/doctor.js +6 -6
- package/build/lib/doctor/doctor.js.map +1 -1
- package/build/lib/extension/driver-config.d.ts +18 -77
- package/build/lib/extension/driver-config.d.ts.map +1 -1
- package/build/lib/extension/driver-config.js +37 -125
- package/build/lib/extension/driver-config.js.map +1 -1
- package/build/lib/extension/extension-config.d.ts +103 -210
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +180 -342
- package/build/lib/extension/extension-config.js.map +1 -1
- package/build/lib/extension/index.d.ts +12 -29
- package/build/lib/extension/index.d.ts.map +1 -1
- package/build/lib/extension/index.js +33 -75
- package/build/lib/extension/index.js.map +1 -1
- package/build/lib/extension/manifest-migrations.d.ts +3 -20
- package/build/lib/extension/manifest-migrations.d.ts.map +1 -1
- package/build/lib/extension/manifest-migrations.js +20 -101
- package/build/lib/extension/manifest-migrations.js.map +1 -1
- package/build/lib/extension/manifest.d.ts +61 -107
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +181 -356
- package/build/lib/extension/manifest.js.map +1 -1
- package/build/lib/extension/package-changed.d.ts +1 -3
- package/build/lib/extension/package-changed.d.ts.map +1 -1
- package/build/lib/extension/package-changed.js +8 -15
- package/build/lib/extension/package-changed.js.map +1 -1
- package/build/lib/extension/plugin-config.d.ts +10 -52
- package/build/lib/extension/plugin-config.d.ts.map +1 -1
- package/build/lib/extension/plugin-config.js +11 -63
- package/build/lib/extension/plugin-config.js.map +1 -1
- package/build/lib/helpers/build.d.ts +22 -0
- package/build/lib/helpers/build.d.ts.map +1 -0
- package/build/lib/helpers/build.js +109 -0
- package/build/lib/helpers/build.js.map +1 -0
- package/build/lib/helpers/capability.d.ts +38 -0
- package/build/lib/helpers/capability.d.ts.map +1 -0
- package/build/lib/helpers/capability.js +128 -0
- package/build/lib/helpers/capability.js.map +1 -0
- package/build/lib/helpers/network.d.ts +14 -0
- package/build/lib/helpers/network.d.ts.map +1 -0
- package/build/lib/helpers/network.js +35 -0
- package/build/lib/helpers/network.js.map +1 -0
- package/build/lib/insecure-features.js +6 -6
- package/build/lib/insecure-features.js.map +1 -1
- package/build/lib/inspector-commands.d.ts +6 -0
- package/build/lib/inspector-commands.d.ts.map +1 -1
- package/build/lib/inspector-commands.js +6 -0
- package/build/lib/inspector-commands.js.map +1 -1
- package/build/lib/logger.d.ts +2 -3
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +2 -3
- package/build/lib/logger.js.map +1 -1
- package/build/lib/main.d.ts +15 -58
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +25 -425
- package/build/lib/main.js.map +1 -1
- package/build/lib/schema/cli-args-guards.d.ts +34 -0
- package/build/lib/schema/cli-args-guards.d.ts.map +1 -0
- package/build/lib/schema/cli-args-guards.js +49 -0
- package/build/lib/schema/cli-args-guards.js.map +1 -0
- package/build/lib/schema/cli-args.js +2 -2
- package/build/lib/schema/cli-args.js.map +1 -1
- package/build/lib/schema/format-errors.d.ts +28 -0
- package/build/lib/schema/format-errors.d.ts.map +1 -0
- package/build/lib/schema/format-errors.js +29 -0
- package/build/lib/schema/format-errors.js.map +1 -0
- package/build/lib/schema/index.d.ts +2 -0
- package/build/lib/schema/index.d.ts.map +1 -1
- package/build/lib/schema/index.js +2 -0
- package/build/lib/schema/index.js.map +1 -1
- package/build/lib/schema/schema.d.ts +15 -15
- package/build/lib/schema/schema.d.ts.map +1 -1
- package/build/lib/schema/schema.js +37 -37
- package/build/lib/schema/schema.js.map +1 -1
- package/build/lib/utils.d.ts +0 -81
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +1 -248
- package/build/lib/utils.js.map +1 -1
- package/lib/{appium.js → appium.ts} +297 -341
- package/lib/bidi-commands.ts +10 -14
- package/lib/bootstrap/appium-initializer.ts +212 -0
- package/lib/bootstrap/appium-main-runner.ts +172 -0
- package/lib/{config-file.ts → bootstrap/config-file.ts} +29 -63
- package/lib/{grid-register.ts → bootstrap/grid-v3-register.ts} +35 -35
- package/lib/bootstrap/init-types.ts +31 -0
- package/lib/bootstrap/main-helpers.ts +223 -0
- package/lib/bootstrap/node-helpers.ts +180 -0
- package/lib/bootstrap/startup-config.ts +143 -0
- package/lib/cli/args.ts +10 -10
- package/lib/cli/extension-command.ts +132 -132
- package/lib/cli/extension.ts +7 -7
- package/lib/cli/parser.ts +50 -50
- package/lib/cli/setup-command.ts +2 -2
- package/lib/cli/utils.ts +33 -33
- package/lib/doctor/doctor.ts +8 -8
- package/lib/extension/driver-config.ts +165 -0
- package/lib/extension/{extension-config.js → extension-config.ts} +291 -405
- package/lib/extension/index.ts +143 -0
- package/lib/extension/manifest-migrations.ts +57 -0
- package/lib/extension/manifest.ts +369 -0
- package/lib/extension/{package-changed.js → package-changed.ts} +9 -18
- package/lib/extension/plugin-config.ts +62 -0
- package/lib/helpers/build.ts +111 -0
- package/lib/helpers/capability.ts +171 -0
- package/lib/helpers/network.ts +30 -0
- package/lib/insecure-features.ts +1 -1
- package/lib/inspector-commands.ts +6 -1
- package/lib/{logger.js → logger.ts} +1 -2
- package/lib/main.ts +60 -0
- package/lib/schema/cli-args-guards.ts +67 -0
- package/lib/schema/cli-args.ts +1 -1
- package/lib/schema/format-errors.ts +43 -0
- package/lib/schema/index.ts +2 -0
- package/lib/schema/schema.ts +51 -52
- package/lib/utils.ts +0 -331
- package/package.json +12 -13
- package/scripts/autoinstall-extensions.js +3 -0
- package/build/lib/config-file.d.ts +0 -57
- package/build/lib/config-file.d.ts.map +0 -1
- package/build/lib/config-file.js.map +0 -1
- package/build/lib/config.d.ts +0 -68
- package/build/lib/config.d.ts.map +0 -1
- package/build/lib/config.js +0 -358
- package/build/lib/config.js.map +0 -1
- package/build/lib/grid-register.d.ts +0 -35
- package/build/lib/grid-register.d.ts.map +0 -1
- package/build/lib/grid-register.js.map +0 -1
- package/lib/config.ts +0 -377
- package/lib/extension/driver-config.js +0 -245
- package/lib/extension/index.js +0 -169
- package/lib/extension/manifest-migrations.js +0 -136
- package/lib/extension/manifest.js +0 -550
- package/lib/extension/plugin-config.js +0 -112
- package/lib/main.js +0 -545
package/lib/main.js
DELETED
|
@@ -1,545 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import {WebSocketServer} from 'ws';
|
|
4
|
-
import {init as logsinkInit} from './logsink'; // this import needs to come first since it sets up global npmlog
|
|
5
|
-
import logger from './logger'; // logger needs to remain second
|
|
6
|
-
import {
|
|
7
|
-
routeConfiguringFunction as makeRouter,
|
|
8
|
-
server as baseServer,
|
|
9
|
-
normalizeBasePath,
|
|
10
|
-
} from '@appium/base-driver';
|
|
11
|
-
import {util, env} from '@appium/support';
|
|
12
|
-
import _ from 'lodash';
|
|
13
|
-
import {AppiumDriver} from './appium';
|
|
14
|
-
import {runExtensionCommand} from './cli/extension';
|
|
15
|
-
import { runSetupCommand } from './cli/setup-command';
|
|
16
|
-
import {getParser, ArgParser} from './cli/parser';
|
|
17
|
-
import {
|
|
18
|
-
APPIUM_VER,
|
|
19
|
-
checkNodeOk,
|
|
20
|
-
getGitRev,
|
|
21
|
-
getNonDefaultServerArgs,
|
|
22
|
-
showConfig,
|
|
23
|
-
showBuildInfo,
|
|
24
|
-
showDebugInfo,
|
|
25
|
-
requireDir,
|
|
26
|
-
} from './config';
|
|
27
|
-
import {readConfigFile} from './config-file';
|
|
28
|
-
import {loadExtensions, getActivePlugins, getActiveDrivers} from './extension';
|
|
29
|
-
import {SERVER_SUBCOMMAND, LONG_STACKTRACE_LIMIT, BIDI_BASE_PATH} from './constants';
|
|
30
|
-
import registerNode from './grid-register';
|
|
31
|
-
import {getDefaultsForSchema, validate as validateSchema} from './schema/schema';
|
|
32
|
-
import {
|
|
33
|
-
inspect,
|
|
34
|
-
adjustNodePath,
|
|
35
|
-
isDriverCommandArgs,
|
|
36
|
-
isExtensionCommandArgs,
|
|
37
|
-
isPluginCommandArgs,
|
|
38
|
-
isServerCommandArgs,
|
|
39
|
-
fetchInterfaces,
|
|
40
|
-
V4_BROADCAST_IP,
|
|
41
|
-
isSetupCommandArgs,
|
|
42
|
-
isBroadcastIp,
|
|
43
|
-
} from './utils';
|
|
44
|
-
import net from 'node:net';
|
|
45
|
-
import { injectAppiumSymlinks } from './cli/extension-command';
|
|
46
|
-
|
|
47
|
-
const {resolveAppiumHome} = env;
|
|
48
|
-
/*
|
|
49
|
-
* By default Node.js shows a warning
|
|
50
|
-
* if the actual amount of listeners exceeds the maximum amount,
|
|
51
|
-
* which equals to 10 by default. It is known that multiple drivers/plugins
|
|
52
|
-
* may assign custom listeners to the server process to handle, for example,
|
|
53
|
-
* the graceful shutdown scenario.
|
|
54
|
-
*/
|
|
55
|
-
const MAX_SERVER_PROCESS_LISTENERS = 100;
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
*
|
|
59
|
-
* @param {ParsedArgs} args
|
|
60
|
-
* @param {boolean} [throwInsteadOfExit]
|
|
61
|
-
*/
|
|
62
|
-
async function preflightChecks(args, throwInsteadOfExit = false) {
|
|
63
|
-
try {
|
|
64
|
-
checkNodeOk();
|
|
65
|
-
if (args.longStacktrace) {
|
|
66
|
-
Error.stackTraceLimit = LONG_STACKTRACE_LIMIT;
|
|
67
|
-
}
|
|
68
|
-
if (args.showBuildInfo) {
|
|
69
|
-
await showBuildInfo();
|
|
70
|
-
process.exit(0);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
validateSchema(args);
|
|
74
|
-
|
|
75
|
-
if (args.tmpDir) {
|
|
76
|
-
await requireDir(args.tmpDir, !args.noPermsCheck, 'tmpDir argument value');
|
|
77
|
-
}
|
|
78
|
-
} catch (err) {
|
|
79
|
-
logger.error(err.message.red);
|
|
80
|
-
if (throwInsteadOfExit) {
|
|
81
|
-
throw err;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
process.exit(1);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* @param {Args} args
|
|
90
|
-
*/
|
|
91
|
-
function logNonDefaultArgsWarning(args) {
|
|
92
|
-
logger.info('Non-default server args:');
|
|
93
|
-
inspect(args);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* @param {Args['defaultCapabilities']} caps
|
|
98
|
-
*/
|
|
99
|
-
function logDefaultCapabilitiesWarning(caps) {
|
|
100
|
-
logger.info(
|
|
101
|
-
'Default capabilities, which will be added to each request ' +
|
|
102
|
-
'unless overridden by desired capabilities:',
|
|
103
|
-
);
|
|
104
|
-
inspect(caps);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* @param {ParsedArgs} args
|
|
109
|
-
*/
|
|
110
|
-
async function logStartupInfo(args) {
|
|
111
|
-
let welcome = `Welcome to Appium v${APPIUM_VER}`;
|
|
112
|
-
let appiumRev = await getGitRev();
|
|
113
|
-
if (appiumRev) {
|
|
114
|
-
welcome += ` (REV ${appiumRev})`;
|
|
115
|
-
}
|
|
116
|
-
logger.info(welcome);
|
|
117
|
-
|
|
118
|
-
let showArgs = getNonDefaultServerArgs(args);
|
|
119
|
-
if (_.size(showArgs)) {
|
|
120
|
-
logNonDefaultArgsWarning(showArgs);
|
|
121
|
-
}
|
|
122
|
-
if (!_.isEmpty(args.defaultCapabilities)) {
|
|
123
|
-
logDefaultCapabilitiesWarning(args.defaultCapabilities);
|
|
124
|
-
}
|
|
125
|
-
// TODO: bring back loglevel reporting below once logger is flushed out
|
|
126
|
-
// logger.info('Console LogLevel: ' + logger.transports.console.level);
|
|
127
|
-
// if (logger.transports.file) {
|
|
128
|
-
// logger.info('File LogLevel: ' + logger.transports.file.level);
|
|
129
|
-
// }
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Gets a list of `updateServer` functions from all extensions
|
|
134
|
-
* @param {DriverNameMap} driverClasses
|
|
135
|
-
* @param {PluginNameMap} pluginClasses
|
|
136
|
-
* @returns {import('@appium/types').UpdateServerCallback[]}
|
|
137
|
-
*/
|
|
138
|
-
function getServerUpdaters(driverClasses, pluginClasses) {
|
|
139
|
-
return _.compact(_.map([...driverClasses.keys(), ...pluginClasses.keys()], 'updateServer'));
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Makes a big `MethodMap` from all the little `MethodMap`s in the extensions
|
|
144
|
-
* @param {DriverNameMap} driverClasses
|
|
145
|
-
* @param {PluginNameMap} pluginClasses
|
|
146
|
-
* @returns {import('@appium/types').MethodMap<import('@appium/types').Driver>}
|
|
147
|
-
*/
|
|
148
|
-
function getExtraMethodMap(driverClasses, pluginClasses) {
|
|
149
|
-
return [...driverClasses.keys(), ...pluginClasses.keys()].reduce(
|
|
150
|
-
(map, klass) => ({
|
|
151
|
-
...map,
|
|
152
|
-
...(klass.newMethodMap ?? {}),
|
|
153
|
-
}),
|
|
154
|
-
{},
|
|
155
|
-
);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/**
|
|
159
|
-
* @param {string?} [appiumHomeFromArgs] - Appium home value retrieved from progrmmatic server args
|
|
160
|
-
* @returns {string}
|
|
161
|
-
*/
|
|
162
|
-
function determineAppiumHomeSource(appiumHomeFromArgs) {
|
|
163
|
-
if (!_.isNil(appiumHomeFromArgs)) {
|
|
164
|
-
return 'appiumHome config value';
|
|
165
|
-
} else if (process.env.APPIUM_HOME) {
|
|
166
|
-
return 'APPIUM_HOME environment variable';
|
|
167
|
-
}
|
|
168
|
-
return 'autodetected Appium home path';
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Initializes Appium, but does not start the server.
|
|
173
|
-
*
|
|
174
|
-
* Use this to get at the configuration schema.
|
|
175
|
-
*
|
|
176
|
-
* If `args` contains a non-empty `subcommand` which is not `server`, this function will return an empty object.
|
|
177
|
-
*
|
|
178
|
-
* @template {CliCommand} [Cmd=ServerCommand]
|
|
179
|
-
* @template {CliExtensionSubcommand|void} [SubCmd=void]
|
|
180
|
-
* @param {Args<Cmd, SubCmd>} [args] - Partial args (programmatic usage only)
|
|
181
|
-
* @returns {Promise<InitResult<Cmd>>}
|
|
182
|
-
* @example
|
|
183
|
-
* import {init, getSchema} from 'appium';
|
|
184
|
-
* const options = {}; // config object
|
|
185
|
-
* await init(options);
|
|
186
|
-
* const schema = getSchema(); // entire config schema including plugins and drivers
|
|
187
|
-
*/
|
|
188
|
-
async function init(args) {
|
|
189
|
-
const appiumHome = args?.appiumHome ?? (await resolveAppiumHome());
|
|
190
|
-
const appiumHomeSourceName = determineAppiumHomeSource(args?.appiumHome);
|
|
191
|
-
// We verify the writeability later based on requested server arguments
|
|
192
|
-
// Here we just need to make sure the path exists and is a folder
|
|
193
|
-
await requireDir(appiumHome, false, appiumHomeSourceName);
|
|
194
|
-
|
|
195
|
-
adjustNodePath();
|
|
196
|
-
|
|
197
|
-
const {driverConfig, pluginConfig} = await loadExtensions(appiumHome);
|
|
198
|
-
|
|
199
|
-
const parser = getParser();
|
|
200
|
-
let throwInsteadOfExit = false;
|
|
201
|
-
/** @type {Args<Cmd, SubCmd>} */
|
|
202
|
-
let preConfigArgs;
|
|
203
|
-
|
|
204
|
-
if (args) {
|
|
205
|
-
// if we have a containing package instead of running as a CLI process,
|
|
206
|
-
// that package might not appreciate us calling 'process.exit' willy-
|
|
207
|
-
// nilly, so give it the option to have us throw instead of exit
|
|
208
|
-
if (args.throwInsteadOfExit) {
|
|
209
|
-
throwInsteadOfExit = true;
|
|
210
|
-
// but remove it since it's not a real server arg per se
|
|
211
|
-
delete args.throwInsteadOfExit;
|
|
212
|
-
}
|
|
213
|
-
preConfigArgs = {...args, subcommand: args.subcommand ?? SERVER_SUBCOMMAND};
|
|
214
|
-
// Normalize hyphenated keys to dest form so programmatic args match CLI shape
|
|
215
|
-
ArgParser.normalizeServerArgs(preConfigArgs);
|
|
216
|
-
} else {
|
|
217
|
-
// otherwise parse from CLI
|
|
218
|
-
preConfigArgs = /** @type {Args<Cmd, SubCmd>} */ (parser.parseArgs());
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const configResult = await readConfigFile(preConfigArgs.configFile);
|
|
222
|
-
|
|
223
|
-
if (!_.isEmpty(configResult.errors)) {
|
|
224
|
-
throw new Error(
|
|
225
|
-
`Errors in config file ${configResult.filepath}:\n ${
|
|
226
|
-
configResult.reason ?? configResult.errors
|
|
227
|
-
}`,
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// merge config and apply defaults.
|
|
232
|
-
// the order of precedence is:
|
|
233
|
-
// 1. command line args
|
|
234
|
-
// 2. config file
|
|
235
|
-
// 3. defaults from config file.
|
|
236
|
-
if (isServerCommandArgs(preConfigArgs)) {
|
|
237
|
-
const defaults = getDefaultsForSchema(false);
|
|
238
|
-
|
|
239
|
-
/** @type {ParsedArgs} */
|
|
240
|
-
const serverArgs = _.defaultsDeep({}, preConfigArgs, configResult.config?.server, defaults);
|
|
241
|
-
|
|
242
|
-
if (preConfigArgs.showConfig) {
|
|
243
|
-
showConfig(getNonDefaultServerArgs(preConfigArgs), configResult, defaults, serverArgs);
|
|
244
|
-
return /** @type {InitResult<Cmd>} */ ({});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
if (preConfigArgs.showDebugInfo) {
|
|
248
|
-
await showDebugInfo({
|
|
249
|
-
driverConfig,
|
|
250
|
-
pluginConfig,
|
|
251
|
-
appiumHome,
|
|
252
|
-
});
|
|
253
|
-
return /** @type {InitResult<Cmd>} */ ({});
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
await logsinkInit(serverArgs);
|
|
257
|
-
|
|
258
|
-
if (serverArgs.logFilters) {
|
|
259
|
-
const {issues, rules} = await logger.unwrap().loadSecureValuesPreprocessingRules(
|
|
260
|
-
serverArgs.logFilters,
|
|
261
|
-
);
|
|
262
|
-
const argToLog = _.truncate(JSON.stringify(serverArgs.logFilters), {
|
|
263
|
-
length: 150
|
|
264
|
-
});
|
|
265
|
-
if (!_.isEmpty(issues)) {
|
|
266
|
-
throw new Error(
|
|
267
|
-
`The log filtering rules config ${argToLog} has issues: ` +
|
|
268
|
-
JSON.stringify(issues, null, 2),
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
if (_.isEmpty(rules)) {
|
|
272
|
-
logger.warn(
|
|
273
|
-
`Found no log filtering rules in the ${argToLog} config. ` +
|
|
274
|
-
`Is that expected?`,
|
|
275
|
-
);
|
|
276
|
-
} else {
|
|
277
|
-
// Filtering aims to "hide" these values from the log,
|
|
278
|
-
// so it would be nice to not show them in the log as well.
|
|
279
|
-
logger.info(
|
|
280
|
-
`Loaded ${util.pluralize('filtering rule', rules.length, true)}`,
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
if (!serverArgs.noPermsCheck) {
|
|
286
|
-
await requireDir(appiumHome, true, appiumHomeSourceName);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
const appiumDriver = new AppiumDriver(
|
|
290
|
-
/** @type {import('@appium/types').DriverOpts<import('./appium').AppiumDriverConstraints>} */ (
|
|
291
|
-
serverArgs
|
|
292
|
-
),
|
|
293
|
-
);
|
|
294
|
-
// set the config on the umbrella driver so it can match drivers to caps
|
|
295
|
-
appiumDriver.driverConfig = driverConfig;
|
|
296
|
-
await preflightChecks(serverArgs, throwInsteadOfExit);
|
|
297
|
-
|
|
298
|
-
return /** @type {InitResult<Cmd>} */ ({
|
|
299
|
-
appiumDriver,
|
|
300
|
-
parsedArgs: serverArgs,
|
|
301
|
-
driverConfig,
|
|
302
|
-
pluginConfig,
|
|
303
|
-
appiumHome,
|
|
304
|
-
});
|
|
305
|
-
} else if (isSetupCommandArgs(preConfigArgs)) {
|
|
306
|
-
await runSetupCommand(preConfigArgs, driverConfig, pluginConfig);
|
|
307
|
-
return /** @type {InitResult<Cmd>} */ ({});
|
|
308
|
-
} else {
|
|
309
|
-
await requireDir(appiumHome, true, appiumHomeSourceName);
|
|
310
|
-
if (isExtensionCommandArgs(preConfigArgs)) {
|
|
311
|
-
// if the user has requested the 'driver' CLI, don't run the normal server,
|
|
312
|
-
// but instead pass control to the driver CLI
|
|
313
|
-
if (isDriverCommandArgs(preConfigArgs)) {
|
|
314
|
-
await runExtensionCommand(preConfigArgs, driverConfig);
|
|
315
|
-
}
|
|
316
|
-
if (isPluginCommandArgs(preConfigArgs)) {
|
|
317
|
-
await runExtensionCommand(preConfigArgs, pluginConfig);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
if (isDriverCommandArgs(preConfigArgs) || isPluginCommandArgs(preConfigArgs)) {
|
|
321
|
-
// @ts-ignore The linter suggest using dot
|
|
322
|
-
const cmd = preConfigArgs.driverCommand || preConfigArgs.pluginCommand;
|
|
323
|
-
if (cmd === 'install') {
|
|
324
|
-
await injectAppiumSymlinks(driverConfig, pluginConfig, logger);
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
return /** @type {InitResult<Cmd>} */ ({});
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Prints the actual server address and the list of URLs that
|
|
334
|
-
* could be used to connect to the current server.
|
|
335
|
-
* Properly replaces broadcast addresses in client URLs.
|
|
336
|
-
*
|
|
337
|
-
* @param {string} url The URL the server is listening on
|
|
338
|
-
*/
|
|
339
|
-
function logServerAddress(url) {
|
|
340
|
-
const urlObj = new URL(url);
|
|
341
|
-
logger.info(`Appium REST http interface listener started on ${url}`);
|
|
342
|
-
if (!isBroadcastIp(urlObj.hostname)) {
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
const interfaces = fetchInterfaces(urlObj.hostname === V4_BROADCAST_IP ? 4 : 6);
|
|
347
|
-
const toLabel = (/** @type {import('node:os').NetworkInterfaceInfo} */ iface) => {
|
|
348
|
-
const href = urlObj.href.replace(urlObj.hostname, iface.address);
|
|
349
|
-
return iface.internal ? `${href} (only accessible from the same host)` : href;
|
|
350
|
-
};
|
|
351
|
-
logger.info(
|
|
352
|
-
`You can provide the following ${interfaces.length === 1 ? 'URL' : 'URLs'} ` +
|
|
353
|
-
`in your client code to connect to this server:\n` +
|
|
354
|
-
interfaces.map((iface) => `\t${toLabel(iface)}`).join('\n'),
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* Initializes Appium's config. Starts server if appropriate and resolves the
|
|
360
|
-
* server instance if so; otherwise resolves w/ `undefined`.
|
|
361
|
-
* @template {CliCommand} [Cmd=ServerCommand]
|
|
362
|
-
* @template {CliExtensionSubcommand|void} [SubCmd=void]
|
|
363
|
-
* @param {Args<Cmd, SubCmd>} [args] - Arguments from CLI or otherwise
|
|
364
|
-
* @returns {Promise<Cmd extends ServerCommand ? import('@appium/types').AppiumServer : void>}
|
|
365
|
-
*/
|
|
366
|
-
async function main(args) {
|
|
367
|
-
const initResult = await init(args);
|
|
368
|
-
|
|
369
|
-
if (_.isEmpty(initResult)) {
|
|
370
|
-
// if this branch is taken, we've run a different subcommand, so there's nothing
|
|
371
|
-
// left to do here.
|
|
372
|
-
return /** @type {Cmd extends ServerCommand ? import('@appium/types').AppiumServer : void} */ (
|
|
373
|
-
undefined
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
const {appiumDriver, pluginConfig, driverConfig, parsedArgs, appiumHome} =
|
|
378
|
-
/** @type {InitResult<ServerCommand>} */ (initResult);
|
|
379
|
-
|
|
380
|
-
const pluginClasses = await getActivePlugins(
|
|
381
|
-
pluginConfig, parsedArgs.pluginsImportChunkSize, parsedArgs.usePlugins
|
|
382
|
-
);
|
|
383
|
-
// set the active plugins on the umbrella driver so it can use them for commands
|
|
384
|
-
appiumDriver.pluginClasses = pluginClasses;
|
|
385
|
-
|
|
386
|
-
await logStartupInfo(parsedArgs);
|
|
387
|
-
|
|
388
|
-
// handle the insecure feature configuration since some features may apply globally
|
|
389
|
-
appiumDriver.configureGlobalFeatures();
|
|
390
|
-
|
|
391
|
-
const appiumHomeSourceName = determineAppiumHomeSource(args?.appiumHome);
|
|
392
|
-
logger.debug(`The ${appiumHomeSourceName}: ${appiumHome}`);
|
|
393
|
-
|
|
394
|
-
let routeConfiguringFunction = makeRouter(appiumDriver);
|
|
395
|
-
|
|
396
|
-
const driverClasses = await getActiveDrivers(
|
|
397
|
-
driverConfig, parsedArgs.driversImportChunkSize, parsedArgs.useDrivers
|
|
398
|
-
);
|
|
399
|
-
const serverUpdaters = getServerUpdaters(driverClasses, pluginClasses);
|
|
400
|
-
const extraMethodMap = getExtraMethodMap(driverClasses, pluginClasses);
|
|
401
|
-
|
|
402
|
-
/** @type {import('@appium/base-driver').ServerOpts} */
|
|
403
|
-
const serverOpts = {
|
|
404
|
-
routeConfiguringFunction,
|
|
405
|
-
port: parsedArgs.port,
|
|
406
|
-
hostname: parsedArgs.address,
|
|
407
|
-
allowCors: parsedArgs.allowCors,
|
|
408
|
-
basePath: parsedArgs.basePath,
|
|
409
|
-
serverUpdaters,
|
|
410
|
-
extraMethodMap,
|
|
411
|
-
cliArgs: parsedArgs,
|
|
412
|
-
};
|
|
413
|
-
const normalizedBasePath = normalizeBasePath(parsedArgs.basePath);
|
|
414
|
-
for (const timeoutArgName of ['keepAliveTimeout', 'requestTimeout']) {
|
|
415
|
-
if (_.isInteger(parsedArgs[timeoutArgName])) {
|
|
416
|
-
serverOpts[timeoutArgName] = parsedArgs[timeoutArgName] * 1000;
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
let server;
|
|
420
|
-
const bidiServer = new WebSocketServer({noServer: true});
|
|
421
|
-
bidiServer.on('connection', appiumDriver.onBidiConnection.bind(appiumDriver));
|
|
422
|
-
bidiServer.on('error', appiumDriver.onBidiServerError.bind(appiumDriver));
|
|
423
|
-
try {
|
|
424
|
-
server = await baseServer(serverOpts);
|
|
425
|
-
const bidiBasePath = `${normalizedBasePath}${BIDI_BASE_PATH}`;
|
|
426
|
-
server.addWebSocketHandler(bidiBasePath, bidiServer);
|
|
427
|
-
server.addWebSocketHandler(`${bidiBasePath}/:sessionId`, bidiServer);
|
|
428
|
-
} catch (err) {
|
|
429
|
-
logger.error(
|
|
430
|
-
`Could not configure Appium server. It's possible that a driver or plugin tried ` +
|
|
431
|
-
`to update the server and failed. Original error: ${err.message}`,
|
|
432
|
-
);
|
|
433
|
-
logger.debug(err.stack);
|
|
434
|
-
return process.exit(1);
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
if (parsedArgs.allowCors) {
|
|
438
|
-
logger.warn(
|
|
439
|
-
'You have enabled CORS requests from any host. Be careful not ' +
|
|
440
|
-
'to visit sites which could maliciously try to start Appium ' +
|
|
441
|
-
'sessions on your machine',
|
|
442
|
-
);
|
|
443
|
-
}
|
|
444
|
-
appiumDriver.server = server;
|
|
445
|
-
try {
|
|
446
|
-
// configure as node on Selenium Grid 3 hub, if necessary
|
|
447
|
-
// falsy values should not cause this to run
|
|
448
|
-
if (parsedArgs.nodeconfig) {
|
|
449
|
-
await registerNode(
|
|
450
|
-
parsedArgs.nodeconfig,
|
|
451
|
-
parsedArgs.address,
|
|
452
|
-
parsedArgs.port,
|
|
453
|
-
normalizedBasePath,
|
|
454
|
-
);
|
|
455
|
-
}
|
|
456
|
-
} catch (err) {
|
|
457
|
-
await server.close();
|
|
458
|
-
throw err;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
process.setMaxListeners(MAX_SERVER_PROCESS_LISTENERS);
|
|
462
|
-
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
463
|
-
process.once(signal, async function onSignal() {
|
|
464
|
-
logger.info(`Received ${signal} - shutting down`);
|
|
465
|
-
try {
|
|
466
|
-
await appiumDriver.shutdown(`The process has received ${signal} signal`);
|
|
467
|
-
await server.close();
|
|
468
|
-
process.exit(0);
|
|
469
|
-
} catch (e) {
|
|
470
|
-
logger.warn(e);
|
|
471
|
-
process.exit(1);
|
|
472
|
-
}
|
|
473
|
-
});
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
const protocol = server.isSecure() ? 'https' : 'http';
|
|
477
|
-
const address = net.isIPv6(parsedArgs.address) ? `[${parsedArgs.address}]` : parsedArgs.address;
|
|
478
|
-
logServerAddress(
|
|
479
|
-
`${protocol}://${address}:${parsedArgs.port}${normalizedBasePath}`,
|
|
480
|
-
);
|
|
481
|
-
|
|
482
|
-
driverConfig.print();
|
|
483
|
-
pluginConfig.print([...pluginClasses.values()]);
|
|
484
|
-
|
|
485
|
-
return /** @type {Cmd extends ServerCommand ? import('@appium/types').AppiumServer : void} */ (
|
|
486
|
-
server
|
|
487
|
-
);
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
// NOTE: this is here for backwards compat for any scripts referencing `main.js` directly
|
|
491
|
-
// (more specifically, `build/lib/main.js`)
|
|
492
|
-
// the executable is now `../index.js`, so that module will typically be `require.main`.
|
|
493
|
-
if (require.main === module) {
|
|
494
|
-
main();
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
// everything below here is intended to be a public API.
|
|
498
|
-
export {readConfigFile} from './config-file';
|
|
499
|
-
export {finalizeSchema, getSchema, validate} from './schema/schema';
|
|
500
|
-
export {main, init, resolveAppiumHome};
|
|
501
|
-
|
|
502
|
-
/**
|
|
503
|
-
* @typedef {import('@appium/types').DriverType} DriverType
|
|
504
|
-
* @typedef {import('@appium/types').PluginType} PluginType
|
|
505
|
-
* @typedef {import('@appium/types').DriverClass} DriverClass
|
|
506
|
-
* @typedef {import('@appium/types').PluginClass} PluginClass
|
|
507
|
-
* @typedef {import('appium/types').CliCommand} CliCommand
|
|
508
|
-
* @typedef {import('appium/types').CliExtensionSubcommand} CliExtensionSubcommand
|
|
509
|
-
* @typedef {import('appium/types').CliExtensionCommand} CliExtensionCommand
|
|
510
|
-
* @typedef {import('appium/types').CliCommandServer} ServerCommand
|
|
511
|
-
* @typedef {import('appium/types').CliCommandDriver} DriverCommand
|
|
512
|
-
* @typedef {import('appium/types').CliCommandPlugin} PluginCommand
|
|
513
|
-
* @typedef {import('appium/types').CliCommandSetup} SetupCommand
|
|
514
|
-
* @typedef {import('./extension').DriverNameMap} DriverNameMap
|
|
515
|
-
* @typedef {import('./extension').PluginNameMap} PluginNameMap
|
|
516
|
-
*/
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* Literally an empty object
|
|
520
|
-
* @typedef { {} } ExtCommandInitResult
|
|
521
|
-
*/
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* @typedef ServerInitData
|
|
525
|
-
* @property {import('./appium').AppiumDriver} appiumDriver - The Appium driver
|
|
526
|
-
* @property {import('appium/types').ParsedArgs} parsedArgs - The parsed arguments
|
|
527
|
-
* @property {string} appiumHome - The full path to the Appium home folder
|
|
528
|
-
*/
|
|
529
|
-
|
|
530
|
-
/**
|
|
531
|
-
* @template {CliCommand} Cmd
|
|
532
|
-
* @typedef {Cmd extends ServerCommand ? ServerInitData & import('./extension').ExtensionConfigs : ExtCommandInitResult} InitResult
|
|
533
|
-
*/
|
|
534
|
-
|
|
535
|
-
/**
|
|
536
|
-
* @template {CliCommand} [Cmd=ServerCommand]
|
|
537
|
-
* @template {CliExtensionSubcommand|void} [SubCmd=void]
|
|
538
|
-
* @typedef {import('appium/types').Args<Cmd, SubCmd>} Args
|
|
539
|
-
*/
|
|
540
|
-
|
|
541
|
-
/**
|
|
542
|
-
* @template {CliCommand} [Cmd=ServerCommand]
|
|
543
|
-
* @template {CliExtensionSubcommand|void} [SubCmd=void]
|
|
544
|
-
* @typedef {import('appium/types').ParsedArgs<Cmd, SubCmd>} ParsedArgs
|
|
545
|
-
*/
|