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/config.ts DELETED
@@ -1,377 +0,0 @@
1
- /* eslint-disable no-console */
2
- import _ from 'lodash';
3
- import {system, fs, npm} from '@appium/support';
4
- import axios from 'axios';
5
- import {exec} from 'teen_process';
6
- import * as semver from 'semver';
7
- import os from 'node:os';
8
- import {npmPackage} from './utils';
9
- import B from 'bluebird';
10
- import {getDefaultsForSchema, getAllArgSpecs} from './schema/schema';
11
- import type {BuildInfo, Args} from 'appium/types';
12
- import type {ReadConfigFileResult} from './config-file';
13
-
14
- export const APPIUM_VER = npmPackage.version;
15
- const ENGINES = npmPackage.engines as Record<string, string>;
16
- const MIN_NODE_VERSION = ENGINES.node;
17
- export const rootDir = fs.findRoot(__dirname);
18
-
19
- const GIT_BINARY = `git${system.isWindows() ? '.exe' : ''}`;
20
- const GITHUB_API = 'https://api.github.com/repos/appium/appium';
21
-
22
- const BUILD_INFO: BuildInfo = {
23
- version: APPIUM_VER,
24
- };
25
-
26
- /**
27
- * Update mutable build info metadata from local git or GitHub fallback.
28
- */
29
- export async function updateBuildInfo(useGithubApiFallback = false): Promise<void> {
30
- const sha = await getGitRev(useGithubApiFallback);
31
- if (!sha) {
32
- return;
33
- }
34
- BUILD_INFO['git-sha'] = sha;
35
- const buildTimestamp = await getGitTimestamp(sha, useGithubApiFallback);
36
- if (buildTimestamp) {
37
- BUILD_INFO.built = buildTimestamp;
38
- }
39
- }
40
-
41
- /**
42
- * Prints server debug info to stdout.
43
- */
44
- export async function showDebugInfo({driverConfig, pluginConfig, appiumHome}: DebugInfoInput): Promise<void> {
45
- const getNpmVersion = async (): Promise<string> => {
46
- const {stdout} = await npm.exec('--version', [], {cwd: process.cwd()});
47
- return _.trim(stdout);
48
- };
49
- const findNpmLocation = async (): Promise<string> =>
50
- await fs.which(system.isWindows() ? 'npm.cmd' : 'npm');
51
-
52
- const [npmVersion, npmLocation] = await B.all([
53
- ...[getNpmVersion, findNpmLocation].map((f) => getSafeResult(f, 'unknown')),
54
- updateBuildInfo() as Promise<unknown>,
55
- ]);
56
-
57
- const debugInfo = {
58
- os: {
59
- platform: os.platform(),
60
- release: os.release(),
61
- arch: os.arch(),
62
- homedir: os.homedir(),
63
- username: os.userInfo().username,
64
- },
65
- node: {
66
- version: process.version,
67
- arch: process.arch,
68
- cwd: process.cwd(),
69
- argv: process.argv,
70
- env: process.env,
71
- npm: {
72
- location: npmLocation,
73
- version: npmVersion,
74
- },
75
- },
76
- appium: {
77
- location: rootDir,
78
- homedir: appiumHome,
79
- build: getBuildInfo(),
80
- drivers: driverConfig.installedExtensions,
81
- plugins: pluginConfig.installedExtensions,
82
- },
83
- };
84
- console.log(JSON.stringify(debugInfo, null, 2));
85
- }
86
-
87
- /**
88
- * Returns the current git commit SHA for this Appium checkout.
89
- *
90
- * Attempts to read from local git first; when unavailable and fallback is enabled,
91
- * queries the GitHub API for the tag matching the current Appium version.
92
- */
93
- export async function getGitRev(useGithubApiFallback = false): Promise<string | null> {
94
- const fullGitPath = await getFullGitPath();
95
- if (fullGitPath) {
96
- try {
97
- const {stdout} = await exec(fullGitPath, ['rev-parse', 'HEAD'], {
98
- cwd: __dirname,
99
- });
100
- return stdout.trim();
101
- } catch {}
102
- }
103
-
104
- if (!useGithubApiFallback) {
105
- return null;
106
- }
107
-
108
- // If the package folder is not a valid git repository
109
- // then fetch the corresponding tag info from GitHub
110
- try {
111
- return (
112
- await axios.get(`${GITHUB_API}/git/refs/tags/appium@${APPIUM_VER}`, {
113
- headers: {
114
- 'User-Agent': `Appium ${APPIUM_VER}`,
115
- },
116
- })
117
- ).data?.object?.sha;
118
- } catch {}
119
- return null;
120
- }
121
-
122
- /**
123
- * Mutable object containing Appium build information. By default it
124
- * only contains the Appium version, but is updated with the build timestamp
125
- * and git commit hash asynchronously as soon as `updateBuildInfo` is called
126
- * and succeeds.
127
- */
128
- export function getBuildInfo(): BuildInfo {
129
- return BUILD_INFO;
130
- }
131
-
132
- /**
133
- * @throws {Error} If Node version is outside of the supported range
134
- */
135
- export function checkNodeOk(): void {
136
- const version = getNodeVersion();
137
- if (!semver.satisfies(version, MIN_NODE_VERSION)) {
138
- throw new Error(`Node version must be at least ${MIN_NODE_VERSION}; current is ${version.version}`);
139
- }
140
- }
141
-
142
- /**
143
- * Prints the current build info JSON to stdout.
144
- *
145
- * This updates build metadata first (using GitHub fallback) and then logs the
146
- * resulting {@link BuildInfo} object.
147
- */
148
- export async function showBuildInfo(): Promise<void> {
149
- await updateBuildInfo(true);
150
- console.log(JSON.stringify(getBuildInfo()));
151
- }
152
-
153
- /**
154
- * Returns k/v pairs of server arguments which are _not_ the defaults.
155
- */
156
- export function getNonDefaultServerArgs(parsedArgs: Args): Args {
157
- /**
158
- * Flattens parsed args into a single level object for comparison with
159
- * flattened defaults across server args and extension args.
160
- */
161
- const flatten = (args: Args): Record<string, FlattenedArg> => {
162
- const argSpecs = getAllArgSpecs();
163
- const flattened = _.reduce(
164
- [...argSpecs.values()],
165
- (acc: Record<string, FlattenedArg>, argSpec: {dest: string}) => {
166
- if (_.has(args, argSpec.dest)) {
167
- acc[argSpec.dest] = {value: _.get(args, argSpec.dest), argSpec};
168
- }
169
- return acc;
170
- },
171
- {}
172
- );
173
-
174
- return flattened;
175
- };
176
-
177
- const args = flatten(parsedArgs);
178
-
179
- // hopefully these function names are descriptive enough
180
- const typesDiffer = (dest: string): boolean =>
181
- typeof args[dest].value !== typeof defaultsFromSchema[dest];
182
-
183
- const defaultValueIsArray = (dest: string): boolean => _.isArray(defaultsFromSchema[dest]);
184
-
185
- const argsValueIsArray = (dest: string): boolean => _.isArray(args[dest].value);
186
-
187
- const arraysDiffer = (dest: string): boolean =>
188
- _.gt(_.size(_.difference(args[dest].value as any[], defaultsFromSchema[dest] as any[])), 0);
189
-
190
- const valuesDiffer = (dest: string): boolean => args[dest].value !== defaultsFromSchema[dest];
191
-
192
- const defaultIsDefined = (dest: string): boolean => !_.isUndefined(defaultsFromSchema[dest]);
193
-
194
- // note that `_.overEvery` is like an "AND", and `_.overSome` is like an "OR"
195
- const argValueNotArrayOrArraysDiffer = _.overSome([_.negate(argsValueIsArray), arraysDiffer]);
196
-
197
- const defaultValueNotArrayAndValuesDiffer = _.overEvery([
198
- _.negate(defaultValueIsArray),
199
- valuesDiffer,
200
- ]);
201
-
202
- /**
203
- * This used to be a hideous conditional, but it's broken up into a hideous function instead.
204
- * hopefully this makes things a little more understandable.
205
- * - checks if the default value is defined
206
- * - if so, and the default is not an array:
207
- * - ensures the types are the same
208
- * - ensures the values are equal
209
- * - if so, and the default is an array:
210
- * - ensures the args value is an array
211
- * - ensures the args values do not differ from the default values
212
- */
213
- const isNotDefault = _.overEvery([
214
- defaultIsDefined,
215
- _.overSome([
216
- typesDiffer,
217
- _.overEvery([defaultValueIsArray, argValueNotArrayOrArraysDiffer]),
218
- defaultValueNotArrayAndValuesDiffer,
219
- ]),
220
- ]);
221
-
222
- const defaultsFromSchema = getDefaultsForSchema(true) as Record<string, unknown>;
223
-
224
- return _.reduce(
225
- _.pickBy(args, (_v, key) => isNotDefault(key)),
226
- // explodes the flattened object back into nested one
227
- (acc: Args, {value, argSpec}: FlattenedArg) => _.set(acc, argSpec.dest, value),
228
- {} as Args
229
- );
230
- }
231
-
232
- /**
233
- * Shows a breakdown of the current config after CLI params, config file loaded & defaults applied.
234
- *
235
- * The actual shape of `preConfigParsedArgs` and `defaults` does not matter for the purposes of this
236
- * function, but it's intended to be called with values of type {@link ParsedArgs} and
237
- * `DefaultValues<true>`, respectively.
238
- */
239
- export function showConfig(
240
- nonDefaultPreConfigParsedArgs: Partial<Args>,
241
- configResult: ReadConfigFileResult,
242
- defaults: Partial<Args>,
243
- parsedArgs: Args
244
- ): void {
245
- console.log('Appium Configuration\n');
246
- console.log('from defaults:\n');
247
- console.dir(compactConfig(defaults));
248
- if (configResult.config) {
249
- console.log(`\nfrom config file at ${configResult.filepath}:\n`);
250
- console.dir(compactConfig(configResult.config));
251
- } else {
252
- console.log(`\n(no configuration file loaded)`);
253
- }
254
- const compactedNonDefaultPreConfigArgs = compactConfig(nonDefaultPreConfigParsedArgs);
255
- if (_.isEmpty(compactedNonDefaultPreConfigArgs)) {
256
- console.log(`\n(no CLI parameters provided)`);
257
- } else {
258
- console.log('\nvia CLI or function call:\n');
259
- console.dir(compactedNonDefaultPreConfigArgs);
260
- }
261
- console.log('\nfinal configuration:\n');
262
- console.dir(compactConfig(parsedArgs));
263
- }
264
-
265
- /**
266
- * Ensures a directory exists and (optionally) is writeable.
267
- *
268
- * If the directory does not exist, this attempts to create it recursively.
269
- *
270
- * @throws {Error}
271
- */
272
- export async function requireDir(
273
- root: string,
274
- requireWriteable = true,
275
- displayName = 'folder path'
276
- ): Promise<void> {
277
- let stat;
278
- try {
279
- stat = await fs.stat(root);
280
- } catch (e) {
281
- if ((e as NodeJS.ErrnoException).code === 'ENOENT') {
282
- try {
283
- await fs.mkdir(root, {recursive: true});
284
- return;
285
- } catch {}
286
- }
287
- throw new Error(`The ${displayName} '${root}' must exist and be a valid directory`);
288
- }
289
- if (stat && !stat.isDirectory()) {
290
- throw new Error(`The ${displayName} '${root}' must be a valid directory`);
291
- }
292
- if (requireWriteable) {
293
- try {
294
- await fs.access(root, fs.constants.W_OK);
295
- } catch {
296
- throw new Error(
297
- `The ${displayName} '${root}' must be writeable for the current user account '${os.userInfo().username}'`
298
- );
299
- }
300
- }
301
- }
302
-
303
- function getNodeVersion(): semver.SemVer {
304
- return semver.coerce(process.version) as semver.SemVer;
305
- }
306
-
307
- const getFullGitPath = _.memoize(async function getFullGitPath(): Promise<string | null> {
308
- try {
309
- return await fs.which(GIT_BINARY);
310
- } catch {
311
- return null;
312
- }
313
- });
314
-
315
- async function getGitTimestamp(commitSha: string, useGithubApiFallback = false): Promise<string | null> {
316
- const fullGitPath = await getFullGitPath();
317
- if (fullGitPath) {
318
- try {
319
- const {stdout} = await exec(fullGitPath, ['show', '-s', '--format=%ci', commitSha], {
320
- cwd: __dirname,
321
- });
322
- return stdout.trim();
323
- } catch {}
324
- }
325
-
326
- if (!useGithubApiFallback) {
327
- return null;
328
- }
329
-
330
- try {
331
- return (
332
- await axios.get(`${GITHUB_API}/git/tags/${commitSha}`, {
333
- headers: {
334
- 'User-Agent': `Appium ${APPIUM_VER}`,
335
- },
336
- })
337
- ).data?.tagger?.date;
338
- } catch {}
339
- return null;
340
- }
341
-
342
- /**
343
- * Compacts an object for {@link showConfig}:
344
- * 1. Removes `subcommand` key/value
345
- * 2. Removes `undefined` values
346
- * 3. Removes empty objects (but not `false` values)
347
- * Does not operate recursively.
348
- */
349
- const compactConfig = _.partial(
350
- _.omitBy,
351
- _,
352
- (value: unknown, key: string) =>
353
- key === 'subcommand' || _.isUndefined(value) || (_.isObject(value) && _.isEmpty(value))
354
- );
355
-
356
- /**
357
- * Calculates the result of the given function and return its value
358
- * or the default one if there was an exception.
359
- */
360
- async function getSafeResult<T>(f: () => Promise<T>, defaultValue: T): Promise<T> {
361
- try {
362
- return await f();
363
- } catch {
364
- return defaultValue;
365
- }
366
- }
367
-
368
- interface DebugInfoInput {
369
- driverConfig: {installedExtensions: unknown};
370
- pluginConfig: {installedExtensions: unknown};
371
- appiumHome: string;
372
- }
373
-
374
- interface FlattenedArg {
375
- value: unknown;
376
- argSpec: {dest: string};
377
- }
@@ -1,245 +0,0 @@
1
- import _ from 'lodash';
2
- import {DRIVER_TYPE} from '../constants';
3
- import log from '../logger';
4
- import {ExtensionConfig} from './extension-config';
5
-
6
- /**
7
- * @extends {ExtensionConfig<DriverType>}
8
- */
9
- export class DriverConfig extends ExtensionConfig {
10
- /**
11
- * A set of unique automation names used by drivers.
12
- * @type {Set<string>}
13
- */
14
- knownAutomationNames;
15
-
16
- /**
17
- * A mapping of {@link Manifest} instances to {@link DriverConfig} instances.
18
- *
19
- * `Manifest` and `ExtensionConfig` have a one-to-many relationship; each `Manifest` should be associated with a `DriverConfig` and a `PluginConfig`; no more, no less.
20
- *
21
- * This variable tracks the `Manifest`-to-`DriverConfig` portion.
22
- *
23
- * @type {WeakMap<Manifest,DriverConfig>}
24
- * @private
25
- */
26
- static _instances = new WeakMap();
27
-
28
- /**
29
- * Call {@link DriverConfig.create} instead.
30
- * @private
31
- * @param {import('./manifest').Manifest} manifest - Manifest instance
32
- */
33
- constructor(manifest) {
34
- super(DRIVER_TYPE, manifest);
35
-
36
- this.knownAutomationNames = new Set();
37
- }
38
-
39
- /**
40
- * Creates a new {@link DriverConfig} instance for a {@link Manifest} instance.
41
- *
42
- * @param {Manifest} manifest
43
- * @throws If `manifest` already associated with a `DriverConfig`
44
- * @returns {DriverConfig}
45
- */
46
- static create(manifest) {
47
- const instance = new DriverConfig(manifest);
48
- if (DriverConfig.getInstance(manifest)) {
49
- throw new Error(
50
- `Manifest with APPIUM_HOME ${manifest.appiumHome} already has a DriverConfig; use DriverConfig.getInstance() to retrieve it.`
51
- );
52
- }
53
- DriverConfig._instances.set(manifest, instance);
54
- return instance;
55
- }
56
-
57
- /**
58
- * Returns a DriverConfig associated with a Manifest
59
- * @param {Manifest} manifest
60
- * @returns {DriverConfig|undefined}
61
- */
62
- static getInstance(manifest) {
63
- return DriverConfig._instances.get(manifest);
64
- }
65
-
66
- /**
67
- * Checks extensions for problems
68
- */
69
- async validate() {
70
- this.knownAutomationNames.clear();
71
- return await super._validate(this.manifest.getExtensionData(DRIVER_TYPE));
72
- }
73
-
74
- /**
75
- * @param {ExtManifest<DriverType>} extData
76
- * @returns {import('./extension-config').ExtManifestProblem[]}
77
- */
78
- getConfigProblems(extData) {
79
- const problems = [];
80
- const {platformNames, automationName} = extData;
81
-
82
- if (!_.isArray(platformNames)) {
83
- problems.push({
84
- err: 'Missing or incorrect supported platformNames list.',
85
- val: platformNames,
86
- });
87
- } else if (_.isEmpty(platformNames)) {
88
- problems.push({
89
- err: 'Empty platformNames list.',
90
- val: platformNames,
91
- });
92
- } else {
93
- for (const pName of platformNames) {
94
- if (!_.isString(pName)) {
95
- problems.push({
96
- err: 'Incorrectly formatted platformName.',
97
- val: pName,
98
- });
99
- }
100
- }
101
- }
102
-
103
- if (!_.isString(automationName)) {
104
- problems.push({
105
- err: 'Missing or incorrect automationName',
106
- val: automationName,
107
- });
108
- }
109
-
110
- if (this.knownAutomationNames.has(automationName)) {
111
- problems.push({
112
- err: 'Multiple drivers claim support for the same automationName',
113
- val: automationName,
114
- });
115
- }
116
-
117
- // should we retain the name at the end of this function, once we've checked there are no problems?
118
- this.knownAutomationNames.add(automationName);
119
-
120
- return problems;
121
- }
122
-
123
- /**
124
- * @param {ExtName<DriverType>} driverName
125
- * @param {ExtManifest<DriverType>} extData
126
- * @returns {string}
127
- */
128
- extensionDesc(driverName, {version, automationName}) {
129
- return `${driverName}@${version} (automationName '${automationName}')`;
130
- }
131
-
132
- /**
133
- * Given capabilities, find a matching driver within the config. Load its class and return it along with version and driver name.
134
- * @template {import('@appium/types').StringRecord} C
135
- * @param {C} caps
136
- * @returns {Promise<MatchedDriver>}
137
- */
138
- async findMatchingDriver({automationName, platformName}) {
139
- if (!_.isString(platformName)) {
140
- throw new Error('You must include a platformName capability');
141
- }
142
-
143
- if (!_.isString(automationName)) {
144
- throw new Error('You must include an automationName capability');
145
- }
146
-
147
- log.info(
148
- `Attempting to find matching driver for automationName ` +
149
- `'${automationName}' and platformName '${platformName}'`
150
- );
151
-
152
- try {
153
- const {driverName, mainClass, version} = this._getDriverBySupport(
154
- automationName,
155
- platformName
156
- );
157
- log.info(`The '${driverName}' driver was installed and matched caps.`);
158
- log.info(`Will require it at ${this.getInstallPath(driverName)}`);
159
- const driver = await this.requireAsync(driverName);
160
- if (!driver) {
161
- throw new Error(
162
- `Driver '${driverName}' did not export a class with name '${mainClass}'. Contact the author of the driver!`
163
- );
164
- }
165
- return {driver, version, driverName};
166
- } catch (err) {
167
- const msg =
168
- `Could not find a driver for automationName ` +
169
- `'${automationName}' and platformName '${platformName}'. ` +
170
- `Have you installed a driver that supports those ` +
171
- `capabilities? Run 'appium driver list --installed' to see. ` +
172
- `(Lower-level error: ${err.message})`;
173
- throw new Error(msg);
174
- }
175
- }
176
-
177
- /**
178
- * Given an automation name and platform name, find a suitable driver and return its extension data.
179
- * @param {string} matchAutomationName
180
- * @param {string} matchPlatformName
181
- * @returns {ExtMetadata<DriverType> & import('appium/types').InternalMetadata & import('appium/types').CommonExtMetadata}
182
- */
183
- _getDriverBySupport(matchAutomationName, matchPlatformName) {
184
- const drivers = this.installedExtensions;
185
- for (const [driverName, driverData] of _.toPairs(drivers)) {
186
- const {automationName, platformNames} = driverData;
187
- const aNameMatches = automationName.toLowerCase() === matchAutomationName.toLowerCase();
188
- const pNameMatches = _.includes(
189
- platformNames.map(_.toLower),
190
- matchPlatformName.toLowerCase()
191
- );
192
-
193
- if (aNameMatches && pNameMatches) {
194
- return {driverName, ...driverData};
195
- }
196
-
197
- if (aNameMatches) {
198
- throw new Error(
199
- `Driver '${driverName}' supports automationName ` +
200
- `'${automationName}', but Appium could not find ` +
201
- `support for platformName '${matchPlatformName}'. Supported ` +
202
- `platformNames are: ` +
203
- JSON.stringify(platformNames)
204
- );
205
- }
206
- }
207
-
208
- throw new Error(`Could not find installed driver to support given caps`);
209
- }
210
- }
211
-
212
- /**
213
- * @template {ExtensionType} T
214
- * @typedef {import('appium/types').ExtMetadata<T>} ExtMetadata
215
- */
216
-
217
- /**
218
- * @template {ExtensionType} T
219
- * @typedef {import('appium/types').ExtManifest<T>} ExtManifest
220
- */
221
-
222
- /**
223
- * @typedef {import('@appium/types').ExtensionType} ExtensionType
224
- * @typedef {import('appium/types').ManifestData} ManifestData
225
- * @typedef {import('@appium/types').DriverType} DriverType
226
- * @typedef {import('./manifest').Manifest} Manifest
227
- */
228
-
229
- /**
230
- * @template {ExtensionType} T
231
- * @typedef {import('appium/types').ExtRecord<T>} ExtRecord
232
- */
233
-
234
- /**
235
- * @template {ExtensionType} T
236
- * @typedef {import('appium/types').ExtName<T>} ExtName
237
- */
238
-
239
- /**
240
- * Return value of {@linkcode DriverConfig.findMatchingDriver}
241
- * @typedef MatchedDriver
242
- * @property {import('@appium/types').DriverClass} driver
243
- * @property {string} version
244
- * @property {string} driverName
245
- */