appium 3.2.2 → 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 (250) 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} +62 -138
  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/bootstrap/grid-v3-register.js +185 -0
  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 +16 -12
  41. package/build/lib/cli/args.d.ts.map +1 -1
  42. package/build/lib/cli/args.js +20 -40
  43. package/build/lib/cli/args.js.map +1 -1
  44. package/build/lib/cli/driver-command.d.ts +51 -93
  45. package/build/lib/cli/driver-command.d.ts.map +1 -1
  46. package/build/lib/cli/driver-command.js +11 -66
  47. package/build/lib/cli/driver-command.js.map +1 -1
  48. package/build/lib/cli/extension-command.d.ts +173 -377
  49. package/build/lib/cli/extension-command.d.ts.map +1 -1
  50. package/build/lib/cli/extension-command.js +387 -656
  51. package/build/lib/cli/extension-command.js.map +1 -1
  52. package/build/lib/cli/extension.d.ts +10 -15
  53. package/build/lib/cli/extension.d.ts.map +1 -1
  54. package/build/lib/cli/extension.js +15 -33
  55. package/build/lib/cli/extension.js.map +1 -1
  56. package/build/lib/cli/parser.d.ts +37 -66
  57. package/build/lib/cli/parser.d.ts.map +1 -1
  58. package/build/lib/cli/parser.js +69 -104
  59. package/build/lib/cli/parser.js.map +1 -1
  60. package/build/lib/cli/plugin-command.d.ts +50 -90
  61. package/build/lib/cli/plugin-command.d.ts.map +1 -1
  62. package/build/lib/cli/plugin-command.js +11 -63
  63. package/build/lib/cli/plugin-command.js.map +1 -1
  64. package/build/lib/cli/setup-command.d.ts +21 -26
  65. package/build/lib/cli/setup-command.d.ts.map +1 -1
  66. package/build/lib/cli/setup-command.js +19 -61
  67. package/build/lib/cli/setup-command.js.map +1 -1
  68. package/build/lib/cli/utils.d.ts +33 -35
  69. package/build/lib/cli/utils.d.ts.map +1 -1
  70. package/build/lib/cli/utils.js +48 -50
  71. package/build/lib/cli/utils.js.map +1 -1
  72. package/build/lib/constants.d.ts +23 -23
  73. package/build/lib/constants.d.ts.map +1 -1
  74. package/build/lib/constants.js +10 -15
  75. package/build/lib/constants.js.map +1 -1
  76. package/build/lib/doctor/doctor.d.ts +40 -57
  77. package/build/lib/doctor/doctor.d.ts.map +1 -1
  78. package/build/lib/doctor/doctor.js +31 -62
  79. package/build/lib/doctor/doctor.js.map +1 -1
  80. package/build/lib/extension/driver-config.d.ts +18 -77
  81. package/build/lib/extension/driver-config.d.ts.map +1 -1
  82. package/build/lib/extension/driver-config.js +37 -125
  83. package/build/lib/extension/driver-config.js.map +1 -1
  84. package/build/lib/extension/extension-config.d.ts +103 -210
  85. package/build/lib/extension/extension-config.d.ts.map +1 -1
  86. package/build/lib/extension/extension-config.js +180 -342
  87. package/build/lib/extension/extension-config.js.map +1 -1
  88. package/build/lib/extension/index.d.ts +12 -29
  89. package/build/lib/extension/index.d.ts.map +1 -1
  90. package/build/lib/extension/index.js +33 -75
  91. package/build/lib/extension/index.js.map +1 -1
  92. package/build/lib/extension/manifest-migrations.d.ts +3 -20
  93. package/build/lib/extension/manifest-migrations.d.ts.map +1 -1
  94. package/build/lib/extension/manifest-migrations.js +20 -101
  95. package/build/lib/extension/manifest-migrations.js.map +1 -1
  96. package/build/lib/extension/manifest.d.ts +61 -107
  97. package/build/lib/extension/manifest.d.ts.map +1 -1
  98. package/build/lib/extension/manifest.js +181 -356
  99. package/build/lib/extension/manifest.js.map +1 -1
  100. package/build/lib/extension/package-changed.d.ts +1 -3
  101. package/build/lib/extension/package-changed.d.ts.map +1 -1
  102. package/build/lib/extension/package-changed.js +8 -15
  103. package/build/lib/extension/package-changed.js.map +1 -1
  104. package/build/lib/extension/plugin-config.d.ts +10 -52
  105. package/build/lib/extension/plugin-config.d.ts.map +1 -1
  106. package/build/lib/extension/plugin-config.js +11 -63
  107. package/build/lib/extension/plugin-config.js.map +1 -1
  108. package/build/lib/helpers/build.d.ts +22 -0
  109. package/build/lib/helpers/build.d.ts.map +1 -0
  110. package/build/lib/helpers/build.js +109 -0
  111. package/build/lib/helpers/build.js.map +1 -0
  112. package/build/lib/helpers/capability.d.ts +38 -0
  113. package/build/lib/helpers/capability.d.ts.map +1 -0
  114. package/build/lib/helpers/capability.js +128 -0
  115. package/build/lib/helpers/capability.js.map +1 -0
  116. package/build/lib/helpers/network.d.ts +14 -0
  117. package/build/lib/helpers/network.d.ts.map +1 -0
  118. package/build/lib/helpers/network.js +35 -0
  119. package/build/lib/helpers/network.js.map +1 -0
  120. package/build/lib/insecure-features.js +6 -6
  121. package/build/lib/insecure-features.js.map +1 -1
  122. package/build/lib/inspector-commands.d.ts +6 -0
  123. package/build/lib/inspector-commands.d.ts.map +1 -1
  124. package/build/lib/inspector-commands.js +6 -0
  125. package/build/lib/inspector-commands.js.map +1 -1
  126. package/build/lib/logger.d.ts +2 -3
  127. package/build/lib/logger.d.ts.map +1 -1
  128. package/build/lib/logger.js +2 -3
  129. package/build/lib/logger.js.map +1 -1
  130. package/build/lib/logsink.d.ts +13 -22
  131. package/build/lib/logsink.d.ts.map +1 -1
  132. package/build/lib/logsink.js +48 -103
  133. package/build/lib/logsink.js.map +1 -1
  134. package/build/lib/main.d.ts +15 -58
  135. package/build/lib/main.d.ts.map +1 -1
  136. package/build/lib/main.js +25 -425
  137. package/build/lib/main.js.map +1 -1
  138. package/build/lib/schema/arg-spec.d.ts +32 -107
  139. package/build/lib/schema/arg-spec.d.ts.map +1 -1
  140. package/build/lib/schema/arg-spec.js +11 -107
  141. package/build/lib/schema/arg-spec.js.map +1 -1
  142. package/build/lib/schema/cli-args-guards.d.ts +34 -0
  143. package/build/lib/schema/cli-args-guards.d.ts.map +1 -0
  144. package/build/lib/schema/cli-args-guards.js +49 -0
  145. package/build/lib/schema/cli-args-guards.js.map +1 -0
  146. package/build/lib/schema/cli-args.d.ts +3 -15
  147. package/build/lib/schema/cli-args.d.ts.map +1 -1
  148. package/build/lib/schema/cli-args.js +17 -107
  149. package/build/lib/schema/cli-args.js.map +1 -1
  150. package/build/lib/schema/cli-transformers.d.ts +15 -12
  151. package/build/lib/schema/cli-transformers.d.ts.map +1 -1
  152. package/build/lib/schema/cli-transformers.js +15 -45
  153. package/build/lib/schema/cli-transformers.js.map +1 -1
  154. package/build/lib/schema/format-errors.d.ts +28 -0
  155. package/build/lib/schema/format-errors.d.ts.map +1 -0
  156. package/build/lib/schema/format-errors.js +29 -0
  157. package/build/lib/schema/format-errors.js.map +1 -0
  158. package/build/lib/schema/index.d.ts +4 -2
  159. package/build/lib/schema/index.d.ts.map +1 -1
  160. package/build/lib/schema/index.js +2 -0
  161. package/build/lib/schema/index.js.map +1 -1
  162. package/build/lib/schema/keywords.d.ts +12 -20
  163. package/build/lib/schema/keywords.d.ts.map +1 -1
  164. package/build/lib/schema/keywords.js +6 -51
  165. package/build/lib/schema/keywords.js.map +1 -1
  166. package/build/lib/schema/schema.d.ts +106 -231
  167. package/build/lib/schema/schema.d.ts.map +1 -1
  168. package/build/lib/schema/schema.js +88 -358
  169. package/build/lib/schema/schema.js.map +1 -1
  170. package/build/lib/utils.d.ts +7 -267
  171. package/build/lib/utils.d.ts.map +1 -1
  172. package/build/lib/utils.js +10 -409
  173. package/build/lib/utils.js.map +1 -1
  174. package/lib/{appium.js → appium.ts} +297 -341
  175. package/lib/bidi-commands.ts +10 -14
  176. package/lib/bootstrap/appium-initializer.ts +212 -0
  177. package/lib/bootstrap/appium-main-runner.ts +172 -0
  178. package/lib/bootstrap/config-file.ts +178 -0
  179. package/lib/bootstrap/grid-v3-register.ts +250 -0
  180. package/lib/bootstrap/init-types.ts +31 -0
  181. package/lib/bootstrap/main-helpers.ts +223 -0
  182. package/lib/bootstrap/node-helpers.ts +180 -0
  183. package/lib/bootstrap/startup-config.ts +143 -0
  184. package/lib/cli/{args.js → args.ts} +45 -56
  185. package/lib/cli/driver-command.ts +122 -0
  186. package/lib/cli/{extension-command.js → extension-command.ts} +827 -906
  187. package/lib/cli/extension.ts +65 -0
  188. package/lib/cli/{parser.js → parser.ts} +93 -116
  189. package/lib/cli/plugin-command.ts +117 -0
  190. package/lib/cli/{setup-command.js → setup-command.ts} +59 -74
  191. package/lib/cli/utils.ts +97 -0
  192. package/lib/{constants.js → constants.ts} +30 -41
  193. package/lib/doctor/{doctor.js → doctor.ts} +82 -92
  194. package/lib/extension/driver-config.ts +165 -0
  195. package/lib/extension/{extension-config.js → extension-config.ts} +291 -405
  196. package/lib/extension/index.ts +143 -0
  197. package/lib/extension/manifest-migrations.ts +57 -0
  198. package/lib/extension/manifest.ts +369 -0
  199. package/lib/extension/{package-changed.js → package-changed.ts} +9 -18
  200. package/lib/extension/plugin-config.ts +62 -0
  201. package/lib/helpers/build.ts +111 -0
  202. package/lib/helpers/capability.ts +171 -0
  203. package/lib/helpers/network.ts +30 -0
  204. package/lib/insecure-features.ts +1 -1
  205. package/lib/inspector-commands.ts +6 -1
  206. package/lib/{logger.js → logger.ts} +1 -2
  207. package/lib/{logsink.js → logsink.ts} +91 -137
  208. package/lib/main.ts +60 -0
  209. package/lib/schema/arg-spec.ts +131 -0
  210. package/lib/schema/cli-args-guards.ts +67 -0
  211. package/lib/schema/cli-args.ts +171 -0
  212. package/lib/schema/cli-transformers.ts +83 -0
  213. package/lib/schema/format-errors.ts +43 -0
  214. package/lib/schema/index.ts +4 -0
  215. package/lib/schema/keywords.ts +96 -0
  216. package/lib/schema/schema.ts +448 -0
  217. package/lib/utils.ts +73 -0
  218. package/package.json +17 -18
  219. package/scripts/autoinstall-extensions.js +3 -0
  220. package/build/lib/config-file.d.ts +0 -100
  221. package/build/lib/config-file.d.ts.map +0 -1
  222. package/build/lib/config-file.js.map +0 -1
  223. package/build/lib/config.d.ts +0 -70
  224. package/build/lib/config.d.ts.map +0 -1
  225. package/build/lib/config.js +0 -390
  226. package/build/lib/config.js.map +0 -1
  227. package/build/lib/grid-register.d.ts +0 -10
  228. package/build/lib/grid-register.d.ts.map +0 -1
  229. package/build/lib/grid-register.js +0 -134
  230. package/build/lib/grid-register.js.map +0 -1
  231. package/lib/cli/driver-command.js +0 -174
  232. package/lib/cli/extension.js +0 -74
  233. package/lib/cli/plugin-command.js +0 -164
  234. package/lib/cli/utils.js +0 -91
  235. package/lib/config-file.js +0 -228
  236. package/lib/config.js +0 -389
  237. package/lib/extension/driver-config.js +0 -245
  238. package/lib/extension/index.js +0 -169
  239. package/lib/extension/manifest-migrations.js +0 -136
  240. package/lib/extension/manifest.js +0 -550
  241. package/lib/extension/plugin-config.js +0 -112
  242. package/lib/grid-register.js +0 -146
  243. package/lib/main.js +0 -545
  244. package/lib/schema/arg-spec.js +0 -229
  245. package/lib/schema/cli-args.js +0 -254
  246. package/lib/schema/cli-transformers.js +0 -113
  247. package/lib/schema/index.js +0 -2
  248. package/lib/schema/keywords.js +0 -136
  249. package/lib/schema/schema.js +0 -725
  250. package/lib/utils.js +0 -512
@@ -1,146 +0,0 @@
1
- import axios from 'axios';
2
- import {fs} from '@appium/support';
3
- import logger from './logger';
4
- import _ from 'lodash';
5
-
6
- const hubUri = (config) => {
7
- const protocol = config.hubProtocol || 'http';
8
- return `${protocol}://${config.hubHost}:${config.hubPort}`;
9
- };
10
-
11
- /**
12
- * Registers a new node with a selenium grid
13
- * @param {string|object} data - Path or object representing selenium grid node config file. If a `string`, all subsequent arguments are required!
14
- * @param {string} [addr] - Bind to this address
15
- * @param {number} [port] - Bind to this port
16
- * @param {string} [basePath] - Base path for the grid
17
- */
18
- async function registerNode(data, addr, port, basePath) {
19
- let configFilePath;
20
- if (_.isString(data)) {
21
- configFilePath = data;
22
- try {
23
- data = await fs.readFile(data, 'utf-8');
24
- } catch (err) {
25
- logger.error(
26
- `Unable to load node configuration file ${configFilePath} to register with grid: ${err.message}`
27
- );
28
- return;
29
- }
30
- try {
31
- data = JSON.parse(data);
32
- } catch (err) {
33
- throw logger.errorWithException(
34
- `Syntax error in node configuration file ${configFilePath}: ${err.message}`
35
- );
36
- }
37
- }
38
-
39
- postRequest(data, addr, port, basePath);
40
- }
41
-
42
- async function registerToGrid(postOptions, configHolder) {
43
- try {
44
- const {status} = await axios(postOptions);
45
- if (status !== 200) {
46
- throw new Error(`Request failed with code ${status}`);
47
- }
48
- logger.debug(
49
- `Appium successfully registered with the the grid on ` + hubUri(configHolder.configuration)
50
- );
51
- } catch (err) {
52
- logger.error(`An attempt to register with the grid was unsuccessful: ${err.message}`);
53
- }
54
- }
55
-
56
- function postRequest(configHolder, addr, port, basePath) {
57
- // Move Selenium 3 configuration properties to configuration object
58
- if (!_.has(configHolder, 'configuration')) {
59
- let configuration = {};
60
- for (const property in /** @type {import('@appium/types').StringRecord} */ (configHolder)) {
61
- if (_.has(configHolder, property) && property !== 'capabilities') {
62
- configuration[property] = configHolder[property];
63
- delete configHolder[property];
64
- }
65
- }
66
- /** @type {import('@appium/types').StringRecord} */ (configHolder).configuration = configuration;
67
- }
68
-
69
- // if the node config does not have the appium/webdriver url, host, and port,
70
- // automatically add it based on how appium was initialized
71
- // otherwise, we will take whatever the user setup
72
- // because we will always set localhost/127.0.0.1. this won't work if your
73
- // node and grid aren't in the same place
74
- if (
75
- !configHolder.configuration.url ||
76
- !configHolder.configuration.host ||
77
- !configHolder.configuration.port
78
- ) {
79
- configHolder.configuration.url = `http://${addr}:${port}${basePath}`;
80
- configHolder.configuration.host = addr;
81
- configHolder.configuration.port = port;
82
- }
83
- // if the node config does not have id automatically add it
84
- if (!configHolder.configuration.id) {
85
- configHolder.configuration.id = `http://${configHolder.configuration.host}:${configHolder.configuration.port}`;
86
- }
87
-
88
- // the post options
89
- const regRequest = {
90
- url: `${hubUri(configHolder.configuration)}/grid/register`,
91
- method: 'POST',
92
- data: configHolder,
93
- };
94
-
95
- if (configHolder.configuration.register !== true) {
96
- logger.debug(`No registration sent (${configHolder.configuration.register} = false)`);
97
- return;
98
- }
99
-
100
- const registerCycleInterval = configHolder.configuration.registerCycle;
101
- if (isNaN(registerCycleInterval) || registerCycleInterval <= 0) {
102
- logger.warn(
103
- `'registerCycle' is not a valid positive number. ` +
104
- `No registration request will be sent to the grid.`
105
- );
106
- return;
107
- }
108
- // initiate a new Thread
109
- let first = true;
110
- logger.debug(
111
- `Starting auto register thread for the grid. ` +
112
- `Will try to register every ${registerCycleInterval} ms.`
113
- );
114
- setInterval(async function registerRetry() {
115
- if (first) {
116
- first = false;
117
- await registerToGrid(regRequest, configHolder);
118
- } else if (!(await isAlreadyRegistered(configHolder))) {
119
- // make the http POST to the grid for registration
120
- await registerToGrid(regRequest, configHolder);
121
- }
122
- }, registerCycleInterval);
123
- }
124
-
125
- async function isAlreadyRegistered(configHolder) {
126
- //check if node is already registered
127
- const id = configHolder.configuration.id;
128
- try {
129
- const {data, status} = await axios({
130
- url: `${hubUri(configHolder.configuration)}/grid/api/proxy?id=${id}`,
131
- timeout: 10000,
132
- });
133
- if (status !== 200) {
134
- throw new Error(`Request failed with code ${status}`);
135
- }
136
- if (!data.success) {
137
- // if register fail, print the debug msg
138
- logger.debug(`Grid registration error: ${data.msg}`);
139
- }
140
- return data.success;
141
- } catch (err) {
142
- logger.debug(`Hub down or not responding: ${err.message}`);
143
- }
144
- }
145
-
146
- export default registerNode;
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 grid, 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
- */