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.
Files changed (196) hide show
  1. package/build/lib/appium.d.ts +147 -205
  2. package/build/lib/appium.d.ts.map +1 -1
  3. package/build/lib/appium.js +169 -282
  4. package/build/lib/appium.js.map +1 -1
  5. package/build/lib/bidi-commands.d.ts.map +1 -1
  6. package/build/lib/bidi-commands.js +11 -11
  7. package/build/lib/bidi-commands.js.map +1 -1
  8. package/build/lib/bootstrap/appium-initializer.d.ts +21 -0
  9. package/build/lib/bootstrap/appium-initializer.d.ts.map +1 -0
  10. package/build/lib/bootstrap/appium-initializer.js +146 -0
  11. package/build/lib/bootstrap/appium-initializer.js.map +1 -0
  12. package/build/lib/bootstrap/appium-main-runner.d.ts +22 -0
  13. package/build/lib/bootstrap/appium-main-runner.d.ts.map +1 -0
  14. package/build/lib/bootstrap/appium-main-runner.js +109 -0
  15. package/build/lib/bootstrap/appium-main-runner.js.map +1 -0
  16. package/build/lib/bootstrap/config-file.d.ts +37 -0
  17. package/build/lib/bootstrap/config-file.d.ts.map +1 -0
  18. package/build/lib/{config-file.js → bootstrap/config-file.js} +9 -26
  19. package/build/lib/bootstrap/config-file.js.map +1 -0
  20. package/build/lib/bootstrap/grid-v3-register.d.ts +20 -0
  21. package/build/lib/bootstrap/grid-v3-register.d.ts.map +1 -0
  22. package/build/lib/{grid-register.js → bootstrap/grid-v3-register.js} +28 -13
  23. package/build/lib/bootstrap/grid-v3-register.js.map +1 -0
  24. package/build/lib/bootstrap/init-types.d.ts +16 -0
  25. package/build/lib/bootstrap/init-types.d.ts.map +1 -0
  26. package/build/lib/bootstrap/init-types.js +3 -0
  27. package/build/lib/bootstrap/init-types.js.map +1 -0
  28. package/build/lib/bootstrap/main-helpers.d.ts +55 -0
  29. package/build/lib/bootstrap/main-helpers.d.ts.map +1 -0
  30. package/build/lib/bootstrap/main-helpers.js +187 -0
  31. package/build/lib/bootstrap/main-helpers.js.map +1 -0
  32. package/build/lib/bootstrap/node-helpers.d.ts +32 -0
  33. package/build/lib/bootstrap/node-helpers.d.ts.map +1 -0
  34. package/build/lib/bootstrap/node-helpers.js +201 -0
  35. package/build/lib/bootstrap/node-helpers.js.map +1 -0
  36. package/build/lib/bootstrap/startup-config.d.ts +22 -0
  37. package/build/lib/bootstrap/startup-config.d.ts.map +1 -0
  38. package/build/lib/bootstrap/startup-config.js +111 -0
  39. package/build/lib/bootstrap/startup-config.js.map +1 -0
  40. package/build/lib/cli/args.d.ts.map +1 -1
  41. package/build/lib/cli/args.js +9 -9
  42. package/build/lib/cli/args.js.map +1 -1
  43. package/build/lib/cli/extension-command.d.ts +95 -95
  44. package/build/lib/cli/extension-command.d.ts.map +1 -1
  45. package/build/lib/cli/extension-command.js +18 -18
  46. package/build/lib/cli/extension-command.js.map +1 -1
  47. package/build/lib/cli/extension.d.ts +1 -1
  48. package/build/lib/cli/extension.d.ts.map +1 -1
  49. package/build/lib/cli/extension.js +5 -5
  50. package/build/lib/cli/extension.js.map +1 -1
  51. package/build/lib/cli/parser.d.ts +8 -8
  52. package/build/lib/cli/parser.d.ts.map +1 -1
  53. package/build/lib/cli/parser.js +49 -49
  54. package/build/lib/cli/parser.js.map +1 -1
  55. package/build/lib/cli/setup-command.js +6 -6
  56. package/build/lib/cli/setup-command.js.map +1 -1
  57. package/build/lib/cli/utils.d.ts +17 -17
  58. package/build/lib/cli/utils.d.ts.map +1 -1
  59. package/build/lib/cli/utils.js +29 -29
  60. package/build/lib/cli/utils.js.map +1 -1
  61. package/build/lib/doctor/doctor.d.ts +2 -2
  62. package/build/lib/doctor/doctor.d.ts.map +1 -1
  63. package/build/lib/doctor/doctor.js +6 -6
  64. package/build/lib/doctor/doctor.js.map +1 -1
  65. package/build/lib/extension/driver-config.d.ts +18 -77
  66. package/build/lib/extension/driver-config.d.ts.map +1 -1
  67. package/build/lib/extension/driver-config.js +37 -125
  68. package/build/lib/extension/driver-config.js.map +1 -1
  69. package/build/lib/extension/extension-config.d.ts +103 -210
  70. package/build/lib/extension/extension-config.d.ts.map +1 -1
  71. package/build/lib/extension/extension-config.js +180 -342
  72. package/build/lib/extension/extension-config.js.map +1 -1
  73. package/build/lib/extension/index.d.ts +12 -29
  74. package/build/lib/extension/index.d.ts.map +1 -1
  75. package/build/lib/extension/index.js +33 -75
  76. package/build/lib/extension/index.js.map +1 -1
  77. package/build/lib/extension/manifest-migrations.d.ts +3 -20
  78. package/build/lib/extension/manifest-migrations.d.ts.map +1 -1
  79. package/build/lib/extension/manifest-migrations.js +20 -101
  80. package/build/lib/extension/manifest-migrations.js.map +1 -1
  81. package/build/lib/extension/manifest.d.ts +61 -107
  82. package/build/lib/extension/manifest.d.ts.map +1 -1
  83. package/build/lib/extension/manifest.js +181 -356
  84. package/build/lib/extension/manifest.js.map +1 -1
  85. package/build/lib/extension/package-changed.d.ts +1 -3
  86. package/build/lib/extension/package-changed.d.ts.map +1 -1
  87. package/build/lib/extension/package-changed.js +8 -15
  88. package/build/lib/extension/package-changed.js.map +1 -1
  89. package/build/lib/extension/plugin-config.d.ts +10 -52
  90. package/build/lib/extension/plugin-config.d.ts.map +1 -1
  91. package/build/lib/extension/plugin-config.js +11 -63
  92. package/build/lib/extension/plugin-config.js.map +1 -1
  93. package/build/lib/helpers/build.d.ts +22 -0
  94. package/build/lib/helpers/build.d.ts.map +1 -0
  95. package/build/lib/helpers/build.js +109 -0
  96. package/build/lib/helpers/build.js.map +1 -0
  97. package/build/lib/helpers/capability.d.ts +38 -0
  98. package/build/lib/helpers/capability.d.ts.map +1 -0
  99. package/build/lib/helpers/capability.js +128 -0
  100. package/build/lib/helpers/capability.js.map +1 -0
  101. package/build/lib/helpers/network.d.ts +14 -0
  102. package/build/lib/helpers/network.d.ts.map +1 -0
  103. package/build/lib/helpers/network.js +35 -0
  104. package/build/lib/helpers/network.js.map +1 -0
  105. package/build/lib/insecure-features.js +6 -6
  106. package/build/lib/insecure-features.js.map +1 -1
  107. package/build/lib/inspector-commands.d.ts +6 -0
  108. package/build/lib/inspector-commands.d.ts.map +1 -1
  109. package/build/lib/inspector-commands.js +6 -0
  110. package/build/lib/inspector-commands.js.map +1 -1
  111. package/build/lib/logger.d.ts +2 -3
  112. package/build/lib/logger.d.ts.map +1 -1
  113. package/build/lib/logger.js +2 -3
  114. package/build/lib/logger.js.map +1 -1
  115. package/build/lib/main.d.ts +15 -58
  116. package/build/lib/main.d.ts.map +1 -1
  117. package/build/lib/main.js +25 -425
  118. package/build/lib/main.js.map +1 -1
  119. package/build/lib/schema/cli-args-guards.d.ts +34 -0
  120. package/build/lib/schema/cli-args-guards.d.ts.map +1 -0
  121. package/build/lib/schema/cli-args-guards.js +49 -0
  122. package/build/lib/schema/cli-args-guards.js.map +1 -0
  123. package/build/lib/schema/cli-args.js +2 -2
  124. package/build/lib/schema/cli-args.js.map +1 -1
  125. package/build/lib/schema/format-errors.d.ts +28 -0
  126. package/build/lib/schema/format-errors.d.ts.map +1 -0
  127. package/build/lib/schema/format-errors.js +29 -0
  128. package/build/lib/schema/format-errors.js.map +1 -0
  129. package/build/lib/schema/index.d.ts +2 -0
  130. package/build/lib/schema/index.d.ts.map +1 -1
  131. package/build/lib/schema/index.js +2 -0
  132. package/build/lib/schema/index.js.map +1 -1
  133. package/build/lib/schema/schema.d.ts +15 -15
  134. package/build/lib/schema/schema.d.ts.map +1 -1
  135. package/build/lib/schema/schema.js +37 -37
  136. package/build/lib/schema/schema.js.map +1 -1
  137. package/build/lib/utils.d.ts +0 -81
  138. package/build/lib/utils.d.ts.map +1 -1
  139. package/build/lib/utils.js +1 -248
  140. package/build/lib/utils.js.map +1 -1
  141. package/lib/{appium.js → appium.ts} +297 -341
  142. package/lib/bidi-commands.ts +10 -14
  143. package/lib/bootstrap/appium-initializer.ts +212 -0
  144. package/lib/bootstrap/appium-main-runner.ts +172 -0
  145. package/lib/{config-file.ts → bootstrap/config-file.ts} +29 -63
  146. package/lib/{grid-register.ts → bootstrap/grid-v3-register.ts} +35 -35
  147. package/lib/bootstrap/init-types.ts +31 -0
  148. package/lib/bootstrap/main-helpers.ts +223 -0
  149. package/lib/bootstrap/node-helpers.ts +180 -0
  150. package/lib/bootstrap/startup-config.ts +143 -0
  151. package/lib/cli/args.ts +10 -10
  152. package/lib/cli/extension-command.ts +132 -132
  153. package/lib/cli/extension.ts +7 -7
  154. package/lib/cli/parser.ts +50 -50
  155. package/lib/cli/setup-command.ts +2 -2
  156. package/lib/cli/utils.ts +33 -33
  157. package/lib/doctor/doctor.ts +8 -8
  158. package/lib/extension/driver-config.ts +165 -0
  159. package/lib/extension/{extension-config.js → extension-config.ts} +291 -405
  160. package/lib/extension/index.ts +143 -0
  161. package/lib/extension/manifest-migrations.ts +57 -0
  162. package/lib/extension/manifest.ts +369 -0
  163. package/lib/extension/{package-changed.js → package-changed.ts} +9 -18
  164. package/lib/extension/plugin-config.ts +62 -0
  165. package/lib/helpers/build.ts +111 -0
  166. package/lib/helpers/capability.ts +171 -0
  167. package/lib/helpers/network.ts +30 -0
  168. package/lib/insecure-features.ts +1 -1
  169. package/lib/inspector-commands.ts +6 -1
  170. package/lib/{logger.js → logger.ts} +1 -2
  171. package/lib/main.ts +60 -0
  172. package/lib/schema/cli-args-guards.ts +67 -0
  173. package/lib/schema/cli-args.ts +1 -1
  174. package/lib/schema/format-errors.ts +43 -0
  175. package/lib/schema/index.ts +2 -0
  176. package/lib/schema/schema.ts +51 -52
  177. package/lib/utils.ts +0 -331
  178. package/package.json +12 -13
  179. package/scripts/autoinstall-extensions.js +3 -0
  180. package/build/lib/config-file.d.ts +0 -57
  181. package/build/lib/config-file.d.ts.map +0 -1
  182. package/build/lib/config-file.js.map +0 -1
  183. package/build/lib/config.d.ts +0 -68
  184. package/build/lib/config.d.ts.map +0 -1
  185. package/build/lib/config.js +0 -358
  186. package/build/lib/config.js.map +0 -1
  187. package/build/lib/grid-register.d.ts +0 -35
  188. package/build/lib/grid-register.d.ts.map +0 -1
  189. package/build/lib/grid-register.js.map +0 -1
  190. package/lib/config.ts +0 -377
  191. package/lib/extension/driver-config.js +0 -245
  192. package/lib/extension/index.js +0 -169
  193. package/lib/extension/manifest-migrations.js +0 -136
  194. package/lib/extension/manifest.js +0 -550
  195. package/lib/extension/plugin-config.js +0 -112
  196. 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
- */