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