appium 2.0.0-beta.7 → 2.0.0-beta.71
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/LICENSE +1 -1
- package/README.md +149 -58
- package/build/lib/appium.d.ts +229 -0
- package/build/lib/appium.d.ts.map +1 -0
- package/build/lib/appium.js +678 -439
- package/build/lib/appium.js.map +1 -0
- package/build/lib/cli/args.d.ts +17 -0
- package/build/lib/cli/args.d.ts.map +1 -0
- package/build/lib/cli/args.js +263 -300
- package/build/lib/cli/args.js.map +1 -0
- package/build/lib/cli/driver-command.d.ts +102 -0
- package/build/lib/cli/driver-command.d.ts.map +1 -0
- package/build/lib/cli/driver-command.js +131 -81
- package/build/lib/cli/driver-command.js.map +1 -0
- package/build/lib/cli/extension-command.d.ts +402 -0
- package/build/lib/cli/extension-command.d.ts.map +1 -0
- package/build/lib/cli/extension-command.js +799 -383
- package/build/lib/cli/extension-command.js.map +1 -0
- package/build/lib/cli/extension.d.ts +23 -0
- package/build/lib/cli/extension.d.ts.map +1 -0
- package/build/lib/cli/extension.js +71 -60
- package/build/lib/cli/extension.js.map +1 -0
- package/build/lib/cli/parser.d.ts +84 -0
- package/build/lib/cli/parser.d.ts.map +1 -0
- package/build/lib/cli/parser.js +252 -148
- package/build/lib/cli/parser.js.map +1 -0
- package/build/lib/cli/plugin-command.d.ts +99 -0
- package/build/lib/cli/plugin-command.d.ts.map +1 -0
- package/build/lib/cli/plugin-command.js +125 -81
- package/build/lib/cli/plugin-command.js.map +1 -0
- package/build/lib/cli/utils.d.ts +29 -0
- package/build/lib/cli/utils.d.ts.map +1 -0
- package/build/lib/cli/utils.js +72 -51
- package/build/lib/cli/utils.js.map +1 -0
- package/build/lib/config-file.d.ts +100 -0
- package/build/lib/config-file.d.ts.map +1 -0
- package/build/lib/config-file.js +207 -0
- package/build/lib/config-file.js.map +1 -0
- package/build/lib/config.d.ts +49 -0
- package/build/lib/config.d.ts.map +1 -0
- package/build/lib/config.js +262 -223
- package/build/lib/config.js.map +1 -0
- package/build/lib/constants.d.ts +56 -0
- package/build/lib/constants.d.ts.map +1 -0
- package/build/lib/constants.js +73 -0
- package/build/lib/constants.js.map +1 -0
- package/build/lib/extension/driver-config.d.ts +82 -0
- package/build/lib/extension/driver-config.d.ts.map +1 -0
- package/build/lib/extension/driver-config.js +210 -0
- package/build/lib/extension/driver-config.js.map +1 -0
- package/build/lib/extension/extension-config.d.ts +270 -0
- package/build/lib/extension/extension-config.d.ts.map +1 -0
- package/build/lib/extension/extension-config.js +601 -0
- package/build/lib/extension/extension-config.js.map +1 -0
- package/build/lib/extension/index.d.ts +48 -0
- package/build/lib/extension/index.d.ts.map +1 -0
- package/build/lib/extension/index.js +105 -0
- package/build/lib/extension/index.js.map +1 -0
- package/build/lib/extension/manifest-migrations.d.ts +27 -0
- package/build/lib/extension/manifest-migrations.d.ts.map +1 -0
- package/build/lib/extension/manifest-migrations.js +134 -0
- package/build/lib/extension/manifest-migrations.js.map +1 -0
- package/build/lib/extension/manifest.d.ts +145 -0
- package/build/lib/extension/manifest.d.ts.map +1 -0
- package/build/lib/extension/manifest.js +528 -0
- package/build/lib/extension/manifest.js.map +1 -0
- package/build/lib/extension/package-changed.d.ts +11 -0
- package/build/lib/extension/package-changed.d.ts.map +1 -0
- package/build/lib/extension/package-changed.js +62 -0
- package/build/lib/extension/package-changed.js.map +1 -0
- package/build/lib/extension/plugin-config.d.ts +56 -0
- package/build/lib/extension/plugin-config.d.ts.map +1 -0
- package/build/lib/extension/plugin-config.js +102 -0
- package/build/lib/extension/plugin-config.js.map +1 -0
- package/build/lib/grid-register.d.ts +10 -0
- package/build/lib/grid-register.d.ts.map +1 -0
- package/build/lib/grid-register.js +122 -144
- package/build/lib/grid-register.js.map +1 -0
- package/build/lib/logger.d.ts +3 -0
- package/build/lib/logger.d.ts.map +1 -0
- package/build/lib/logger.js +5 -17
- package/build/lib/logger.js.map +1 -0
- package/build/lib/logsink.d.ts +4 -0
- package/build/lib/logsink.d.ts.map +1 -0
- package/build/lib/logsink.js +189 -184
- package/build/lib/logsink.js.map +1 -0
- package/build/lib/main.d.ts +62 -0
- package/build/lib/main.d.ts.map +1 -0
- package/build/lib/main.js +388 -234
- package/build/lib/main.js.map +1 -0
- package/build/lib/schema/arg-spec.d.ts +143 -0
- package/build/lib/schema/arg-spec.d.ts.map +1 -0
- package/build/lib/schema/arg-spec.js +164 -0
- package/build/lib/schema/arg-spec.js.map +1 -0
- package/build/lib/schema/cli-args.d.ts +19 -0
- package/build/lib/schema/cli-args.d.ts.map +1 -0
- package/build/lib/schema/cli-args.js +220 -0
- package/build/lib/schema/cli-args.js.map +1 -0
- package/build/lib/schema/cli-transformers.d.ts +5 -0
- package/build/lib/schema/cli-transformers.d.ts.map +1 -0
- package/build/lib/schema/cli-transformers.js +124 -0
- package/build/lib/schema/cli-transformers.js.map +1 -0
- package/build/lib/schema/index.d.ts +3 -0
- package/build/lib/schema/index.d.ts.map +1 -0
- package/build/lib/schema/index.js +19 -0
- package/build/lib/schema/index.js.map +1 -0
- package/build/lib/schema/keywords.d.ts +24 -0
- package/build/lib/schema/keywords.d.ts.map +1 -0
- package/build/lib/schema/keywords.js +128 -0
- package/build/lib/schema/keywords.js.map +1 -0
- package/build/lib/schema/schema.d.ts +260 -0
- package/build/lib/schema/schema.d.ts.map +1 -0
- package/build/lib/schema/schema.js +640 -0
- package/build/lib/schema/schema.js.map +1 -0
- package/build/lib/utils.d.ts +266 -0
- package/build/lib/utils.d.ts.map +1 -0
- package/build/lib/utils.js +349 -273
- package/build/lib/utils.js.map +1 -0
- package/build/types/cli.d.ts +134 -0
- package/build/types/cli.d.ts.map +1 -0
- package/build/types/cli.js +3 -0
- package/build/types/cli.js.map +1 -0
- package/build/types/index.d.ts +15 -0
- package/build/types/index.d.ts.map +1 -0
- package/build/types/index.js +19 -0
- package/build/types/index.js.map +1 -0
- package/build/types/manifest/base.d.ts +135 -0
- package/build/types/manifest/base.d.ts.map +1 -0
- package/build/types/manifest/base.js +3 -0
- package/build/types/manifest/base.js.map +1 -0
- package/build/types/manifest/index.d.ts +21 -0
- package/build/types/manifest/index.d.ts.map +1 -0
- package/build/types/manifest/index.js +42 -0
- package/build/types/manifest/index.js.map +1 -0
- package/build/types/manifest/v3.d.ts +139 -0
- package/build/types/manifest/v3.d.ts.map +1 -0
- package/build/types/manifest/v3.js +3 -0
- package/build/types/manifest/v3.js.map +1 -0
- package/build/types/manifest/v4.d.ts +139 -0
- package/build/types/manifest/v4.d.ts.map +1 -0
- package/build/types/manifest/v4.js +3 -0
- package/build/types/manifest/v4.js.map +1 -0
- package/driver.d.ts +1 -0
- package/driver.js +14 -0
- package/index.js +11 -0
- package/lib/appium.js +558 -186
- package/lib/cli/args.js +275 -407
- package/lib/cli/driver-command.js +132 -24
- package/lib/cli/extension-command.js +751 -272
- package/lib/cli/extension.js +47 -20
- package/lib/cli/parser.js +267 -95
- package/lib/cli/plugin-command.js +122 -22
- package/lib/cli/utils.js +24 -10
- package/lib/config-file.js +220 -0
- package/lib/config.js +243 -132
- package/lib/constants.js +79 -0
- package/lib/extension/driver-config.js +247 -0
- package/lib/extension/extension-config.js +709 -0
- package/lib/extension/index.js +116 -0
- package/lib/extension/manifest-migrations.js +136 -0
- package/lib/extension/manifest.js +580 -0
- package/lib/extension/package-changed.js +64 -0
- package/lib/extension/plugin-config.js +112 -0
- package/lib/grid-register.js +49 -35
- package/lib/logger.js +1 -2
- package/lib/logsink.js +59 -36
- package/lib/main.js +369 -104
- package/lib/schema/arg-spec.js +229 -0
- package/lib/schema/cli-args.js +241 -0
- package/lib/schema/cli-transformers.js +119 -0
- package/lib/schema/index.js +2 -0
- package/lib/schema/keywords.js +136 -0
- package/lib/schema/schema.js +725 -0
- package/lib/utils.js +289 -167
- package/package.json +84 -83
- package/plugin.d.ts +1 -0
- package/plugin.js +13 -0
- package/scripts/autoinstall-extensions.js +243 -0
- package/support.d.ts +1 -0
- package/support.js +13 -0
- package/tsconfig.json +25 -0
- package/types/cli.ts +193 -0
- package/types/index.ts +20 -0
- package/types/manifest/README.md +30 -0
- package/types/manifest/base.ts +158 -0
- package/types/manifest/index.ts +28 -0
- package/types/manifest/v3.ts +161 -0
- package/types/manifest/v4.ts +161 -0
- package/CHANGELOG.md +0 -3594
- package/bin/ios-webkit-debug-proxy-launcher.js +0 -71
- package/build/lib/cli/argparse-actions.js +0 -104
- package/build/lib/cli/npm.js +0 -200
- package/build/lib/cli/parser-helpers.js +0 -93
- package/build/lib/driver-config.js +0 -77
- package/build/lib/drivers.js +0 -99
- package/build/lib/extension-config.js +0 -253
- package/build/lib/plugin-config.js +0 -59
- package/build/lib/plugins.js +0 -14
- package/lib/cli/argparse-actions.js +0 -77
- package/lib/cli/npm.js +0 -175
- package/lib/cli/parser-helpers.js +0 -91
- package/lib/driver-config.js +0 -46
- package/lib/drivers.js +0 -84
- package/lib/extension-config.js +0 -209
- package/lib/plugin-config.js +0 -34
- package/lib/plugins.js +0 -10
package/lib/cli/npm.js
DELETED
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import path from 'path';
|
|
2
|
-
import semver from 'semver';
|
|
3
|
-
import { exec } from 'teen_process';
|
|
4
|
-
import { mkdirp, util, system } from 'appium-support';
|
|
5
|
-
|
|
6
|
-
const INSTALL_LOCKFILE = '.appium.install.lock';
|
|
7
|
-
const LINK_LOCKFILE = '.appium.link.lock';
|
|
8
|
-
|
|
9
|
-
export default class NPM {
|
|
10
|
-
|
|
11
|
-
constructor (appiumHome) {
|
|
12
|
-
this.appiumHome = appiumHome;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
async exec (cmd, args, opts, execOpts = {}) {
|
|
16
|
-
let { cwd, json, lockFile } = opts;
|
|
17
|
-
if (!cwd) {
|
|
18
|
-
cwd = this.appiumHome;
|
|
19
|
-
}
|
|
20
|
-
// ensure the directory we want to install inside of exists
|
|
21
|
-
await mkdirp(cwd);
|
|
22
|
-
|
|
23
|
-
// make sure we perform the current operation in cwd
|
|
24
|
-
execOpts = {...execOpts, cwd};
|
|
25
|
-
|
|
26
|
-
args.unshift(cmd);
|
|
27
|
-
if (json) {
|
|
28
|
-
args.push('-json');
|
|
29
|
-
}
|
|
30
|
-
const npmCmd = system.isWindows() ? 'npm.cmd' : 'npm';
|
|
31
|
-
let runner = async () => await exec(npmCmd, args, execOpts);
|
|
32
|
-
if (lockFile) {
|
|
33
|
-
const acquireLock = util.getLockFileGuard(path.resolve(cwd, lockFile));
|
|
34
|
-
const _runner = runner;
|
|
35
|
-
runner = async () => await acquireLock(_runner);
|
|
36
|
-
}
|
|
37
|
-
const {stdout, stderr, code} = await runner();
|
|
38
|
-
const ret = {stdout, stderr, code, json: null};
|
|
39
|
-
|
|
40
|
-
if (json) {
|
|
41
|
-
// if possible, parse NPM's json output. During NPM install 3rd-party
|
|
42
|
-
// packages can write to stdout, so sometimes the json output can't be
|
|
43
|
-
// guaranteed to be parseable
|
|
44
|
-
try {
|
|
45
|
-
ret.json = JSON.parse(stdout);
|
|
46
|
-
} catch (ign) {}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
return ret;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
async getLatestVersion (pkg) {
|
|
53
|
-
return (await this.exec('view', [pkg, 'dist-tags'], {
|
|
54
|
-
json: true
|
|
55
|
-
})).json.latest;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
async getLatestSafeUpgradeVersion (pkg, curVersion) {
|
|
59
|
-
const allVersions = (await this.exec('view', [pkg, 'versions'], {
|
|
60
|
-
json: true
|
|
61
|
-
})).json;
|
|
62
|
-
return this.getLatestSafeUpgradeFromVersions(curVersion, allVersions);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Given a current version and a list of all versions for a package, return the version which is
|
|
67
|
-
* the highest safely-upgradable version (meaning not crossing any major revision boundaries, and
|
|
68
|
-
* not including any alpha/beta/rc versions)
|
|
69
|
-
*
|
|
70
|
-
* @param {string} curVersion - the current version of a package
|
|
71
|
-
* @param {Array<string>} allVersions - a list of version strings
|
|
72
|
-
*
|
|
73
|
-
* @return {string|null} - the highest safely-upgradable version, or null if there isn't one
|
|
74
|
-
*/
|
|
75
|
-
getLatestSafeUpgradeFromVersions (curVersion, allVersions) {
|
|
76
|
-
let safeUpgradeVer = null;
|
|
77
|
-
const curSemver = semver.parse(curVersion);
|
|
78
|
-
if (curSemver === null) {
|
|
79
|
-
throw new Error(`Could not parse current version '${curVersion}'`);
|
|
80
|
-
}
|
|
81
|
-
for (const testVer of allVersions) {
|
|
82
|
-
const testSemver = semver.parse(testVer);
|
|
83
|
-
if (testSemver === null) {
|
|
84
|
-
throw new Error(`Could not parse version to test against: '${testVer}'`);
|
|
85
|
-
}
|
|
86
|
-
// if the test version is a prerelease, ignore it
|
|
87
|
-
if (testSemver.prerelease.length > 0) {
|
|
88
|
-
continue;
|
|
89
|
-
}
|
|
90
|
-
// if the current version is later than the test version, skip this test version
|
|
91
|
-
if (curSemver.compare(testSemver) === 1) {
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
// if the test version is newer, but crosses a major revision boundary, also skip it
|
|
95
|
-
if (testSemver.major > curSemver.major) {
|
|
96
|
-
continue;
|
|
97
|
-
}
|
|
98
|
-
// otherwise this version is safe to upgrade to. But there might be multiple ones of this
|
|
99
|
-
// kind, so keep iterating and keeping the highest
|
|
100
|
-
if (safeUpgradeVer === null || testSemver.compare(safeUpgradeVer) === 1) {
|
|
101
|
-
safeUpgradeVer = testSemver;
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
if (safeUpgradeVer) {
|
|
105
|
-
safeUpgradeVer = safeUpgradeVer.format();
|
|
106
|
-
}
|
|
107
|
-
return safeUpgradeVer;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async installPackage ({pkgDir, pkgName, pkgVer}) {
|
|
111
|
-
const res = await this.exec('install', [
|
|
112
|
-
'--no-save',
|
|
113
|
-
'--no-package-lock',
|
|
114
|
-
pkgVer ? `${pkgName}@${pkgVer}` : pkgName
|
|
115
|
-
], {
|
|
116
|
-
cwd: pkgDir,
|
|
117
|
-
json: true,
|
|
118
|
-
lockFile: INSTALL_LOCKFILE
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
if (res.json) {
|
|
122
|
-
// we parsed a valid json response, so if we got an error here, return that
|
|
123
|
-
// message straightaway
|
|
124
|
-
if (res.json.error) {
|
|
125
|
-
throw new Error(res.json.error);
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
// Now read package data from the installed package to return, and make sure
|
|
130
|
-
// everything got installed ok. Remember, pkgName might end up with a / in it due to an npm
|
|
131
|
-
// org, so if so, that will get correctly exploded into multiple directories, by path.resolve here
|
|
132
|
-
// (even on Windows!)
|
|
133
|
-
const pkgJson = path.resolve(pkgDir, 'node_modules', pkgName, 'package.json');
|
|
134
|
-
try {
|
|
135
|
-
return require(pkgJson);
|
|
136
|
-
} catch {
|
|
137
|
-
throw new Error('The package was not downloaded correctly; its package.json ' +
|
|
138
|
-
'did not exist or was unreadable. We looked for it at ' +
|
|
139
|
-
pkgJson);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
async linkPackage (pkgPath) {
|
|
144
|
-
// from the path alone we don't know the npm package name, so we need to
|
|
145
|
-
// look in package.json
|
|
146
|
-
let pkgName;
|
|
147
|
-
try {
|
|
148
|
-
pkgName = require(path.resolve(pkgPath, 'package.json')).name;
|
|
149
|
-
} catch {
|
|
150
|
-
throw new Error('Could not find package.json inside the package path ' +
|
|
151
|
-
`provided: ${pkgPath}`);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
const pkgHome = path.resolve(this.appiumHome, pkgName);
|
|
155
|
-
const res = await this.exec('link', [pkgPath], {cwd: pkgHome, lockFile: LINK_LOCKFILE});
|
|
156
|
-
if (res.json && res.json.error) {
|
|
157
|
-
throw new Error(res.json.error);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
// now ensure it was linked to the correct place
|
|
161
|
-
try {
|
|
162
|
-
return require(path.resolve(pkgHome, 'node_modules', pkgName, 'package.json'));
|
|
163
|
-
} catch {
|
|
164
|
-
throw new Error('The package was not linked correctly; its package.json ' +
|
|
165
|
-
'did not exist or was unreadable');
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
async uninstallPackage (pkgDir, pkg) {
|
|
170
|
-
await this.exec('uninstall', [pkg], {
|
|
171
|
-
cwd: pkgDir,
|
|
172
|
-
lockFile: INSTALL_LOCKFILE
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { INSTALL_TYPES } from '../extension-config';
|
|
4
|
-
|
|
5
|
-
// serverArgs will be added to the `server` (default) subcommand
|
|
6
|
-
function parseSecurityFeatures (features) {
|
|
7
|
-
const splitter = (splitOn, str) => `${str}`.split(splitOn)
|
|
8
|
-
.map((s) => s.trim())
|
|
9
|
-
.filter(Boolean);
|
|
10
|
-
let parsedFeatures;
|
|
11
|
-
try {
|
|
12
|
-
parsedFeatures = splitter(',', features);
|
|
13
|
-
} catch (err) {
|
|
14
|
-
throw new TypeError('Could not parse value of --allow/deny-insecure. Should be ' +
|
|
15
|
-
'a list of strings separated by commas, or a path to a file ' +
|
|
16
|
-
'listing one feature name per line.');
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (parsedFeatures.length === 1 && fs.existsSync(parsedFeatures[0])) {
|
|
20
|
-
// we might have a file which is a list of features
|
|
21
|
-
try {
|
|
22
|
-
const fileFeatures = fs.readFileSync(parsedFeatures[0], 'utf8');
|
|
23
|
-
parsedFeatures = splitter('\n', fileFeatures);
|
|
24
|
-
} catch (err) {
|
|
25
|
-
throw new TypeError(`Attempted to read --allow/deny-insecure feature names ` +
|
|
26
|
-
`from file ${parsedFeatures[0]} but got error: ${err.message}`);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return parsedFeatures;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function parsePluginNames (names) {
|
|
34
|
-
if (!_.isString(names)) {
|
|
35
|
-
throw new TypeError('To parse plugin names, names must be a CSV string');
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
try {
|
|
39
|
-
return names.split(',').map((s) => s.trim()).filter(Boolean);
|
|
40
|
-
} catch (err) {
|
|
41
|
-
throw new TypeError('Could not parse value of --plugins. Should be a list of plugin names ' +
|
|
42
|
-
'separated by commas. Plugin names are those found when running `appium ' +
|
|
43
|
-
'plugin list`');
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function parseDefaultCaps (capsOrPath) {
|
|
48
|
-
let caps = capsOrPath;
|
|
49
|
-
let loadedFromFile = false;
|
|
50
|
-
try {
|
|
51
|
-
// use synchronous file access, as `argparse` provides no way of either
|
|
52
|
-
// awaiting or using callbacks. This step happens in startup, in what is
|
|
53
|
-
// effectively command-line code, so nothing is blocked in terms of
|
|
54
|
-
// sessions, so holding up the event loop does not incur the usual
|
|
55
|
-
// drawbacks.
|
|
56
|
-
if (_.isString(capsOrPath) && fs.statSync(capsOrPath).isFile()) {
|
|
57
|
-
caps = fs.readFileSync(capsOrPath, 'utf8');
|
|
58
|
-
loadedFromFile = true;
|
|
59
|
-
}
|
|
60
|
-
} catch (err) {
|
|
61
|
-
// not a file, or not readable
|
|
62
|
-
}
|
|
63
|
-
try {
|
|
64
|
-
const result = JSON.parse(caps);
|
|
65
|
-
if (!_.isPlainObject(result)) {
|
|
66
|
-
throw new Error(`'${_.truncate(result, {length: 100})}' is not an object`);
|
|
67
|
-
}
|
|
68
|
-
return result;
|
|
69
|
-
} catch (e) {
|
|
70
|
-
const msg = loadedFromFile
|
|
71
|
-
? `Default capabilities in '${capsOrPath}' must be a valid JSON`
|
|
72
|
-
: `Default capabilities must be a valid JSON`;
|
|
73
|
-
throw new TypeError(`${msg}. Original error: ${e.message}`);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
function parseInstallTypes (source) {
|
|
78
|
-
if (!_.includes(INSTALL_TYPES, source)) {
|
|
79
|
-
throw `Argument to --source was '${source}', which is not a valid ` +
|
|
80
|
-
`driver source type. It must be one of ${JSON.stringify(INSTALL_TYPES)}`;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
return source;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export {
|
|
87
|
-
parseSecurityFeatures,
|
|
88
|
-
parseDefaultCaps,
|
|
89
|
-
parseInstallTypes,
|
|
90
|
-
parsePluginNames,
|
|
91
|
-
};
|
package/lib/driver-config.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import ExtensionConfig, { DRIVER_TYPE } from './extension-config';
|
|
3
|
-
|
|
4
|
-
export default class DriverConfig extends ExtensionConfig {
|
|
5
|
-
constructor (appiumHome, logFn = null) {
|
|
6
|
-
super(appiumHome, DRIVER_TYPE, logFn);
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
getConfigProblems (driver) {
|
|
10
|
-
const problems = [];
|
|
11
|
-
const automationNames = [];
|
|
12
|
-
const {platformNames, automationName} = driver;
|
|
13
|
-
|
|
14
|
-
if (!_.isArray(platformNames)) {
|
|
15
|
-
problems.push({
|
|
16
|
-
err: 'Missing or incorrect supported platformName list.',
|
|
17
|
-
val: platformNames
|
|
18
|
-
});
|
|
19
|
-
} else {
|
|
20
|
-
for (const pName of platformNames) {
|
|
21
|
-
if (!_.isString(pName)) {
|
|
22
|
-
problems.push({err: 'Incorrectly formatted platformName.', val: pName});
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (!_.isString(automationName)) {
|
|
28
|
-
problems.push({err: 'Missing or incorrect automationName', val: automationName});
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (_.includes(automationNames, automationName)) {
|
|
32
|
-
problems.push({
|
|
33
|
-
err: 'Multiple drivers claim support for the same automationName',
|
|
34
|
-
val: automationName
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
automationNames.push(automationName);
|
|
38
|
-
|
|
39
|
-
return problems;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
extensionDesc (driverName, {version, automationName}) {
|
|
43
|
-
return `${driverName}@${version} (automationName '${automationName}')`;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
package/lib/drivers.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import log from './logger';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
// This is a map of driver names to npm packages representing those drivers.
|
|
6
|
-
// The drivers in this list will be available to the CLI so users can just
|
|
7
|
-
// type 'appium driver install 'name'', rather than having to specify the full
|
|
8
|
-
// npm package. I.e., these are the officially recognized drivers.
|
|
9
|
-
const KNOWN_DRIVERS = {
|
|
10
|
-
uiautomator2: 'appium-uiautomator2-driver',
|
|
11
|
-
xcuitest: 'appium-xcuitest-driver',
|
|
12
|
-
youiengine: 'appium-youiengine-driver',
|
|
13
|
-
windows: 'appium-windows-driver',
|
|
14
|
-
mac: 'appium-mac-driver',
|
|
15
|
-
mac2: 'appium-mac2-driver',
|
|
16
|
-
espresso: 'appium-espresso-driver',
|
|
17
|
-
tizen: 'appium-tizen-driver',
|
|
18
|
-
flutter: 'appium-flutter-driver',
|
|
19
|
-
safari: 'appium-safari-driver',
|
|
20
|
-
gecko: 'appium-geckodriver',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
function getDriverBySupport (drivers, matchAutomationName, matchPlatformName) {
|
|
24
|
-
for (const [driverName, driverData] of _.toPairs(drivers)) {
|
|
25
|
-
const {automationName, platformNames} = driverData;
|
|
26
|
-
const aNameMatches = automationName.toLowerCase() === matchAutomationName.toLowerCase();
|
|
27
|
-
const pNameMatches = _.includes(platformNames.map(_.toLower),
|
|
28
|
-
matchPlatformName.toLowerCase());
|
|
29
|
-
|
|
30
|
-
if (aNameMatches && pNameMatches) {
|
|
31
|
-
return {driverName, ...driverData};
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (aNameMatches) {
|
|
35
|
-
throw new Error(`Driver '${driverName}' supports automationName ` +
|
|
36
|
-
`'${automationName}', but Appium could not find ` +
|
|
37
|
-
`support for platformName '${matchPlatformName}'. Supported ` +
|
|
38
|
-
`platformNames are: ` +
|
|
39
|
-
JSON.stringify(platformNames));
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
throw new Error(`Could not find installed driver to support given caps`);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function findMatchingDriver (config, {automationName, platformName}) {
|
|
47
|
-
if (!_.isString(platformName)) {
|
|
48
|
-
throw new Error('You must include a platformName capability');
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (!_.isString(automationName)) {
|
|
52
|
-
throw new Error('You must include an automationName capability');
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
log.info(`Attempting to find matching driver for automationName ` +
|
|
56
|
-
`'${automationName}' and platformName '${platformName}'`);
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
const {
|
|
60
|
-
driverName,
|
|
61
|
-
mainClass,
|
|
62
|
-
version,
|
|
63
|
-
} = getDriverBySupport(config.installedExtensions, automationName, platformName);
|
|
64
|
-
log.info(`The '${driverName}' driver was installed and matched caps.`);
|
|
65
|
-
log.info(`Will require it at ${config.getExtensionRequirePath(driverName)}`);
|
|
66
|
-
const driver = config.require(driverName);
|
|
67
|
-
if (!driver) {
|
|
68
|
-
throw new Error(`MainClass ${mainClass} did not result in a driver object`);
|
|
69
|
-
}
|
|
70
|
-
return {driver, version};
|
|
71
|
-
} catch (err) {
|
|
72
|
-
const msg = `Could not find a driver for automationName ` +
|
|
73
|
-
`'${automationName}' and platformName ${platformName}'. ` +
|
|
74
|
-
`Have you installed a driver that supports those ` +
|
|
75
|
-
`capabilities? Run 'appium driver list --installed' to see. ` +
|
|
76
|
-
`(Lower-level error: ${err.message})`;
|
|
77
|
-
throw new Error(msg);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export {
|
|
82
|
-
findMatchingDriver,
|
|
83
|
-
KNOWN_DRIVERS,
|
|
84
|
-
};
|
package/lib/extension-config.js
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import log from './logger';
|
|
3
|
-
import { fs, mkdirp } from 'appium-support';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import os from 'os';
|
|
6
|
-
import YAML from 'yaml';
|
|
7
|
-
|
|
8
|
-
const DRIVER_TYPE = 'driver';
|
|
9
|
-
const PLUGIN_TYPE = 'plugin';
|
|
10
|
-
const DEFAULT_APPIUM_HOME = path.resolve(os.homedir(), '.appium');
|
|
11
|
-
|
|
12
|
-
const CONFIG_FILE_NAME = 'extensions.yaml';
|
|
13
|
-
const CONFIG_SCHEMA_REV = 2;
|
|
14
|
-
|
|
15
|
-
const INSTALL_TYPE_NPM = 'npm';
|
|
16
|
-
const INSTALL_TYPE_LOCAL = 'local';
|
|
17
|
-
const INSTALL_TYPE_GITHUB = 'github';
|
|
18
|
-
const INSTALL_TYPE_GIT = 'git';
|
|
19
|
-
const INSTALL_TYPES = [
|
|
20
|
-
INSTALL_TYPE_GIT,
|
|
21
|
-
INSTALL_TYPE_GITHUB,
|
|
22
|
-
INSTALL_TYPE_LOCAL,
|
|
23
|
-
INSTALL_TYPE_NPM
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
export default class ExtensionConfig {
|
|
28
|
-
constructor (appiumHome, extensionType, logFn = null) {
|
|
29
|
-
if (logFn === null) {
|
|
30
|
-
logFn = log.error.bind(log);
|
|
31
|
-
}
|
|
32
|
-
this.appiumHome = appiumHome;
|
|
33
|
-
this.configFile = path.resolve(this.appiumHome, CONFIG_FILE_NAME);
|
|
34
|
-
this.installedExtensions = {};
|
|
35
|
-
this.extensionType = extensionType;
|
|
36
|
-
this.configKey = `${extensionType}s`;
|
|
37
|
-
this.yamlData = {[`${DRIVER_TYPE}s`]: {}, [`${PLUGIN_TYPE}s`]: {}};
|
|
38
|
-
this.log = logFn;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
validate (exts) {
|
|
42
|
-
const foundProblems = {};
|
|
43
|
-
for (const [extName, extData] of _.toPairs(exts)) {
|
|
44
|
-
foundProblems[extName] = [
|
|
45
|
-
...this.getGenericConfigProblems(extData),
|
|
46
|
-
...this.getConfigProblems(extData)
|
|
47
|
-
];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
const problemSummaries = [];
|
|
51
|
-
for (const [extName, problems] of _.toPairs(foundProblems)) {
|
|
52
|
-
if (_.isEmpty(problems)) {
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
// remove this extension from the list since it's not valid
|
|
56
|
-
delete exts[extName];
|
|
57
|
-
problemSummaries.push(`${this.extensionType} ${extName} had errors and will not ` +
|
|
58
|
-
`be available. Errors:`);
|
|
59
|
-
for (const problem of problems) {
|
|
60
|
-
problemSummaries.push(` - ${problem.err} (Actual value: ` +
|
|
61
|
-
`${JSON.stringify(problem.val)})`);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
if (!_.isEmpty(problemSummaries)) {
|
|
66
|
-
this.log(`Appium encountered one or more errors while validating ` +
|
|
67
|
-
`the ${this.configKey} extension file (${this.configFile}):`);
|
|
68
|
-
for (const summary of problemSummaries) {
|
|
69
|
-
this.log(summary);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return exts;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
getGenericConfigProblems (ext) {
|
|
77
|
-
const {version, pkgName, installSpec, installType, installPath, mainClass} = ext;
|
|
78
|
-
const problems = [];
|
|
79
|
-
|
|
80
|
-
if (!_.isString(version)) {
|
|
81
|
-
problems.push({err: 'Missing or incorrect version', val: version});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
if (!_.isString(pkgName)) {
|
|
85
|
-
problems.push({err: 'Missing or incorrect NPM package name', val: pkgName});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (!_.isString(installSpec)) {
|
|
89
|
-
problems.push({err: 'Missing or incorrect installation spec', val: installSpec});
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if (!_.includes(INSTALL_TYPES, installType)) {
|
|
93
|
-
problems.push({err: 'Missing or incorrect install type', val: installType});
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (!_.isString(installPath)) {
|
|
97
|
-
problems.push({err: 'Missing or incorrect installation path', val: installPath});
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
if (!_.isString(mainClass)) {
|
|
101
|
-
problems.push({err: 'Missing or incorrect driver class name', val: mainClass});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
return problems;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
getConfigProblems (/*ext*/) {
|
|
108
|
-
// shoud override this method if special validation is necessary for this extension type
|
|
109
|
-
return [];
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
applySchemaMigrations () {
|
|
113
|
-
if (this.yamlData.schemaRev < 2 && _.isUndefined(this.yamlData[PLUGIN_TYPE])) {
|
|
114
|
-
// at schema revision 2, we started including plugins as well as drivers in the file,
|
|
115
|
-
// so make sure we at least have an empty section for it
|
|
116
|
-
this.yamlData[PLUGIN_TYPE] = {};
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
async read () {
|
|
121
|
-
await mkdirp(this.appiumHome); // ensure appium home exists
|
|
122
|
-
try {
|
|
123
|
-
this.yamlData = YAML.parse(await fs.readFile(this.configFile, 'utf8'));
|
|
124
|
-
this.applySchemaMigrations();
|
|
125
|
-
|
|
126
|
-
// set the list of drivers the user has installed
|
|
127
|
-
this.installedExtensions = this.validate(this.yamlData[this.configKey]);
|
|
128
|
-
} catch (err) {
|
|
129
|
-
if (await fs.exists(this.configFile)) {
|
|
130
|
-
// if the file exists and we couldn't parse it, that's a problem
|
|
131
|
-
throw new Error(`Appium had trouble loading the extension installation ` +
|
|
132
|
-
`cache file (${this.configFile}). Ensure it exists and is ` +
|
|
133
|
-
`readable. Specific error: ${err.message}`);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// if the config file doesn't exist, try to write an empty one, to make
|
|
137
|
-
// sure we actually have write privileges, and complain if we don't
|
|
138
|
-
try {
|
|
139
|
-
await this.write();
|
|
140
|
-
} catch {
|
|
141
|
-
throw new Error(`Appium could not read or write from the Appium Home directory ` +
|
|
142
|
-
`(${this.appiumHome}). Please ensure it is writable.`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
return this.installedExtensions;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
async write () {
|
|
150
|
-
const newYamlData = {
|
|
151
|
-
...this.yamlData,
|
|
152
|
-
schemaRev: CONFIG_SCHEMA_REV,
|
|
153
|
-
[this.configKey]: this.installedExtensions
|
|
154
|
-
};
|
|
155
|
-
await fs.writeFile(this.configFile, YAML.stringify(newYamlData), 'utf8');
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async addExtension (extName, extData) {
|
|
159
|
-
this.installedExtensions[extName] = extData;
|
|
160
|
-
await this.write();
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
async removeExtension (extName) {
|
|
164
|
-
delete this.installedExtensions[extName];
|
|
165
|
-
await this.write();
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
print () {
|
|
169
|
-
const extNames = Object.keys(this.installedExtensions);
|
|
170
|
-
if (_.isEmpty(extNames)) {
|
|
171
|
-
log.info(`No ${this.configKey} have been installed. Use the "appium ${this.extensionType}" ` +
|
|
172
|
-
'command to install the one(s) you want to use.');
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
log.info(`Available ${this.configKey}:`);
|
|
177
|
-
for (const [extName, extData] of _.toPairs(this.installedExtensions)) {
|
|
178
|
-
log.info(` - ${this.extensionDesc(extName, extData)}`);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
extensionDesc () {
|
|
183
|
-
throw new Error('This must be implemented in a final class');
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
getExtensionRequirePath (extName) {
|
|
187
|
-
const {pkgName, installPath} = this.installedExtensions[extName];
|
|
188
|
-
return path.resolve(this.appiumHome, installPath, 'node_modules', pkgName);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
getInstallPath (extName) {
|
|
192
|
-
const {installPath} = this.installedExtensions[extName];
|
|
193
|
-
return path.resolve(this.appiumHome, installPath);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
require (extName) {
|
|
197
|
-
const {mainClass} = this.installedExtensions[extName];
|
|
198
|
-
return require(this.getExtensionRequirePath(extName))[mainClass];
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
isInstalled (extName) {
|
|
202
|
-
return _.includes(Object.keys(this.installedExtensions), extName);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
export {
|
|
207
|
-
INSTALL_TYPE_NPM, INSTALL_TYPE_GIT, INSTALL_TYPE_LOCAL, INSTALL_TYPE_GITHUB,
|
|
208
|
-
INSTALL_TYPES, DEFAULT_APPIUM_HOME, DRIVER_TYPE, PLUGIN_TYPE,
|
|
209
|
-
};
|
package/lib/plugin-config.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
import ExtensionConfig, { PLUGIN_TYPE } from './extension-config';
|
|
3
|
-
import log from './logger';
|
|
4
|
-
|
|
5
|
-
export default class PluginConfig extends ExtensionConfig {
|
|
6
|
-
constructor (appiumHome, logFn = null) {
|
|
7
|
-
super(appiumHome, PLUGIN_TYPE, logFn);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
extensionDesc (pluginName, {version}) {
|
|
11
|
-
return `${pluginName}@${version}`;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
print (activePlugins) {
|
|
15
|
-
const pluginNames = Object.keys(this.installedExtensions);
|
|
16
|
-
const activeNames = activePlugins.map((p) => p.name);
|
|
17
|
-
|
|
18
|
-
if (_.isEmpty(pluginNames)) {
|
|
19
|
-
log.info(`No plugins have been installed. Use the "appium plugin" ` +
|
|
20
|
-
'command to install the one(s) you want to use.');
|
|
21
|
-
return;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
log.info(`Available plugins:`);
|
|
25
|
-
for (const [pluginName, pluginData] of _.toPairs(this.installedExtensions)) {
|
|
26
|
-
const activeTxt = _.includes(activeNames, pluginName) ? ' (ACTIVE)' : '';
|
|
27
|
-
log.info(` - ${this.extensionDesc(pluginName, pluginData)}${activeTxt}`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (_.isEmpty(activePlugins)) {
|
|
31
|
-
log.info('No plugins activated. Use the --plugins flag with names of plugins to activate');
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
package/lib/plugins.js
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
// This is a map of plugin names to npm packages representing those plugins.
|
|
2
|
-
// The plugins in this list will be available to the CLI so users can just
|
|
3
|
-
// type 'appium plugin install 'name'', rather than having to specify the full
|
|
4
|
-
// npm package. I.e., these are the officially recognized plugins.
|
|
5
|
-
const KNOWN_PLUGINS = {
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
export {
|
|
9
|
-
KNOWN_PLUGINS,
|
|
10
|
-
};
|