appium 2.13.1 → 2.14.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 (45) hide show
  1. package/build/lib/appium.d.ts +4 -64
  2. package/build/lib/appium.d.ts.map +1 -1
  3. package/build/lib/appium.js +48 -316
  4. package/build/lib/appium.js.map +1 -1
  5. package/build/lib/bidi.d.ts +32 -0
  6. package/build/lib/bidi.d.ts.map +1 -0
  7. package/build/lib/bidi.js +348 -0
  8. package/build/lib/bidi.js.map +1 -0
  9. package/build/lib/cli/args.d.ts.map +1 -1
  10. package/build/lib/cli/args.js +21 -31
  11. package/build/lib/cli/args.js.map +1 -1
  12. package/build/lib/cli/extension-command.d.ts.map +1 -1
  13. package/build/lib/cli/extension-command.js +38 -5
  14. package/build/lib/cli/extension-command.js.map +1 -1
  15. package/build/lib/cli/parser.d.ts.map +1 -1
  16. package/build/lib/cli/parser.js +26 -15
  17. package/build/lib/cli/parser.js.map +1 -1
  18. package/build/lib/cli/utils.d.ts.map +1 -1
  19. package/build/lib/cli/utils.js +3 -1
  20. package/build/lib/cli/utils.js.map +1 -1
  21. package/build/lib/config.js +42 -9
  22. package/build/lib/config.js.map +1 -1
  23. package/build/lib/extension/extension-config.d.ts +7 -0
  24. package/build/lib/extension/extension-config.d.ts.map +1 -1
  25. package/build/lib/extension/extension-config.js +42 -11
  26. package/build/lib/extension/extension-config.js.map +1 -1
  27. package/build/lib/extension/manifest.js +2 -2
  28. package/build/lib/extension/manifest.js.map +1 -1
  29. package/build/lib/schema/schema.js +3 -3
  30. package/build/lib/schema/schema.js.map +1 -1
  31. package/build/lib/utils.js +1 -2
  32. package/build/lib/utils.js.map +1 -1
  33. package/lib/appium.js +18 -377
  34. package/lib/bidi.ts +436 -0
  35. package/lib/cli/args.js +22 -32
  36. package/lib/cli/extension-command.js +4 -4
  37. package/lib/cli/parser.js +33 -17
  38. package/lib/cli/utils.js +3 -1
  39. package/lib/config.js +7 -7
  40. package/lib/extension/extension-config.js +49 -11
  41. package/lib/extension/manifest.js +2 -2
  42. package/lib/schema/schema.js +2 -2
  43. package/lib/utils.js +2 -2
  44. package/package.json +11 -11
  45. package/scripts/autoinstall-extensions.js +5 -5
package/lib/cli/parser.js CHANGED
@@ -18,9 +18,11 @@ import {finalizeSchema, getArgSpec, hasArgSpec} from '../schema';
18
18
  import {rootDir} from '../config';
19
19
  import {getExtensionArgs, getServerArgs} from './args';
20
20
  import {
21
+ DEFAULT_PLUGINS,
21
22
  SUBCOMMAND_MOBILE,
22
23
  SUBCOMMAND_DESKTOP,
23
24
  SUBCOMMAND_BROWSER,
25
+ SUBCOMMAND_RESET,
24
26
  getPresetDrivers,
25
27
  determinePlatformName
26
28
  } from './setup-command';
@@ -53,7 +55,8 @@ class ArgParser {
53
55
  const parser = new ArgumentParser({
54
56
  add_help: true,
55
57
  description:
56
- 'A webdriver-compatible server that facilitates automation of web, mobile, and other types of apps across various platforms.',
58
+ 'A webdriver-compatible server that facilitates automation of web, mobile, and other ' +
59
+ 'types of apps across various platforms.',
57
60
  prog,
58
61
  });
59
62
 
@@ -84,9 +87,6 @@ class ArgParser {
84
87
 
85
88
  const subParsers = parser.add_subparsers({dest: 'subcommand'});
86
89
 
87
- // add the 'setup' command
88
- ArgParser._addSetupToParser(subParsers);
89
-
90
90
  // add the 'server' subcommand, and store the raw arguments on the parser
91
91
  // object as a way for other parts of the code to work with the arguments
92
92
  // conceptually rather than just through argparse
@@ -97,6 +97,9 @@ class ArgParser {
97
97
  // add the 'driver' and 'plugin' subcommands
98
98
  ArgParser._addExtensionCommandsToParser(subParsers);
99
99
 
100
+ // add the 'setup' command
101
+ ArgParser._addSetupToParser(subParsers);
102
+
100
103
  // backwards compatibility / drop-in wrapper
101
104
  /**
102
105
  * @type {ArgParser['parseArgs']}
@@ -205,7 +208,8 @@ class ArgParser {
205
208
  static _addServerToParser(subParser) {
206
209
  const serverParser = subParser.add_parser('server', {
207
210
  add_help: true,
208
- help: 'Run an Appium server',
211
+ help: 'Start an Appium server',
212
+ description: 'Start an Appium server (the "server" subcommand is optional)',
209
213
  });
210
214
 
211
215
  ArgParser._patchExit(serverParser);
@@ -227,7 +231,8 @@ class ArgParser {
227
231
  for (const type of /** @type {[DriverType, PluginType]} */ ([DRIVER_TYPE, PLUGIN_TYPE])) {
228
232
  const extParser = subParsers.add_parser(type, {
229
233
  add_help: true,
230
- help: `Access the ${type} management CLI commands`,
234
+ help: `Manage Appium ${type}s`,
235
+ description: `Manage Appium ${type}s using various subcommands`,
231
236
  });
232
237
 
233
238
  ArgParser._patchExit(extParser);
@@ -259,19 +264,17 @@ class ArgParser {
259
264
  {
260
265
  command: EXT_SUBCOMMAND_UPDATE,
261
266
  args: extensionArgs[type].update,
262
- help: `Update installed ${type}s to the latest version`,
267
+ help: `Update one or more installed ${type}s to the latest version`,
263
268
  },
264
269
  {
265
270
  command: EXT_SUBCOMMAND_RUN,
266
271
  args: extensionArgs[type].run,
267
- help:
268
- `Run a script (defined inside the ${type}'s package.json under the ` +
269
- `“scripts” field inside the “appium” field) from an installed ${type}`,
272
+ help: `Run a script (if available) from the given ${type}`,
270
273
  },
271
274
  {
272
275
  command: EXT_SUBCOMMAND_DOCTOR,
273
276
  args: extensionArgs[type].doctor,
274
- help: `Run doctor checks (if any defined) for the given ${type}`,
277
+ help: `Run doctor checks (if available) for the given ${type}`,
275
278
  },
276
279
  ];
277
280
 
@@ -299,9 +302,12 @@ class ArgParser {
299
302
  static _addSetupToParser(subParser) {
300
303
  const setupParser = subParser.add_parser('setup', {
301
304
  add_help: true,
302
- help: `Select a preset of official drivers/plugins to install ` +
303
- `compatible with '${determinePlatformName()}' host platform. ` +
304
- `Existing drivers/plugins will remain. The default preset is 'mobile'.`,
305
+ help: 'Batch install or uninstall Appium drivers and plugins',
306
+ description:
307
+ `Install a preset of official drivers/plugins compatible with the current host platform ` +
308
+ `(${determinePlatformName()}). Existing drivers/plugins will remain. The default preset ` +
309
+ `is "mobile". Providing the special "reset" subcommand will instead uninstall all ` +
310
+ `drivers and plugins, and remove their related manifest files.`,
305
311
  });
306
312
 
307
313
 
@@ -313,15 +319,25 @@ class ArgParser {
313
319
  const parserSpecs = [
314
320
  {
315
321
  command: SUBCOMMAND_MOBILE,
316
- help: `The preset for mobile devices: ${_.join(getPresetDrivers(SUBCOMMAND_MOBILE), ',')}`
322
+ help:
323
+ `The preset for mobile devices ` +
324
+ `(drivers: ${_.join(getPresetDrivers(SUBCOMMAND_MOBILE), ',')}; plugins: ${DEFAULT_PLUGINS})`
317
325
  },
318
326
  {
319
327
  command: SUBCOMMAND_BROWSER,
320
- help: `The preset for desktop browser drivers: ${_.join(getPresetDrivers(SUBCOMMAND_BROWSER), ',')}`
328
+ help:
329
+ `The preset for desktop browsers ` +
330
+ `(drivers: ${_.join(getPresetDrivers(SUBCOMMAND_BROWSER), ',')}; plugins: ${DEFAULT_PLUGINS})`
321
331
  },
322
332
  {
323
333
  command: SUBCOMMAND_DESKTOP,
324
- help: `The preset for desktop application drivers: ${_.join(getPresetDrivers(SUBCOMMAND_DESKTOP), ',')}`
334
+ help:
335
+ `The preset for desktop applications ` +
336
+ `(drivers: ${_.join(getPresetDrivers(SUBCOMMAND_DESKTOP), ',')}; plugins: ${DEFAULT_PLUGINS})`
337
+ },
338
+ {
339
+ command: SUBCOMMAND_RESET,
340
+ help: 'Remove all installed drivers and plugins'
325
341
  },
326
342
  ];
327
343
 
package/lib/cli/utils.js CHANGED
@@ -27,7 +27,9 @@ export function errAndQuit(json, msg) {
27
27
  * @param {string} msg - string to log
28
28
  */
29
29
  export function log(json, msg) {
30
- !json && console.log(msg);
30
+ if (!json) {
31
+ console.log(msg);
32
+ }
31
33
  }
32
34
 
33
35
  /**
package/lib/config.js CHANGED
@@ -3,7 +3,7 @@ import _ from 'lodash';
3
3
  import {system, fs, npm} from '@appium/support';
4
4
  import axios from 'axios';
5
5
  import {exec} from 'teen_process';
6
- import semver from 'semver';
6
+ import * as semver from 'semver';
7
7
  import os from 'node:os';
8
8
  import {npmPackage} from './utils';
9
9
  import B from 'bluebird';
@@ -115,7 +115,7 @@ export async function getGitRev(useGithubApiFallback = false) {
115
115
  cwd: __dirname,
116
116
  });
117
117
  return stdout.trim();
118
- } catch (ign) {}
118
+ } catch {}
119
119
  }
120
120
 
121
121
  if (!useGithubApiFallback) {
@@ -132,7 +132,7 @@ export async function getGitRev(useGithubApiFallback = false) {
132
132
  },
133
133
  })
134
134
  ).data?.object?.sha;
135
- } catch (ign) {}
135
+ } catch {}
136
136
  return null;
137
137
  }
138
138
 
@@ -149,7 +149,7 @@ async function getGitTimestamp(commitSha, useGithubApiFallback = false) {
149
149
  cwd: __dirname,
150
150
  });
151
151
  return stdout.trim();
152
- } catch (ign) {}
152
+ } catch {}
153
153
  }
154
154
 
155
155
  if (!useGithubApiFallback) {
@@ -164,7 +164,7 @@ async function getGitTimestamp(commitSha, useGithubApiFallback = false) {
164
164
  },
165
165
  })
166
166
  ).data?.tagger?.date;
167
- } catch (ign) {}
167
+ } catch {}
168
168
  return null;
169
169
  }
170
170
 
@@ -194,7 +194,7 @@ export function checkNodeOk() {
194
194
 
195
195
  export async function showBuildInfo() {
196
196
  await updateBuildInfo(true);
197
- console.log(JSON.stringify(getBuildInfo())); // eslint-disable-line no-console
197
+ console.log(JSON.stringify(getBuildInfo()));
198
198
  }
199
199
 
200
200
  /**
@@ -356,7 +356,7 @@ export async function requireDir(root, requireWriteable = true, displayName = 'f
356
356
  if (requireWriteable) {
357
357
  try {
358
358
  await fs.access(root, fs.constants.W_OK);
359
- } catch (e) {
359
+ } catch {
360
360
  throw new Error(
361
361
  `The ${displayName} '${root}' must be ` +
362
362
  `writeable for the current user account '${os.userInfo().username}'`
@@ -14,6 +14,7 @@ import {
14
14
  } from '../schema/schema';
15
15
  import { pathToFileURL } from 'url';
16
16
 
17
+ const DEFAULT_ENTRY_POINT = 'index.js';
17
18
  /**
18
19
  * "npm" install type
19
20
  * Used when extension was installed by npm package name
@@ -567,23 +568,39 @@ export class ExtensionConfig {
567
568
  const {mainClass} = this.installedExtensions[extName];
568
569
  const moduleRoot = this.getInstallPath(extName);
569
570
  const packageJsonPath = path.join(moduleRoot, 'package.json');
570
- let entryPointPath;
571
+ let extensionManifest;
571
572
  try {
572
- entryPointPath = JSON.parse(await fs.readFile(packageJsonPath, 'utf8')).main ?? 'index.js';
573
+ extensionManifest = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
573
574
  } catch (e) {
574
- throw new ReferenceError(`Could not find a ${this.extensionType} installed at ${moduleRoot}`);
575
+ throw new ReferenceError(
576
+ `Could not read the ${this.extensionType} manifest at ${packageJsonPath}: ${e.message}`
577
+ );
575
578
  }
576
- if (entryPointPath) {
577
- entryPointPath = path.resolve(moduleRoot, entryPointPath);
578
- } else {
579
- throw new ReferenceError(`Cannot find a valid ${this.extensionType} main entry point in '${packageJsonPath}'`);
579
+ /** @type {string | undefined} */
580
+ let entryPointRelativePath;
581
+ try {
582
+ if (extensionManifest.type === 'module' && extensionManifest.exports) {
583
+ entryPointRelativePath = resolveEsmEntryPoint(extensionManifest.exports);
584
+ }
585
+ entryPointRelativePath = entryPointRelativePath ?? extensionManifest.main ?? DEFAULT_ENTRY_POINT;
586
+ } catch (e) {
587
+ throw new ReferenceError(
588
+ `Could not find the ${this.extensionType} installed at ${moduleRoot}: ${e.message}`
589
+ );
590
+ }
591
+ const entryPointFullPath = path.resolve(moduleRoot, /** @type {string} */ (entryPointRelativePath));
592
+ if (!await fs.exists(entryPointFullPath)) {
593
+ throw new ReferenceError(
594
+ `Cannot find a valid ${this.extensionType} main entry point in '${packageJsonPath}'. ` +
595
+ `Assumed entry point: '${entryPointFullPath}'`
596
+ );
580
597
  }
581
598
  // note: this will only reload the entry point
582
- if (process.env.APPIUM_RELOAD_EXTENSIONS && require.cache[entryPointPath]) {
583
- log.debug(`Removing ${entryPointPath} from require cache`);
584
- delete require.cache[entryPointPath];
599
+ if (process.env.APPIUM_RELOAD_EXTENSIONS && require.cache[entryPointFullPath]) {
600
+ log.debug(`Removing ${entryPointFullPath} from require cache`);
601
+ delete require.cache[entryPointFullPath];
585
602
  }
586
- return [entryPointPath, mainClass];
603
+ return [entryPointFullPath, mainClass];
587
604
  }
588
605
 
589
606
  /**
@@ -672,6 +689,27 @@ export class ExtensionConfig {
672
689
  }
673
690
  }
674
691
 
692
+ /**
693
+ * https://nodejs.org/api/packages.html#package-entry-points
694
+ *
695
+ * @param {any} exportsValue
696
+ * @returns {string | undefined}
697
+ */
698
+ export function resolveEsmEntryPoint(exportsValue) {
699
+ if (_.isString(exportsValue) && exportsValue) {
700
+ return exportsValue;
701
+ }
702
+ if (!_.isPlainObject(exportsValue)) {
703
+ return;
704
+ }
705
+
706
+ for (const key of ['.', 'import']) {
707
+ if (exportsValue[key]) {
708
+ return resolveEsmEntryPoint(exportsValue[key]);
709
+ }
710
+ }
711
+ }
712
+
675
713
  /**
676
714
  * An issue with the {@linkcode ExtManifest} for a particular extension.
677
715
  *
@@ -242,8 +242,8 @@ export class Manifest {
242
242
  * @type {InternalMetadata}
243
243
  */
244
244
  const internal = {
245
- pkgName: pkgJson.name,
246
- version: pkgJson.version,
245
+ pkgName: /** @type {string} */ (pkgJson.name),
246
+ version: /** @type {string} */ (pkgJson.version),
247
247
  appiumVersion: pkgJson.peerDependencies?.appium,
248
248
  installType,
249
249
  installSpec: `${pkgJson.name}@${pkgJson.version}`,
@@ -1,4 +1,4 @@
1
- import Ajv from 'ajv';
1
+ import {Ajv} from 'ajv';
2
2
  import addFormats from 'ajv-formats';
3
3
  import _ from 'lodash';
4
4
  import path from 'path';
@@ -453,7 +453,7 @@ class AppiumSchema {
453
453
  let refSchema;
454
454
  try {
455
455
  refSchema = this.getSchema($ref);
456
- } catch (err) {
456
+ } catch {
457
457
  // this can happen if an extension schema supplies a $ref to a non-existent schema
458
458
  throw new SchemaUnknownSchemaError($ref);
459
459
  }
package/lib/utils.js CHANGED
@@ -247,10 +247,10 @@ export function adjustNodePath() {
247
247
  // ! so it could break (maybe, eventually).
248
248
  // See https://gist.github.com/branneman/8048520#7-the-hack
249
249
  // @ts-ignore see above comment
250
- // eslint-disable-next-line @typescript-eslint/no-var-requires
250
+
251
251
  require('module').Module._initPaths();
252
252
  return true;
253
- } catch (e) {
253
+ } catch {
254
254
  return false;
255
255
  }
256
256
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "appium",
3
- "version": "2.13.1",
3
+ "version": "2.14.1",
4
4
  "description": "Automation for Apps.",
5
5
  "keywords": [
6
6
  "automation",
@@ -60,13 +60,13 @@
60
60
  "test:unit": "mocha \"./test/unit/**/*.spec.js\""
61
61
  },
62
62
  "dependencies": {
63
- "@appium/base-driver": "^9.13.1",
64
- "@appium/base-plugin": "^2.2.50",
65
- "@appium/docutils": "^1.0.26",
63
+ "@appium/base-driver": "^9.14.1",
64
+ "@appium/base-plugin": "^2.2.52",
65
+ "@appium/docutils": "^1.0.28",
66
66
  "@appium/logger": "^1.6.1",
67
- "@appium/schema": "^0.7.0",
68
- "@appium/support": "^6.0.0",
69
- "@appium/types": "^0.22.3",
67
+ "@appium/schema": "^0.7.1",
68
+ "@appium/support": "^6.0.2",
69
+ "@appium/types": "^0.23.0",
70
70
  "@sidvind/better-ajv-errors": "3.0.1",
71
71
  "@types/argparse": "2.0.17",
72
72
  "@types/bluebird": "3.5.42",
@@ -89,12 +89,12 @@
89
89
  "resolve-from": "5.0.0",
90
90
  "semver": "7.6.3",
91
91
  "source-map-support": "0.5.21",
92
- "teen_process": "2.2.2",
93
- "type-fest": "4.30.0",
92
+ "teen_process": "2.2.3",
93
+ "type-fest": "4.31.0",
94
94
  "winston": "3.17.0",
95
95
  "wrap-ansi": "7.0.0",
96
96
  "ws": "8.18.0",
97
- "yaml": "2.6.1"
97
+ "yaml": "2.7.0"
98
98
  },
99
99
  "engines": {
100
100
  "node": "^14.17.0 || ^16.13.0 || >=18.0.0",
@@ -103,5 +103,5 @@
103
103
  "publishConfig": {
104
104
  "access": "public"
105
105
  },
106
- "gitHead": "1d16ac6b4521b1ac06b8650c6bb5c311d8d49ae3"
106
+ "gitHead": "3467f32c8e3618db05b6b210544cfdc6a57bb73c"
107
107
  }
@@ -85,10 +85,10 @@ async function init() {
85
85
  }
86
86
  try {
87
87
  ({env, util, logger} = require('@appium/support'));
88
- // @ts-ignore
88
+ // @ts-ignore This is OK
89
89
  ({runExtensionCommand} = require('../build/lib/cli/extension'));
90
90
  ({DRIVER_TYPE, PLUGIN_TYPE} = require('../build/lib/constants'));
91
- // @ts-ignore
91
+ // @ts-ignore This is OK
92
92
  ({loadExtensions} = require('../build/lib/extension'));
93
93
  logger.getLogger('Appium').level = 'error';
94
94
 
@@ -119,7 +119,7 @@ async function main() {
119
119
 
120
120
  if (!driverEnv && !pluginEnv) {
121
121
  spinner.succeed(
122
- wrap(`No drivers or plugins to automatically install.
122
+ wrap(`No drivers or plugins to automatically install.
123
123
  If desired, provide arguments with comma-separated values "--drivers=<known_driver>[,known_driver...]" and/or "--plugins=<known_plugin>[,known_plugin...]" to the "npm install appium" command. The specified extensions will be installed automatically with Appium. Note: to see the list of known extensions, run "appium <driver|plugin> list".`)
124
124
  );
125
125
  return;
@@ -193,7 +193,7 @@ async function checkAndInstallExtension({
193
193
  spinner,
194
194
  }) {
195
195
  const extList = await runExtensionCommand(
196
- // @ts-ignore
196
+ // @ts-ignore This is OK
197
197
  {
198
198
  appiumHome,
199
199
  subcommand: type,
@@ -209,7 +209,7 @@ async function checkAndInstallExtension({
209
209
  }
210
210
  spinner.start(`Installing ${type} "${ext}"...`);
211
211
  await runExtensionCommand(
212
- // @ts-ignore
212
+ // @ts-ignore this is OK
213
213
  {
214
214
  subcommand: type,
215
215
  appiumHome,