appium 3.5.0 → 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.
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +43 -45
- package/build/lib/appium.js.map +1 -1
- package/build/lib/bidi-commands.d.ts.map +1 -1
- package/build/lib/bidi-commands.js +34 -29
- package/build/lib/bidi-commands.js.map +1 -1
- package/build/lib/bootstrap/appium-initializer.d.ts.map +1 -1
- package/build/lib/bootstrap/appium-initializer.js +13 -13
- package/build/lib/bootstrap/appium-initializer.js.map +1 -1
- package/build/lib/bootstrap/appium-main-runner.d.ts.map +1 -1
- package/build/lib/bootstrap/appium-main-runner.js +2 -2
- package/build/lib/bootstrap/appium-main-runner.js.map +1 -1
- package/build/lib/bootstrap/config-file.d.ts.map +1 -1
- package/build/lib/bootstrap/config-file.js +11 -11
- package/build/lib/bootstrap/config-file.js.map +1 -1
- package/build/lib/bootstrap/grid-v3-register.d.ts.map +1 -1
- package/build/lib/bootstrap/grid-v3-register.js +9 -6
- package/build/lib/bootstrap/grid-v3-register.js.map +1 -1
- package/build/lib/bootstrap/main-helpers.d.ts +1 -1
- package/build/lib/bootstrap/main-helpers.d.ts.map +1 -1
- package/build/lib/bootstrap/main-helpers.js +19 -20
- package/build/lib/bootstrap/main-helpers.js.map +1 -1
- package/build/lib/bootstrap/node-helpers.d.ts +1 -1
- package/build/lib/bootstrap/node-helpers.d.ts.map +1 -1
- package/build/lib/bootstrap/node-helpers.js +7 -14
- package/build/lib/bootstrap/node-helpers.js.map +1 -1
- package/build/lib/bootstrap/startup-config.d.ts.map +1 -1
- package/build/lib/bootstrap/startup-config.js +32 -30
- package/build/lib/bootstrap/startup-config.js.map +1 -1
- package/build/lib/cli/args.d.ts +3 -2
- package/build/lib/cli/args.d.ts.map +1 -1
- package/build/lib/cli/args.js +2 -5
- package/build/lib/cli/args.js.map +1 -1
- package/build/lib/cli/driver-command.d.ts +1 -2
- package/build/lib/cli/driver-command.d.ts.map +1 -1
- package/build/lib/cli/driver-command.js +7 -8
- package/build/lib/cli/driver-command.js.map +1 -1
- package/build/lib/cli/extension-command.d.ts +2 -2
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +100 -66
- package/build/lib/cli/extension-command.js.map +1 -1
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js.map +1 -1
- package/build/lib/cli/parser.d.ts.map +1 -1
- package/build/lib/cli/parser.js +21 -14
- package/build/lib/cli/parser.js.map +1 -1
- package/build/lib/cli/plugin-command.d.ts +1 -1
- package/build/lib/cli/plugin-command.d.ts.map +1 -1
- package/build/lib/cli/plugin-command.js +5 -5
- package/build/lib/cli/plugin-command.js.map +1 -1
- package/build/lib/cli/setup-command.d.ts +1 -1
- package/build/lib/cli/setup-command.d.ts.map +1 -1
- package/build/lib/cli/setup-command.js +14 -19
- package/build/lib/cli/setup-command.js.map +1 -1
- package/build/lib/cli/utils.d.ts.map +1 -1
- package/build/lib/cli/utils.js +3 -2
- package/build/lib/cli/utils.js.map +1 -1
- package/build/lib/doctor/doctor.d.ts +0 -1
- package/build/lib/doctor/doctor.d.ts.map +1 -1
- package/build/lib/doctor/doctor.js +12 -17
- package/build/lib/doctor/doctor.js.map +1 -1
- package/build/lib/extension/driver-config.d.ts.map +1 -1
- package/build/lib/extension/driver-config.js +11 -12
- package/build/lib/extension/driver-config.js.map +1 -1
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +28 -27
- package/build/lib/extension/extension-config.js.map +1 -1
- package/build/lib/extension/index.d.ts.map +1 -1
- package/build/lib/extension/index.js +13 -16
- package/build/lib/extension/index.js.map +1 -1
- package/build/lib/extension/manifest.d.ts +3 -2
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +19 -22
- package/build/lib/extension/manifest.js.map +1 -1
- package/build/lib/extension/plugin-config.d.ts.map +1 -1
- package/build/lib/extension/plugin-config.js +7 -9
- package/build/lib/extension/plugin-config.js.map +1 -1
- package/build/lib/helpers/build.d.ts +0 -1
- package/build/lib/helpers/build.d.ts.map +1 -1
- package/build/lib/helpers/build.js +2 -4
- package/build/lib/helpers/build.js.map +1 -1
- package/build/lib/helpers/capability.d.ts.map +1 -1
- package/build/lib/helpers/capability.js +27 -22
- package/build/lib/helpers/capability.js.map +1 -1
- package/build/lib/helpers/network.d.ts.map +1 -1
- package/build/lib/helpers/network.js +4 -3
- package/build/lib/helpers/network.js.map +1 -1
- package/build/lib/insecure-features.d.ts.map +1 -1
- package/build/lib/insecure-features.js +9 -13
- package/build/lib/insecure-features.js.map +1 -1
- package/build/lib/inspector-commands.d.ts.map +1 -1
- package/build/lib/inspector-commands.js +29 -28
- package/build/lib/inspector-commands.js.map +1 -1
- package/build/lib/logsink.d.ts.map +1 -1
- package/build/lib/logsink.js +8 -7
- package/build/lib/logsink.js.map +1 -1
- package/build/lib/schema/arg-spec.d.ts.map +1 -1
- package/build/lib/schema/arg-spec.js +5 -8
- package/build/lib/schema/arg-spec.js.map +1 -1
- package/build/lib/schema/cli-args.d.ts.map +1 -1
- package/build/lib/schema/cli-args.js +20 -19
- package/build/lib/schema/cli-args.js.map +1 -1
- package/build/lib/schema/cli-transformers.d.ts.map +1 -1
- package/build/lib/schema/cli-transformers.js.map +1 -1
- package/build/lib/schema/schema.d.ts.map +1 -1
- package/build/lib/schema/schema.js +28 -21
- package/build/lib/schema/schema.js.map +1 -1
- package/build/lib/utils/hash.d.ts +5 -0
- package/build/lib/utils/hash.d.ts.map +1 -0
- package/build/lib/{utils.js → utils/hash.js} +3 -21
- package/build/lib/utils/hash.js.map +1 -0
- package/build/lib/utils/index.d.ts +8 -0
- package/build/lib/utils/index.d.ts.map +1 -0
- package/build/lib/utils/index.js +31 -0
- package/build/lib/utils/index.js.map +1 -0
- package/build/lib/utils/is-package-changed.d.ts +16 -0
- package/build/lib/utils/is-package-changed.d.ts.map +1 -0
- package/build/lib/utils/is-package-changed.js +62 -0
- package/build/lib/utils/is-package-changed.js.map +1 -0
- package/build/lib/utils/object.d.ts +120 -0
- package/build/lib/utils/object.d.ts.map +1 -0
- package/build/lib/utils/object.js +288 -0
- package/build/lib/utils/object.js.map +1 -0
- package/build/lib/{extension → utils}/package-changed.d.ts +0 -1
- package/build/lib/utils/package-changed.d.ts.map +1 -0
- package/build/lib/{extension → utils}/package-changed.js +3 -4
- package/build/lib/utils/package-changed.js.map +1 -0
- package/build/lib/utils/package-json.d.ts +9 -0
- package/build/lib/utils/package-json.d.ts.map +1 -0
- package/build/lib/utils/package-json.js +32 -0
- package/build/lib/utils/package-json.js.map +1 -0
- package/build/lib/utils/resolve-from.d.ts +11 -0
- package/build/lib/utils/resolve-from.d.ts.map +1 -0
- package/build/lib/utils/resolve-from.js +41 -0
- package/build/lib/utils/resolve-from.js.map +1 -0
- package/build/types/cli.d.ts.map +1 -1
- package/build/types/index.d.ts.map +1 -1
- package/build/types/manifest/base.d.ts.map +1 -1
- package/build/types/manifest/v3.d.ts.map +1 -1
- package/build/types/manifest/v4.d.ts.map +1 -1
- package/lib/appium.ts +59 -55
- package/lib/bidi-commands.ts +106 -60
- package/lib/bootstrap/appium-initializer.ts +27 -19
- package/lib/bootstrap/appium-main-runner.ts +8 -4
- package/lib/bootstrap/config-file.ts +33 -16
- package/lib/bootstrap/grid-v3-register.ts +26 -19
- package/lib/bootstrap/main-helpers.ts +25 -19
- package/lib/bootstrap/node-helpers.ts +19 -22
- package/lib/bootstrap/startup-config.ts +42 -39
- package/lib/cli/args.ts +3 -4
- package/lib/cli/driver-command.ts +19 -13
- package/lib/cli/extension-command.ts +208 -143
- package/lib/cli/extension.ts +4 -6
- package/lib/cli/parser.ts +32 -30
- package/lib/cli/plugin-command.ts +20 -9
- package/lib/cli/setup-command.ts +54 -39
- package/lib/cli/utils.ts +4 -3
- package/lib/doctor/doctor.ts +15 -17
- package/lib/extension/driver-config.ts +22 -17
- package/lib/extension/extension-config.ts +74 -66
- package/lib/extension/index.ts +42 -25
- package/lib/extension/manifest.ts +34 -31
- package/lib/extension/plugin-config.ts +15 -10
- package/lib/helpers/build.ts +6 -5
- package/lib/helpers/capability.ts +40 -35
- package/lib/helpers/network.ts +6 -5
- package/lib/insecure-features.ts +16 -14
- package/lib/inspector-commands.ts +72 -40
- package/lib/logsink.ts +22 -26
- package/lib/schema/arg-spec.ts +9 -8
- package/lib/schema/cli-args-guards.ts +4 -4
- package/lib/schema/cli-args.ts +25 -21
- package/lib/schema/cli-transformers.ts +6 -2
- package/lib/schema/format-errors.ts +1 -1
- package/lib/schema/schema.ts +52 -38
- package/lib/{utils.ts → utils/hash.ts} +2 -19
- package/lib/utils/index.ts +23 -0
- package/lib/utils/is-package-changed.ts +78 -0
- package/lib/utils/object.ts +312 -0
- package/lib/{extension → utils}/package-changed.ts +6 -7
- package/lib/utils/package-json.ts +36 -0
- package/lib/utils/resolve-from.ts +40 -0
- package/package.json +13 -16
- package/scripts/autoinstall-extensions.js +8 -8
- package/tsconfig.json +8 -2
- package/types/cli.ts +18 -18
- package/types/index.ts +2 -2
- package/types/manifest/base.ts +2 -2
- package/types/manifest/v3.ts +2 -2
- package/types/manifest/v4.ts +2 -2
- package/build/lib/extension/package-changed.d.ts.map +0 -1
- package/build/lib/extension/package-changed.js.map +0 -1
- package/build/lib/utils.d.ts +0 -13
- package/build/lib/utils.d.ts.map +0 -1
- package/build/lib/utils.js.map +0 -1
package/lib/cli/extension.ts
CHANGED
|
@@ -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
|
-
|
|
14
|
-
|
|
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 {
|
|
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([
|
|
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 =
|
|
135
|
-
|
|
136
|
-
(
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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: ${
|
|
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: ${
|
|
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: ${
|
|
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
|
|
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({
|
|
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
|
|
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(
|
|
105
|
-
|
|
106
|
-
|
|
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 (!
|
|
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
|
}
|
package/lib/cli/setup-command.ts
CHANGED
|
@@ -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 {
|
|
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:
|
|
33
|
-
desktop:
|
|
34
|
-
browser:
|
|
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(
|
|
53
|
-
|
|
54
|
-
|
|
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 (
|
|
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(
|
|
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
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
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(
|
|
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 (
|
|
195
|
-
log.info(
|
|
196
|
-
`
|
|
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 (!
|
|
211
|
-
log.info(
|
|
212
|
-
`
|
|
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
|
|
227
|
-
? {
|
|
228
|
-
: {
|
|
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)
|
|
53
|
+
console.error(supportConsole.styleText('red', String(msg)));
|
|
53
54
|
if ((msg as ErrorLike)?.stderr) {
|
|
54
|
-
console.error((String((msg as ErrorLike).stderr)
|
|
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();
|
package/lib/doctor/doctor.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import '@
|
|
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) =>
|
|
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 =
|
|
92
|
-
const manualIssuesOptional =
|
|
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 (
|
|
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
|
|
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'
|
|
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'
|
|
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 =
|
|
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 (
|
|
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'
|
|
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'
|
|
197
|
-
: ` ${'\u2716'
|
|
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
|
|
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 (
|
|
55
|
+
if (typeof platformName !== 'string') {
|
|
56
56
|
throw new Error('You must include a platformName capability');
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
-
if (
|
|
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(
|
|
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 (!
|
|
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 (
|
|
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 (
|
|
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 (
|
|
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
|
|
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 =
|
|
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
|
}
|