appium 3.4.2 → 3.5.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 +3 -0
  2. package/build/lib/appium.d.ts.map +1 -1
  3. package/build/lib/appium.js +73 -51
  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 +36 -31
  7. package/build/lib/bidi-commands.js.map +1 -1
  8. package/build/lib/bootstrap/appium-initializer.d.ts.map +1 -1
  9. package/build/lib/bootstrap/appium-initializer.js +13 -13
  10. package/build/lib/bootstrap/appium-initializer.js.map +1 -1
  11. package/build/lib/bootstrap/appium-main-runner.d.ts.map +1 -1
  12. package/build/lib/bootstrap/appium-main-runner.js +2 -2
  13. package/build/lib/bootstrap/appium-main-runner.js.map +1 -1
  14. package/build/lib/bootstrap/config-file.d.ts.map +1 -1
  15. package/build/lib/bootstrap/config-file.js +11 -11
  16. package/build/lib/bootstrap/config-file.js.map +1 -1
  17. package/build/lib/bootstrap/grid-v3-register.d.ts.map +1 -1
  18. package/build/lib/bootstrap/grid-v3-register.js +9 -6
  19. package/build/lib/bootstrap/grid-v3-register.js.map +1 -1
  20. package/build/lib/bootstrap/main-helpers.d.ts +1 -1
  21. package/build/lib/bootstrap/main-helpers.d.ts.map +1 -1
  22. package/build/lib/bootstrap/main-helpers.js +19 -20
  23. package/build/lib/bootstrap/main-helpers.js.map +1 -1
  24. package/build/lib/bootstrap/node-helpers.d.ts +1 -1
  25. package/build/lib/bootstrap/node-helpers.d.ts.map +1 -1
  26. package/build/lib/bootstrap/node-helpers.js +8 -16
  27. package/build/lib/bootstrap/node-helpers.js.map +1 -1
  28. package/build/lib/bootstrap/startup-config.d.ts.map +1 -1
  29. package/build/lib/bootstrap/startup-config.js +32 -30
  30. package/build/lib/bootstrap/startup-config.js.map +1 -1
  31. package/build/lib/cli/args.d.ts +3 -2
  32. package/build/lib/cli/args.d.ts.map +1 -1
  33. package/build/lib/cli/args.js +2 -5
  34. package/build/lib/cli/args.js.map +1 -1
  35. package/build/lib/cli/driver-command.d.ts +1 -2
  36. package/build/lib/cli/driver-command.d.ts.map +1 -1
  37. package/build/lib/cli/driver-command.js +7 -8
  38. package/build/lib/cli/driver-command.js.map +1 -1
  39. package/build/lib/cli/extension-command.d.ts +2 -2
  40. package/build/lib/cli/extension-command.d.ts.map +1 -1
  41. package/build/lib/cli/extension-command.js +105 -71
  42. package/build/lib/cli/extension-command.js.map +1 -1
  43. package/build/lib/cli/extension.d.ts.map +1 -1
  44. package/build/lib/cli/extension.js.map +1 -1
  45. package/build/lib/cli/parser.d.ts.map +1 -1
  46. package/build/lib/cli/parser.js +21 -14
  47. package/build/lib/cli/parser.js.map +1 -1
  48. package/build/lib/cli/plugin-command.d.ts +1 -1
  49. package/build/lib/cli/plugin-command.d.ts.map +1 -1
  50. package/build/lib/cli/plugin-command.js +5 -5
  51. package/build/lib/cli/plugin-command.js.map +1 -1
  52. package/build/lib/cli/setup-command.d.ts +1 -1
  53. package/build/lib/cli/setup-command.d.ts.map +1 -1
  54. package/build/lib/cli/setup-command.js +14 -19
  55. package/build/lib/cli/setup-command.js.map +1 -1
  56. package/build/lib/cli/utils.d.ts.map +1 -1
  57. package/build/lib/cli/utils.js +3 -2
  58. package/build/lib/cli/utils.js.map +1 -1
  59. package/build/lib/doctor/doctor.d.ts +0 -1
  60. package/build/lib/doctor/doctor.d.ts.map +1 -1
  61. package/build/lib/doctor/doctor.js +12 -17
  62. package/build/lib/doctor/doctor.js.map +1 -1
  63. package/build/lib/extension/driver-config.d.ts.map +1 -1
  64. package/build/lib/extension/driver-config.js +11 -12
  65. package/build/lib/extension/driver-config.js.map +1 -1
  66. package/build/lib/extension/extension-config.d.ts.map +1 -1
  67. package/build/lib/extension/extension-config.js +30 -30
  68. package/build/lib/extension/extension-config.js.map +1 -1
  69. package/build/lib/extension/index.d.ts.map +1 -1
  70. package/build/lib/extension/index.js +28 -41
  71. package/build/lib/extension/index.js.map +1 -1
  72. package/build/lib/extension/manifest.d.ts +3 -2
  73. package/build/lib/extension/manifest.d.ts.map +1 -1
  74. package/build/lib/extension/manifest.js +20 -24
  75. package/build/lib/extension/manifest.js.map +1 -1
  76. package/build/lib/extension/plugin-config.d.ts.map +1 -1
  77. package/build/lib/extension/plugin-config.js +7 -9
  78. package/build/lib/extension/plugin-config.js.map +1 -1
  79. package/build/lib/helpers/build.d.ts +0 -1
  80. package/build/lib/helpers/build.d.ts.map +1 -1
  81. package/build/lib/helpers/build.js +2 -4
  82. package/build/lib/helpers/build.js.map +1 -1
  83. package/build/lib/helpers/capability.d.ts.map +1 -1
  84. package/build/lib/helpers/capability.js +27 -22
  85. package/build/lib/helpers/capability.js.map +1 -1
  86. package/build/lib/helpers/network.d.ts.map +1 -1
  87. package/build/lib/helpers/network.js +4 -3
  88. package/build/lib/helpers/network.js.map +1 -1
  89. package/build/lib/insecure-features.d.ts.map +1 -1
  90. package/build/lib/insecure-features.js +9 -13
  91. package/build/lib/insecure-features.js.map +1 -1
  92. package/build/lib/inspector-commands.d.ts.map +1 -1
  93. package/build/lib/inspector-commands.js +29 -28
  94. package/build/lib/inspector-commands.js.map +1 -1
  95. package/build/lib/logsink.d.ts.map +1 -1
  96. package/build/lib/logsink.js +8 -7
  97. package/build/lib/logsink.js.map +1 -1
  98. package/build/lib/schema/arg-spec.d.ts.map +1 -1
  99. package/build/lib/schema/arg-spec.js +5 -8
  100. package/build/lib/schema/arg-spec.js.map +1 -1
  101. package/build/lib/schema/cli-args.d.ts.map +1 -1
  102. package/build/lib/schema/cli-args.js +20 -19
  103. package/build/lib/schema/cli-args.js.map +1 -1
  104. package/build/lib/schema/cli-transformers.d.ts.map +1 -1
  105. package/build/lib/schema/cli-transformers.js.map +1 -1
  106. package/build/lib/schema/schema.d.ts.map +1 -1
  107. package/build/lib/schema/schema.js +28 -21
  108. package/build/lib/schema/schema.js.map +1 -1
  109. package/build/lib/utils/hash.d.ts +5 -0
  110. package/build/lib/utils/hash.d.ts.map +1 -0
  111. package/build/lib/{utils.js → utils/hash.js} +3 -21
  112. package/build/lib/utils/hash.js.map +1 -0
  113. package/build/lib/utils/index.d.ts +8 -0
  114. package/build/lib/utils/index.d.ts.map +1 -0
  115. package/build/lib/utils/index.js +31 -0
  116. package/build/lib/utils/index.js.map +1 -0
  117. package/build/lib/utils/is-package-changed.d.ts +16 -0
  118. package/build/lib/utils/is-package-changed.d.ts.map +1 -0
  119. package/build/lib/utils/is-package-changed.js +62 -0
  120. package/build/lib/utils/is-package-changed.js.map +1 -0
  121. package/build/lib/utils/object.d.ts +120 -0
  122. package/build/lib/utils/object.d.ts.map +1 -0
  123. package/build/lib/utils/object.js +288 -0
  124. package/build/lib/utils/object.js.map +1 -0
  125. package/build/lib/{extension → utils}/package-changed.d.ts +0 -1
  126. package/build/lib/utils/package-changed.d.ts.map +1 -0
  127. package/build/lib/{extension → utils}/package-changed.js +3 -4
  128. package/build/lib/utils/package-changed.js.map +1 -0
  129. package/build/lib/utils/package-json.d.ts +9 -0
  130. package/build/lib/utils/package-json.d.ts.map +1 -0
  131. package/build/lib/utils/package-json.js +32 -0
  132. package/build/lib/utils/package-json.js.map +1 -0
  133. package/build/lib/utils/resolve-from.d.ts +11 -0
  134. package/build/lib/utils/resolve-from.d.ts.map +1 -0
  135. package/build/lib/utils/resolve-from.js +41 -0
  136. package/build/lib/utils/resolve-from.js.map +1 -0
  137. package/build/types/cli.d.ts.map +1 -1
  138. package/build/types/index.d.ts.map +1 -1
  139. package/build/types/manifest/base.d.ts.map +1 -1
  140. package/build/types/manifest/v3.d.ts.map +1 -1
  141. package/build/types/manifest/v4.d.ts.map +1 -1
  142. package/lib/appium.ts +96 -61
  143. package/lib/bidi-commands.ts +107 -61
  144. package/lib/bootstrap/appium-initializer.ts +27 -19
  145. package/lib/bootstrap/appium-main-runner.ts +8 -4
  146. package/lib/bootstrap/config-file.ts +33 -16
  147. package/lib/bootstrap/grid-v3-register.ts +26 -19
  148. package/lib/bootstrap/main-helpers.ts +25 -19
  149. package/lib/bootstrap/node-helpers.ts +20 -24
  150. package/lib/bootstrap/startup-config.ts +42 -39
  151. package/lib/cli/args.ts +3 -4
  152. package/lib/cli/driver-command.ts +19 -13
  153. package/lib/cli/extension-command.ts +214 -149
  154. package/lib/cli/extension.ts +4 -6
  155. package/lib/cli/parser.ts +32 -30
  156. package/lib/cli/plugin-command.ts +20 -9
  157. package/lib/cli/setup-command.ts +54 -39
  158. package/lib/cli/utils.ts +4 -3
  159. package/lib/doctor/doctor.ts +15 -17
  160. package/lib/extension/driver-config.ts +22 -17
  161. package/lib/extension/extension-config.ts +76 -69
  162. package/lib/extension/index.ts +60 -51
  163. package/lib/extension/manifest.ts +35 -33
  164. package/lib/extension/plugin-config.ts +15 -10
  165. package/lib/helpers/build.ts +6 -5
  166. package/lib/helpers/capability.ts +40 -35
  167. package/lib/helpers/network.ts +6 -5
  168. package/lib/insecure-features.ts +16 -14
  169. package/lib/inspector-commands.ts +72 -40
  170. package/lib/logsink.ts +22 -26
  171. package/lib/schema/arg-spec.ts +9 -8
  172. package/lib/schema/cli-args-guards.ts +4 -4
  173. package/lib/schema/cli-args.ts +25 -21
  174. package/lib/schema/cli-transformers.ts +6 -2
  175. package/lib/schema/format-errors.ts +1 -1
  176. package/lib/schema/schema.ts +52 -38
  177. package/lib/{utils.ts → utils/hash.ts} +2 -19
  178. package/lib/utils/index.ts +23 -0
  179. package/lib/utils/is-package-changed.ts +78 -0
  180. package/lib/utils/object.ts +312 -0
  181. package/lib/{extension → utils}/package-changed.ts +6 -7
  182. package/lib/utils/package-json.ts +36 -0
  183. package/lib/utils/resolve-from.ts +40 -0
  184. package/package.json +16 -19
  185. package/scripts/autoinstall-extensions.js +8 -13
  186. package/tsconfig.json +8 -2
  187. package/types/cli.ts +18 -18
  188. package/types/index.ts +2 -2
  189. package/types/manifest/base.ts +2 -2
  190. package/types/manifest/v3.ts +2 -2
  191. package/types/manifest/v4.ts +2 -2
  192. package/build/lib/extension/package-changed.d.ts.map +0 -1
  193. package/build/lib/extension/package-changed.js.map +0 -1
  194. package/build/lib/utils.d.ts +0 -13
  195. package/build/lib/utils.d.ts.map +0 -1
  196. package/build/lib/utils.js.map +0 -1
@@ -8,12 +8,10 @@ import DriverCliCommand from './driver-command';
8
8
  import PluginCliCommand from './plugin-command';
9
9
  import {errAndQuit, JSON_SPACES} from './utils';
10
10
 
11
- export const commandClasses = Object.freeze(
12
- {
13
- [DRIVER_TYPE]: DriverCliCommand,
14
- [PLUGIN_TYPE]: PluginCliCommand,
15
- } as const
16
- );
11
+ export const commandClasses = Object.freeze({
12
+ [DRIVER_TYPE]: DriverCliCommand,
13
+ [PLUGIN_TYPE]: PluginCliCommand,
14
+ } as const);
17
15
 
18
16
  export type ExtCommand<ExtType extends ExtensionType> = ExtType extends DriverType
19
17
  ? Class<DriverCliCommand>
package/lib/cli/parser.ts CHANGED
@@ -1,8 +1,7 @@
1
- import {fs} from '@appium/support';
2
1
  import {ArgumentParser} from 'argparse';
3
2
  import type {SubArgumentParserOptions, SubParser} from 'argparse';
4
- import _ from 'lodash';
5
3
  import path from 'node:path';
4
+ import {setPath} from '../utils';
6
5
  import type {DriverType, PluginType} from '@appium/types';
7
6
  import type {CliExtensionSubcommand} from 'appium/types';
8
7
  import {
@@ -15,10 +14,10 @@ import {
15
14
  EXT_SUBCOMMAND_UPDATE,
16
15
  PLUGIN_TYPE,
17
16
  SERVER_SUBCOMMAND,
18
- SETUP_SUBCOMMAND
17
+ SETUP_SUBCOMMAND,
19
18
  } from '../constants';
20
19
  import {finalizeSchema, getAllArgSpecs, getArgSpec, hasArgSpec} from '../schema';
21
- import {rootDir} from '../helpers/build';
20
+ import {APPIUM_VER} from '../helpers/build';
22
21
  import {getExtensionArgs, getServerArgs} from './args';
23
22
  import type {ArgumentDefinitions} from './args';
24
23
  import {
@@ -28,7 +27,7 @@ import {
28
27
  SUBCOMMAND_BROWSER,
29
28
  SUBCOMMAND_RESET,
30
29
  getPresetDrivers,
31
- determinePlatformName
30
+ determinePlatformName,
32
31
  } from './setup-command';
33
32
 
34
33
  export const EXTRA_ARGS = 'extraArgs';
@@ -38,10 +37,18 @@ export const EXTRA_ARGS = 'extraArgs';
38
37
  * will automatically inject the `server` subcommand.
39
38
  */
40
39
  const NON_SERVER_ARGS = Object.freeze(
41
- new Set([SETUP_SUBCOMMAND, DRIVER_TYPE, PLUGIN_TYPE, SERVER_SUBCOMMAND, '-h', '--help', '-v', '--version'])
40
+ new Set([
41
+ SETUP_SUBCOMMAND,
42
+ DRIVER_TYPE,
43
+ PLUGIN_TYPE,
44
+ SERVER_SUBCOMMAND,
45
+ '-h',
46
+ '--help',
47
+ '-v',
48
+ '--version',
49
+ ]),
42
50
  );
43
51
 
44
- const version = fs.readPackageJsonFrom(rootDir).version;
45
52
  type LooseArgsMap = {[key: string]: any};
46
53
  type TransformedArgsMap = LooseArgsMap & {[EXTRA_ARGS]: string[]};
47
54
 
@@ -82,7 +89,7 @@ export class ArgParser {
82
89
 
83
90
  parser.add_argument('-v', '--version', {
84
91
  action: 'version',
85
- version,
92
+ version: APPIUM_VER,
86
93
  });
87
94
 
88
95
  const subParsers = parser.add_subparsers({dest: 'subcommand'});
@@ -129,23 +136,19 @@ export class ArgParser {
129
136
  */
130
137
  private static _transformParsedArgs(
131
138
  args: LooseArgsMap,
132
- unknownArgs: string[] = []
139
+ unknownArgs: string[] = [],
133
140
  ): TransformedArgsMap {
134
- const result = _.reduce(
135
- args,
136
- (unpacked, value, key) => {
137
- const spec = hasArgSpec(key) ? getArgSpec(key) : undefined;
138
- if (!_.isUndefined(value) && spec) {
139
- const {dest} = spec;
140
- _.set(unpacked, dest, value);
141
- } else {
142
- // this could be anything that _isn't_ a server arg
143
- unpacked[key] = value;
144
- }
145
- return unpacked;
146
- },
147
- {}
148
- );
141
+ const result = Object.entries(args).reduce((unpacked: LooseArgsMap, [key, value]) => {
142
+ const spec = hasArgSpec(key) ? getArgSpec(key) : undefined;
143
+ if (value !== undefined && spec) {
144
+ const {dest} = spec;
145
+ setPath(unpacked as Record<string, unknown>, dest, value);
146
+ } else {
147
+ // this could be anything that isn't a server arg
148
+ unpacked[key] = value;
149
+ }
150
+ return unpacked;
151
+ }, {} as LooseArgsMap);
149
152
  result[EXTRA_ARGS] = unknownArgs;
150
153
  return result as TransformedArgsMap;
151
154
  }
@@ -270,7 +273,6 @@ export class ArgParser {
270
273
  `drivers and plugins, and remove their related manifest files.`,
271
274
  });
272
275
 
273
-
274
276
  ArgParser._patchExit(setupParser);
275
277
  const extSubParsers = setupParser.add_subparsers({
276
278
  dest: `setupCommand`,
@@ -281,23 +283,23 @@ export class ArgParser {
281
283
  command: SUBCOMMAND_MOBILE,
282
284
  help:
283
285
  `The preset for mobile devices ` +
284
- `(drivers: ${_.join(getPresetDrivers(SUBCOMMAND_MOBILE), ',')}; plugins: ${DEFAULT_PLUGINS})`
286
+ `(drivers: ${getPresetDrivers(SUBCOMMAND_MOBILE).join(',')}; plugins: ${DEFAULT_PLUGINS})`,
285
287
  },
286
288
  {
287
289
  command: SUBCOMMAND_BROWSER,
288
290
  help:
289
291
  `The preset for desktop browsers ` +
290
- `(drivers: ${_.join(getPresetDrivers(SUBCOMMAND_BROWSER), ',')}; plugins: ${DEFAULT_PLUGINS})`
292
+ `(drivers: ${getPresetDrivers(SUBCOMMAND_BROWSER).join(',')}; plugins: ${DEFAULT_PLUGINS})`,
291
293
  },
292
294
  {
293
295
  command: SUBCOMMAND_DESKTOP,
294
296
  help:
295
297
  `The preset for desktop applications ` +
296
- `(drivers: ${_.join(getPresetDrivers(SUBCOMMAND_DESKTOP), ',')}; plugins: ${DEFAULT_PLUGINS})`
298
+ `(drivers: ${getPresetDrivers(SUBCOMMAND_DESKTOP).join(',')}; plugins: ${DEFAULT_PLUGINS})`,
297
299
  },
298
300
  {
299
301
  command: SUBCOMMAND_RESET,
300
- help: 'Remove all installed drivers and plugins'
302
+ help: 'Remove all installed drivers and plugins',
301
303
  },
302
304
  ];
303
305
 
@@ -348,7 +350,7 @@ export class ArgParser {
348
350
  // eslint-disable-next-line no-console
349
351
  console.error(); // need an extra space since argparse prints usage.
350
352
  // eslint-disable-next-line no-console
351
- console.error(err.message);
353
+ console.error(err instanceof Error ? err.message : String(err));
352
354
  process.exit(1);
353
355
  }
354
356
  }
@@ -1,4 +1,4 @@
1
- import _ from 'lodash';
1
+ import {console, util} from '@appium/support';
2
2
  import type {ExtMetadata, ExtRecord, InstallType} from 'appium/types';
3
3
  import ExtensionCliCommand from './extension-command';
4
4
  import type {
@@ -28,7 +28,11 @@ export default class PluginCliCommand extends ExtensionCliCommand<'plugin'> {
28
28
  *
29
29
  * @param opts - install options
30
30
  */
31
- async install({plugin, installType, packageName}: PluginInstallOpts): Promise<ExtRecord<'plugin'>> {
31
+ async install({
32
+ plugin,
33
+ installType,
34
+ packageName,
35
+ }: PluginInstallOpts): Promise<ExtRecord<'plugin'>> {
32
36
  return await super._install({
33
37
  installSpec: plugin,
34
38
  installType,
@@ -89,7 +93,10 @@ export default class PluginCliCommand extends ExtensionCliCommand<'plugin'> {
89
93
  * @returns formatted success text
90
94
  */
91
95
  override getPostInstallText({extName, extData}: ExtensionArgs<'plugin'>): PostInstallText {
92
- return `Plugin ${extName}@${extData.version} successfully installed`.green;
96
+ return console.styleText(
97
+ 'green',
98
+ `Plugin ${extName}@${extData.version} successfully installed`,
99
+ );
93
100
  }
94
101
 
95
102
  /**
@@ -101,16 +108,20 @@ export default class PluginCliCommand extends ExtensionCliCommand<'plugin'> {
101
108
  * @param pluginMetadata - `appium` metadata from extension package
102
109
  * @param installSpec - install spec from CLI
103
110
  */
104
- override validateExtensionFields(pluginMetadata: ExtMetadata<'plugin'>, installSpec: string): void {
105
- const missingFields = REQ_PLUGIN_FIELDS.reduce(
106
- (acc, field) => (pluginMetadata[field] ? acc : [...acc, field]),
107
- []
111
+ override validateExtensionFields(
112
+ pluginMetadata: ExtMetadata<'plugin'>,
113
+ installSpec: string,
114
+ ): void {
115
+ const missingFields = REQ_PLUGIN_FIELDS.reduce<string[]>(
116
+ (acc, field) =>
117
+ pluginMetadata[field as keyof typeof pluginMetadata] ? acc : [...acc, field],
118
+ [],
108
119
  );
109
120
 
110
- if (!_.isEmpty(missingFields)) {
121
+ if (!util.isEmpty(missingFields)) {
111
122
  throw new Error(
112
123
  `Installed plugin "${installSpec}" did not expose correct fields for compatibility ` +
113
- `with Appium. Missing fields: ${JSON.stringify(missingFields)}`
124
+ `with Appium. Missing fields: ${JSON.stringify(missingFields)}`,
114
125
  );
115
126
  }
116
127
  }
@@ -1,4 +1,3 @@
1
- import _ from 'lodash';
2
1
  import type {
3
2
  Args,
4
3
  CliCommandSetup,
@@ -6,13 +5,9 @@ import type {
6
5
  CliExtensionCommand,
7
6
  CliExtensionSubcommand,
8
7
  } from 'appium/types';
9
- import {
10
- DESKTOP_BROWSERS,
11
- DESKTOP_DRIVERS,
12
- MOBILE_DRIVERS
13
- } from '../constants';
8
+ import {DESKTOP_BROWSERS, DESKTOP_DRIVERS, MOBILE_DRIVERS} from '../constants';
14
9
  import {runExtensionCommand} from './extension';
15
- import { system, fs } from '@appium/support';
10
+ import {system, fs} from '@appium/support';
16
11
  import {log} from '../logger';
17
12
  import type {ExtensionConfig} from '../extension/extension-config';
18
13
 
@@ -29,9 +24,9 @@ export const SUBCOMMAND_RESET = 'reset';
29
24
  * Driver names listed in KNOWN_DRIVERS to install by default
30
25
  */
31
26
  const PRESET_PAIRS = Object.freeze({
32
- mobile: _.keys(MOBILE_DRIVERS),
33
- desktop: _.keys(DESKTOP_DRIVERS),
34
- browser: _.keys(DESKTOP_BROWSERS),
27
+ mobile: Object.keys(MOBILE_DRIVERS),
28
+ desktop: Object.keys(DESKTOP_DRIVERS),
29
+ browser: Object.keys(DESKTOP_BROWSERS),
35
30
  } as const);
36
31
  const DRIVERS_ONLY_MACOS = ['xcuitest', 'safari', 'mac2'];
37
32
 
@@ -49,19 +44,20 @@ type CliExtArgs = Args<CliExtensionCommand, CliExtensionSubcommand>;
49
44
  /**
50
45
  * Return a list of drivers available for current host platform.
51
46
  */
52
- export function getPresetDrivers(presetName: CliCommandSetupSubcommand): string[] {
53
- return _.filter(PRESET_PAIRS[presetName], (driver) => {
54
- if (_.includes(DRIVERS_ONLY_MACOS, driver)) {
47
+ export function getPresetDrivers(
48
+ presetName: Exclude<CliCommandSetupSubcommand, 'reset'>,
49
+ ): string[] {
50
+ return PRESET_PAIRS[presetName].filter((driver) => {
51
+ if (DRIVERS_ONLY_MACOS.includes(driver)) {
55
52
  return system.isMac();
56
53
  }
57
54
 
58
- if (_.includes(DRIVERS_ONLY_WINDOWS, driver)) {
55
+ if (DRIVERS_ONLY_WINDOWS.includes(driver)) {
59
56
  return system.isWindows();
60
57
  }
61
58
 
62
59
  return true;
63
60
  });
64
-
65
61
  }
66
62
 
67
63
  /**
@@ -85,7 +81,7 @@ export function determinePlatformName(): string {
85
81
  export async function runSetupCommand(
86
82
  preConfigArgs: Args<CliCommandSetup>,
87
83
  driverConfig: DriverConfig,
88
- pluginConfig: PluginConfig
84
+ pluginConfig: PluginConfig,
89
85
  ): Promise<void> {
90
86
  switch (preConfigArgs.setupCommand) {
91
87
  case SUBCOMMAND_DESKTOP:
@@ -104,40 +100,45 @@ export async function runSetupCommand(
104
100
  await setupDefaultPlugins(pluginConfig);
105
101
  break;
106
102
  }
107
- };
103
+ }
108
104
 
109
105
  /**
110
106
  * Resets all installed drivers and extensions
111
107
  */
112
- async function resetAllExtensions(driverConfig: DriverConfig, pluginConfig: PluginConfig): Promise<void> {
108
+ async function resetAllExtensions(
109
+ driverConfig: DriverConfig,
110
+ pluginConfig: PluginConfig,
111
+ ): Promise<void> {
113
112
  const commandConfigs: [CliExtensionCommand, DriverConfig | PluginConfig][] = [
114
113
  ['driver', driverConfig],
115
114
  ['plugin', pluginConfig],
116
115
  ];
117
116
  for (const [command, config] of commandConfigs) {
118
- for (const extensionName of _.keys(config.installedExtensions)) {
117
+ for (const extensionName of Object.keys(config.installedExtensions)) {
119
118
  try {
120
119
  await uninstallExtension(
121
120
  extensionName,
122
121
  extensionCommandArgs(command, extensionName, 'uninstall'),
123
- config
122
+ config,
124
123
  );
125
124
  } catch (e) {
126
125
  log.warn(
127
126
  `${extensionName} ${command} cannot be uninstalled. Will delete the manifest anyway. ` +
128
- `Original error: ${e.stack}`
127
+ `Original error: ${e instanceof Error ? e.stack : String(e)}`,
129
128
  );
130
129
  }
131
130
  }
132
131
 
133
132
  const manifestPath = config.manifestPath;
134
- if (!manifestPath || !await fs.exists(manifestPath)) {
133
+ if (!manifestPath || !(await fs.exists(manifestPath))) {
135
134
  continue;
136
135
  }
137
136
 
138
137
  await fs.rimraf(manifestPath);
139
138
  if (await fs.exists(manifestPath)) {
140
- throw new Error(`${command} manifest at '${manifestPath}' cannot be deleted. Is it accessible?`);
139
+ throw new Error(
140
+ `${command} manifest at '${manifestPath}' cannot be deleted. Is it accessible?`,
141
+ );
141
142
  } else {
142
143
  log.info(`Successfully deleted ${command} manifest at '${manifestPath}'`);
143
144
  }
@@ -168,9 +169,16 @@ async function setupDesktopAppDrivers(driverConfig: DriverConfig): Promise<void>
168
169
  /**
169
170
  * Install the given driver name. It skips the installation if the given driver name was already installed.
170
171
  */
171
- async function installDrivers(subcommand: CliCommandSetupSubcommand, driverConfig: DriverConfig): Promise<void> {
172
+ async function installDrivers(
173
+ subcommand: Exclude<CliCommandSetupSubcommand, 'reset'>,
174
+ driverConfig: DriverConfig,
175
+ ): Promise<void> {
172
176
  for (const driverName of getPresetDrivers(subcommand)) {
173
- await installExtension(driverName, extensionCommandArgs('driver', driverName, 'install'), driverConfig);
177
+ await installExtension(
178
+ driverName,
179
+ extensionCommandArgs('driver', driverName, 'install'),
180
+ driverConfig,
181
+ );
174
182
  }
175
183
  }
176
184
 
@@ -179,7 +187,11 @@ async function installDrivers(subcommand: CliCommandSetupSubcommand, driverConfi
179
187
  */
180
188
  async function setupDefaultPlugins(pluginConfig: PluginConfig): Promise<void> {
181
189
  for (const pluginName of DEFAULT_PLUGINS) {
182
- await installExtension(pluginName, extensionCommandArgs('plugin', pluginName, 'install'), pluginConfig);
190
+ await installExtension(
191
+ pluginName,
192
+ extensionCommandArgs('plugin', pluginName, 'install'),
193
+ pluginConfig,
194
+ );
183
195
  }
184
196
  }
185
197
 
@@ -189,11 +201,13 @@ async function setupDefaultPlugins(pluginConfig: PluginConfig): Promise<void> {
189
201
  async function installExtension(
190
202
  extensionName: string,
191
203
  extensionConfigArgs: CliExtArgs,
192
- extensionConfig: DriverConfig | PluginConfig
204
+ extensionConfig: DriverConfig | PluginConfig,
193
205
  ): Promise<void> {
194
- if (_.keys(extensionConfig.installedExtensions).includes(extensionName)) {
195
- log.info(`${extensionName} (${extensionConfig.installedExtensions[extensionName].version}) is already installed. ` +
196
- `Skipping the installation.`);
206
+ if (Object.keys(extensionConfig.installedExtensions).includes(extensionName)) {
207
+ log.info(
208
+ `${extensionName} (${extensionConfig.installedExtensions[extensionName].version}) is already installed. ` +
209
+ `Skipping the installation.`,
210
+ );
197
211
  return;
198
212
  }
199
213
  await runExtensionCommand(extensionConfigArgs, extensionConfig);
@@ -205,11 +219,13 @@ async function installExtension(
205
219
  async function uninstallExtension(
206
220
  extensionName: string,
207
221
  extensionConfigArgs: CliExtArgs,
208
- extensionConfig: DriverConfig | PluginConfig
222
+ extensionConfig: DriverConfig | PluginConfig,
209
223
  ): Promise<void> {
210
- if (!_.keys(extensionConfig.installedExtensions).includes(extensionName)) {
211
- log.info(`${extensionName} (${extensionConfig.installedExtensions[extensionName].version}) is not installed. ` +
212
- `Skipping its uninstall.`);
224
+ if (!Object.keys(extensionConfig.installedExtensions).includes(extensionName)) {
225
+ log.info(
226
+ `${extensionName} (${extensionConfig.installedExtensions[extensionName].version}) is not installed. ` +
227
+ `Skipping its uninstall.`,
228
+ );
213
229
  return;
214
230
  }
215
231
  await runExtensionCommand(extensionConfigArgs, extensionConfig);
@@ -221,10 +237,9 @@ async function uninstallExtension(
221
237
  function extensionCommandArgs(
222
238
  extensionCommand: CliExtensionCommand,
223
239
  extensionName: string,
224
- command: CliExtensionSubcommand
240
+ command: CliExtensionSubcommand,
225
241
  ): CliExtArgs {
226
- return (extensionCommand === 'plugin')
227
- ? {'subcommand': 'plugin', 'pluginCommand': command, 'plugin': extensionName}
228
- : {'subcommand': 'driver', 'driverCommand': command, 'driver': extensionName};
242
+ return extensionCommand === 'plugin'
243
+ ? {subcommand: 'plugin', pluginCommand: command, plugin: extensionName}
244
+ : {subcommand: 'driver', driverCommand: command, driver: extensionName};
229
245
  }
230
-
package/lib/cli/utils.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable no-console */
2
2
 
3
+ import {console as supportConsole} from '@appium/support';
3
4
  import ora from 'ora';
4
5
 
5
6
  export const JSON_SPACES = 4;
@@ -49,9 +50,9 @@ export function errAndQuit(json: boolean, msg: unknown): never {
49
50
  if (json) {
50
51
  console.log(JSON.stringify({error: String(msg)}, null, JSON_SPACES));
51
52
  } else {
52
- console.error((String(msg) as any).red);
53
+ console.error(supportConsole.styleText('red', String(msg)));
53
54
  if ((msg as ErrorLike)?.stderr) {
54
- console.error((String((msg as ErrorLike).stderr) as any).red);
55
+ console.error(supportConsole.styleText('red', String((msg as ErrorLike).stderr)));
55
56
  }
56
57
  }
57
58
  process.exit(1);
@@ -80,7 +81,7 @@ export function log(json: boolean, msg: string): void {
80
81
  export async function spinWith<T>(
81
82
  json: boolean,
82
83
  msg: string,
83
- fn: () => T | Promise<T>
84
+ fn: () => T | Promise<T>,
84
85
  ): Promise<T> {
85
86
  if (json) {
86
87
  return await fn();
@@ -1,6 +1,4 @@
1
- import '@colors/colors';
2
- import _ from 'lodash';
3
- import {util, doctor, logger} from '@appium/support';
1
+ import {console, doctor, logger, util} from '@appium/support';
4
2
  import type {AppiumLogger, DoctorCheckResult, IDoctorCheck} from '@appium/types';
5
3
 
6
4
  /**
@@ -35,7 +33,7 @@ export class Doctor {
35
33
  this.log = logger.getLogger('Doctor');
36
34
  this.checks = checks;
37
35
  this.checks
38
- .filter((c) => _.isNil(c.log))
36
+ .filter((c) => !util.hasValue(c.log))
39
37
  .forEach((c) => {
40
38
  c.log = this.log;
41
39
  });
@@ -88,11 +86,11 @@ export class Doctor {
88
86
  }
89
87
 
90
88
  private async reportManualIssues(): Promise<boolean> {
91
- const manualIssues = _.filter(this.issuesRequiredToFix, (f) => !f.check.hasAutofix());
92
- const manualIssuesOptional = _.filter(this.issuesOptionalToFix, (f) => !f.check.hasAutofix());
89
+ const manualIssues = this.issuesRequiredToFix.filter((f) => !f.check.hasAutofix());
90
+ const manualIssuesOptional = this.issuesOptionalToFix.filter((f) => !f.check.hasAutofix());
93
91
 
94
92
  const handleIssues = async (headerLogs: string[], issues: DoctorIssue[]): Promise<void> => {
95
- if (_.isEmpty(issues)) {
93
+ if (util.isEmpty(issues)) {
96
94
  return;
97
95
  }
98
96
 
@@ -111,7 +109,7 @@ export class Doctor {
111
109
  fixMessages.push(message);
112
110
  }
113
111
  }
114
- for (const m of _.uniq(fixMessages)) {
112
+ for (const m of util.uniq(fixMessages)) {
115
113
  this.log.warn(` \u279C ${m}`);
116
114
  }
117
115
  this.log.info('');
@@ -122,14 +120,14 @@ export class Doctor {
122
120
  '### Manual Fixes Needed ###',
123
121
  'The configuration cannot be automatically fixed, please do the following first:',
124
122
  ],
125
- manualIssues
123
+ manualIssues,
126
124
  );
127
125
  await handleIssues(
128
126
  [
129
127
  '### Optional Manual Fixes ###',
130
128
  'To fix these optional issues, please do the following manually:',
131
129
  ],
132
- manualIssuesOptional
130
+ manualIssuesOptional,
133
131
  );
134
132
 
135
133
  if (manualIssues.length > 0) {
@@ -160,21 +158,21 @@ export class Doctor {
160
158
  const res = await f.check.diagnose();
161
159
  if (res.ok) {
162
160
  f.fixed = true;
163
- this.log.info(` ${'\u2714'.green} ${res.message}`);
161
+ this.log.info(` ${console.styleText('green', '\u2714')} ${res.message}`);
164
162
  this.log.info(`### Fix was successfully applied ###`);
165
163
  } else {
166
- this.log.info(` ${'\u2716'.red} ${res.message}`);
164
+ this.log.info(` ${console.styleText('red', '\u2716')} ${res.message}`);
167
165
  this.log.info(`### Fix was applied but issue remains ###`);
168
166
  }
169
167
  }
170
168
 
171
169
  private async runAutoFixes(): Promise<boolean> {
172
- const autoFixes = _.filter(this.foundIssues, (f) => f.check.hasAutofix());
170
+ const autoFixes = this.foundIssues.filter((f) => f.check.hasAutofix());
173
171
  for (const f of autoFixes) {
174
172
  await this.runAutoFix(f);
175
173
  this.log.info('');
176
174
  }
177
- if (_.find(autoFixes, (f) => !f.fixed)) {
175
+ if (autoFixes.find((f) => !f.fixed)) {
178
176
  // a few issues remain.
179
177
  this.log.info('Bye! A few issues remain, fix manually and/or rerun doctor!');
180
178
  this.log.info('');
@@ -188,13 +186,13 @@ export class Doctor {
188
186
 
189
187
  private toIssue(result: DoctorCheckResult, check: IDoctorCheck): DoctorIssue | null {
190
188
  if (result.ok) {
191
- this.log.info(` ${'\u2714'.green} ${result.message}`);
189
+ this.log.info(` ${console.styleText('green', '\u2714')} ${result.message}`);
192
190
  return null;
193
191
  }
194
192
 
195
193
  const errorMessage = result.optional
196
- ? ` ${'\u2716'.yellow} ${result.message}`
197
- : ` ${'\u2716'.red} ${result.message}`;
194
+ ? ` ${console.styleText('yellow', '\u2716')} ${result.message}`
195
+ : ` ${console.styleText('red', '\u2716')} ${result.message}`;
198
196
  this.log.warn(errorMessage);
199
197
  return {
200
198
  error: errorMessage,
@@ -1,4 +1,4 @@
1
- import _ from 'lodash';
1
+ import {util} from '@appium/support';
2
2
  import type {DriverClass, DriverType, StringRecord} from '@appium/types';
3
3
  import type {ExtManifest, ExtName, ExtRecord} from 'appium/types';
4
4
  import {DRIVER_TYPE} from '../constants';
@@ -25,7 +25,7 @@ export class DriverConfig extends ExtensionConfig<DriverType> {
25
25
  const instance = new DriverConfig(manifest);
26
26
  if (DriverConfig.getInstance(manifest)) {
27
27
  throw new Error(
28
- `Manifest with APPIUM_HOME ${manifest.appiumHome} already has a DriverConfig; use DriverConfig.getInstance() to retrieve it.`
28
+ `Manifest with APPIUM_HOME ${manifest.appiumHome} already has a DriverConfig; use DriverConfig.getInstance() to retrieve it.`,
29
29
  );
30
30
  }
31
31
  DriverConfig._instances.set(manifest, instance);
@@ -43,7 +43,7 @@ export class DriverConfig extends ExtensionConfig<DriverType> {
43
43
 
44
44
  public override extensionDesc(
45
45
  driverName: ExtName<DriverType>,
46
- {version, automationName}: ExtManifest<DriverType>
46
+ {version, automationName}: ExtManifest<DriverType>,
47
47
  ): string {
48
48
  return `${String(driverName)}@${version} (automationName '${automationName}')`;
49
49
  }
@@ -52,27 +52,30 @@ export class DriverConfig extends ExtensionConfig<DriverType> {
52
52
  automationName,
53
53
  platformName,
54
54
  }: C): Promise<MatchedDriver> {
55
- if (!_.isString(platformName)) {
55
+ if (typeof platformName !== 'string') {
56
56
  throw new Error('You must include a platformName capability');
57
57
  }
58
58
 
59
- if (!_.isString(automationName)) {
59
+ if (typeof automationName !== 'string') {
60
60
  throw new Error('You must include an automationName capability');
61
61
  }
62
62
 
63
63
  log.info(
64
64
  `Attempting to find matching driver for automationName ` +
65
- `'${automationName}' and platformName '${platformName}'`
65
+ `'${automationName}' and platformName '${platformName}'`,
66
66
  );
67
67
 
68
68
  try {
69
- const {driverName, mainClass, version} = this._getDriverBySupport(automationName, platformName);
69
+ const {driverName, mainClass, version} = this._getDriverBySupport(
70
+ automationName,
71
+ platformName,
72
+ );
70
73
  log.info(`The '${driverName}' driver was installed and matched caps.`);
71
74
  log.info(`Will require it at ${this.getInstallPath(driverName)}`);
72
75
  const driver = await this.requireAsync(driverName as ExtName<DriverType>);
73
76
  if (!driver) {
74
77
  throw new Error(
75
- `Driver '${driverName}' did not export a class with name '${mainClass}'. Contact the author of the driver!`
78
+ `Driver '${driverName}' did not export a class with name '${mainClass}'. Contact the author of the driver!`,
76
79
  );
77
80
  }
78
81
  return {driver, version, driverName};
@@ -89,25 +92,25 @@ export class DriverConfig extends ExtensionConfig<DriverType> {
89
92
 
90
93
  protected override getConfigProblems(
91
94
  extManifest: ExtManifest<DriverType>,
92
- extName: string
95
+ extName: string,
93
96
  ): ExtManifestProblem[] {
94
97
  void extName;
95
98
  const problems: ExtManifestProblem[] = [];
96
99
  const {platformNames, automationName} = extManifest;
97
100
 
98
- if (!_.isArray(platformNames)) {
101
+ if (!Array.isArray(platformNames)) {
99
102
  problems.push({
100
103
  err: 'Missing or incorrect supported platformNames list.',
101
104
  val: platformNames,
102
105
  });
103
- } else if (_.isEmpty(platformNames)) {
106
+ } else if (util.isEmpty(platformNames)) {
104
107
  problems.push({
105
108
  err: 'Empty platformNames list.',
106
109
  val: platformNames,
107
110
  });
108
111
  } else {
109
112
  for (const pName of platformNames) {
110
- if (!_.isString(pName)) {
113
+ if (typeof pName !== 'string') {
111
114
  problems.push({
112
115
  err: 'Incorrectly formatted platformName.',
113
116
  val: pName,
@@ -116,7 +119,7 @@ export class DriverConfig extends ExtensionConfig<DriverType> {
116
119
  }
117
120
  }
118
121
 
119
- if (!_.isString(automationName)) {
122
+ if (typeof automationName !== 'string') {
120
123
  problems.push({
121
124
  err: 'Missing or incorrect automationName',
122
125
  val: automationName,
@@ -137,13 +140,15 @@ export class DriverConfig extends ExtensionConfig<DriverType> {
137
140
 
138
141
  private _getDriverBySupport(
139
142
  matchAutomationName: string,
140
- matchPlatformName: string
143
+ matchPlatformName: string,
141
144
  ): ExtManifest<DriverType> & {driverName: string} {
142
145
  const drivers = this.installedExtensions;
143
- for (const [driverName, driverData] of _.toPairs(drivers)) {
146
+ for (const [driverName, driverData] of Object.entries(drivers)) {
144
147
  const {automationName, platformNames} = driverData;
145
148
  const aNameMatches = automationName.toLowerCase() === matchAutomationName.toLowerCase();
146
- const pNameMatches = _.includes(platformNames.map((p) => _.toLower(p)), matchPlatformName.toLowerCase());
149
+ const pNameMatches = platformNames
150
+ .map((p) => p.toLowerCase())
151
+ .includes(matchPlatformName.toLowerCase());
147
152
 
148
153
  if (aNameMatches && pNameMatches) {
149
154
  return {driverName, ...driverData};
@@ -155,7 +160,7 @@ export class DriverConfig extends ExtensionConfig<DriverType> {
155
160
  `'${automationName}', but Appium could not find ` +
156
161
  `support for platformName '${matchPlatformName}'. Supported ` +
157
162
  `platformNames are: ` +
158
- JSON.stringify(platformNames)
163
+ JSON.stringify(platformNames),
159
164
  );
160
165
  }
161
166
  }