appium 2.0.0-beta.40 → 2.0.0-beta.43
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 +14 -15
- package/build/lib/cli/args.d.ts +2 -5
- package/build/lib/cli/args.d.ts.map +1 -1
- package/build/lib/cli/args.js +2 -2
- package/build/lib/cli/driver-command.d.ts +2 -1
- package/build/lib/cli/driver-command.d.ts.map +1 -1
- package/build/lib/cli/driver-command.js +5 -3
- package/build/lib/cli/extension-command.d.ts +5 -1
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +4 -3
- package/build/lib/cli/extension.d.ts +8 -4
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +2 -1
- package/build/lib/cli/parser.d.ts +5 -1
- package/build/lib/cli/parser.d.ts.map +1 -1
- package/build/lib/cli/parser.js +19 -6
- package/build/lib/cli/plugin-command.d.ts +2 -1
- package/build/lib/cli/plugin-command.d.ts.map +1 -1
- package/build/lib/cli/plugin-command.js +5 -3
- package/build/lib/config-file.d.ts.map +1 -1
- package/build/lib/config-file.js +8 -6
- package/build/lib/config.d.ts +10 -2
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +30 -32
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +3 -3
- package/build/lib/extension/index.js +6 -5
- package/build/lib/extension/package-changed.js +2 -4
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +25 -31
- package/build/lib/schema/arg-spec.d.ts +5 -5
- package/build/lib/schema/arg-spec.d.ts.map +1 -1
- package/build/lib/schema/arg-spec.js +2 -2
- package/build/lib/schema/cli-args.js +5 -7
- package/build/lib/schema/schema.d.ts +3 -3
- package/build/lib/schema/schema.d.ts.map +1 -1
- package/build/lib/schema/schema.js +2 -4
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/cli.d.ts +16 -5
- package/build/types/cli.d.ts.map +1 -1
- package/lib/appium.js +8 -5
- package/lib/cli/args.js +3 -5
- package/lib/cli/driver-command.js +2 -2
- package/lib/cli/extension-command.js +3 -2
- package/lib/cli/extension.js +16 -4
- package/lib/cli/parser.js +27 -5
- package/lib/cli/plugin-command.js +2 -2
- package/lib/config-file.js +4 -2
- package/lib/config.js +40 -26
- package/lib/extension/extension-config.js +4 -6
- package/lib/main.js +21 -14
- package/lib/schema/arg-spec.js +1 -1
- package/lib/schema/schema.js +1 -1
- package/package.json +27 -17
- package/scripts/autoinstall-extensions.js +11 -3
- package/test.d.ts +7 -0
- package/test.js +13 -0
- package/types/cli.ts +23 -19
package/lib/cli/args.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @ts-ignore
|
|
2
1
|
import _ from 'lodash';
|
|
3
2
|
import {
|
|
4
3
|
DRIVER_TYPE,
|
|
@@ -215,8 +214,8 @@ function makeRunArgs(type) {
|
|
|
215
214
|
default: null,
|
|
216
215
|
type: 'str',
|
|
217
216
|
help:
|
|
218
|
-
`Name of the script to run from the ${type}. The script name must be
|
|
219
|
-
`inside the "scripts" field
|
|
217
|
+
`Name of the script to run from the ${type}. The script name must be a key ` +
|
|
218
|
+
`inside the "appium.scripts" field inside the ${type}'s "package.json" file`,
|
|
220
219
|
},
|
|
221
220
|
],
|
|
222
221
|
]);
|
|
@@ -280,8 +279,7 @@ const serverArgsDisallowedInConfig = new Map([
|
|
|
280
279
|
export {getServerArgs, getExtensionArgs};
|
|
281
280
|
|
|
282
281
|
/**
|
|
283
|
-
*
|
|
284
|
-
* @typedef {import('../extension/manifest').ExtensionType} ExtensionType
|
|
282
|
+
* @typedef {import('@appium/types').ExtensionType} ExtensionType
|
|
285
283
|
*/
|
|
286
284
|
|
|
287
285
|
/**
|
|
@@ -33,8 +33,8 @@ export default class DriverCommand extends ExtensionCommand {
|
|
|
33
33
|
return await super._update({installSpec: driver, unsafe});
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
async run({driver, scriptName}) {
|
|
37
|
-
return await super._run({installSpec: driver, scriptName});
|
|
36
|
+
async run({driver, scriptName, extraArgs}) {
|
|
37
|
+
return await super._run({installSpec: driver, scriptName, extraArgs});
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
getPostInstallText({extName, extData}) {
|
|
@@ -628,7 +628,7 @@ class ExtensionCommand {
|
|
|
628
628
|
* @param {RunOptions} opts
|
|
629
629
|
* @return {Promise<RunOutput>}
|
|
630
630
|
*/
|
|
631
|
-
async _run({installSpec, scriptName}) {
|
|
631
|
+
async _run({installSpec, scriptName, extraArgs = []}) {
|
|
632
632
|
if (!this.config.isInstalled(installSpec)) {
|
|
633
633
|
throw this._createFatalError(`The ${this.type} "${installSpec}" is not installed`);
|
|
634
634
|
}
|
|
@@ -657,7 +657,7 @@ class ExtensionCommand {
|
|
|
657
657
|
);
|
|
658
658
|
}
|
|
659
659
|
|
|
660
|
-
const runner = new SubProcess(process.execPath, [extScripts[scriptName]], {
|
|
660
|
+
const runner = new SubProcess(process.execPath, [extScripts[scriptName], ...extraArgs], {
|
|
661
661
|
cwd: this.config.getInstallPath(installSpec),
|
|
662
662
|
});
|
|
663
663
|
|
|
@@ -755,6 +755,7 @@ export {ExtensionCommand};
|
|
|
755
755
|
* @typedef RunOptions
|
|
756
756
|
* @property {string} installSpec - name of the extension to run a script from
|
|
757
757
|
* @property {string} scriptName - name of the script to run
|
|
758
|
+
* @property {string[]} [extraArgs] - arguments to pass to the script
|
|
758
759
|
*/
|
|
759
760
|
|
|
760
761
|
/**
|
package/lib/cli/extension.js
CHANGED
|
@@ -15,9 +15,9 @@ export const commandClasses = Object.freeze(
|
|
|
15
15
|
* Run a subcommand of the 'appium driver' type. Each subcommand has its own set of arguments which
|
|
16
16
|
* can be represented as a JS object.
|
|
17
17
|
*
|
|
18
|
-
* @param {
|
|
18
|
+
* @param {import('appium/types').Args<import('appium/types').WithExtSubcommand>} args - JS object where the key is the parameter name (as defined in
|
|
19
19
|
* driver-parser.js)
|
|
20
|
-
* @template {
|
|
20
|
+
* @template {ExtensionType} ExtType
|
|
21
21
|
* @param {import('../extension/extension-config').ExtensionConfig<ExtType>} config - Extension config object
|
|
22
22
|
*/
|
|
23
23
|
async function runExtensionCommand(args, config) {
|
|
@@ -30,6 +30,7 @@ async function runExtensionCommand(args, config) {
|
|
|
30
30
|
throw new TypeError(`Cannot call ${type} command without a subcommand like 'install'`);
|
|
31
31
|
}
|
|
32
32
|
let {json, suppressOutput} = args;
|
|
33
|
+
json = Boolean(json);
|
|
33
34
|
if (suppressOutput) {
|
|
34
35
|
json = true;
|
|
35
36
|
}
|
|
@@ -56,6 +57,17 @@ async function runExtensionCommand(args, config) {
|
|
|
56
57
|
export {runExtensionCommand};
|
|
57
58
|
|
|
58
59
|
/**
|
|
59
|
-
* @template {
|
|
60
|
-
* @typedef {ExtType extends
|
|
60
|
+
* @template {ExtensionType} ExtType
|
|
61
|
+
* @typedef {ExtType extends DriverType ? Class<DriverCommand> : ExtType extends PluginType ? Class<PluginCommand> : never} ExtCommand
|
|
62
|
+
*/
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @typedef {import('@appium/types').ExtensionType} ExtensionType
|
|
66
|
+
* @typedef {import('@appium/types').DriverType} DriverType
|
|
67
|
+
* @typedef {import('@appium/types').PluginType} PluginType
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @template T
|
|
72
|
+
* @typedef {import('@appium/types').Class<T>} Class
|
|
61
73
|
*/
|
package/lib/cli/parser.js
CHANGED
|
@@ -7,6 +7,8 @@ import {finalizeSchema, getArgSpec, hasArgSpec} from '../schema';
|
|
|
7
7
|
import {rootDir} from '../config';
|
|
8
8
|
import {getExtensionArgs, getServerArgs} from './args';
|
|
9
9
|
|
|
10
|
+
export const EXTRA_ARGS = 'extraArgs';
|
|
11
|
+
|
|
10
12
|
/**
|
|
11
13
|
* If the parsed args do not contain any of these values, then we
|
|
12
14
|
* will automatially inject the `server` subcommand.
|
|
@@ -97,8 +99,17 @@ class ArgParser {
|
|
|
97
99
|
}
|
|
98
100
|
|
|
99
101
|
try {
|
|
100
|
-
const parsed = this.parser.
|
|
101
|
-
|
|
102
|
+
const parsed = this.parser.parse_known_args(args);
|
|
103
|
+
const [knownArgs, unknownArgs] = parsed;
|
|
104
|
+
if (
|
|
105
|
+
unknownArgs?.length &&
|
|
106
|
+
(knownArgs.driverCommand === 'run' || knownArgs.pluginCommand === 'run')
|
|
107
|
+
) {
|
|
108
|
+
return ArgParser._transformParsedArgs(knownArgs, unknownArgs);
|
|
109
|
+
} else if (unknownArgs?.length) {
|
|
110
|
+
throw new Error(`[ERROR] Unrecognized arguments: ${unknownArgs.join(' ')}`);
|
|
111
|
+
}
|
|
112
|
+
return ArgParser._transformParsedArgs(knownArgs);
|
|
102
113
|
} catch (err) {
|
|
103
114
|
if (this.debug) {
|
|
104
115
|
throw err;
|
|
@@ -123,10 +134,11 @@ class ArgParser {
|
|
|
123
134
|
*
|
|
124
135
|
* E.g., `{'driver-foo-bar': baz}` becomes `{driver: {foo: {bar: 'baz'}}}`
|
|
125
136
|
* @param {object} args
|
|
137
|
+
* @param {string[]} [unknownArgs]
|
|
126
138
|
* @returns {object}
|
|
127
139
|
*/
|
|
128
|
-
static _transformParsedArgs(args) {
|
|
129
|
-
|
|
140
|
+
static _transformParsedArgs(args, unknownArgs = []) {
|
|
141
|
+
const result = _.reduce(
|
|
130
142
|
args,
|
|
131
143
|
(unpacked, value, key) => {
|
|
132
144
|
if (!_.isUndefined(value) && hasArgSpec(key)) {
|
|
@@ -140,6 +152,8 @@ class ArgParser {
|
|
|
140
152
|
},
|
|
141
153
|
{}
|
|
142
154
|
);
|
|
155
|
+
result[EXTRA_ARGS] = unknownArgs;
|
|
156
|
+
return result;
|
|
143
157
|
}
|
|
144
158
|
|
|
145
159
|
/**
|
|
@@ -183,7 +197,7 @@ class ArgParser {
|
|
|
183
197
|
* @param {import('argparse').SubParser} subParsers
|
|
184
198
|
*/
|
|
185
199
|
static _addExtensionCommandsToParser(subParsers) {
|
|
186
|
-
for (const type of [DRIVER_TYPE, PLUGIN_TYPE]) {
|
|
200
|
+
for (const type of /** @type {[DriverType, PluginType]} */ ([DRIVER_TYPE, PLUGIN_TYPE])) {
|
|
187
201
|
const extParser = subParsers.add_parser(type, {
|
|
188
202
|
add_help: true,
|
|
189
203
|
help: `Access the ${type} management CLI commands`,
|
|
@@ -195,6 +209,9 @@ class ArgParser {
|
|
|
195
209
|
dest: `${type}Command`,
|
|
196
210
|
});
|
|
197
211
|
const extensionArgs = getExtensionArgs();
|
|
212
|
+
/**
|
|
213
|
+
* @type { {command: import('appium/types').CliExtensionSubcommand, args: import('./args').ArgumentDefinitions, help: string}[] }
|
|
214
|
+
*/
|
|
198
215
|
const parserSpecs = [
|
|
199
216
|
{
|
|
200
217
|
command: 'list',
|
|
@@ -254,3 +271,8 @@ function getParser(debug) {
|
|
|
254
271
|
}
|
|
255
272
|
|
|
256
273
|
export {getParser, ArgParser};
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* @typedef {import('@appium/types').DriverType} DriverType
|
|
277
|
+
* @typedef {import('@appium/types').PluginType} PluginType
|
|
278
|
+
*/
|
|
@@ -33,8 +33,8 @@ export default class PluginCommand extends ExtensionCommand {
|
|
|
33
33
|
return await super._update({installSpec: plugin, unsafe});
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
async run({plugin, scriptName}) {
|
|
37
|
-
return await super._run({installSpec: plugin, scriptName});
|
|
36
|
+
async run({plugin, scriptName, extraArgs}) {
|
|
37
|
+
return await super._run({installSpec: plugin, scriptName, extraArgs});
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
getPostInstallText({extName, extData}) {
|
package/lib/config-file.js
CHANGED
|
@@ -161,7 +161,9 @@ export function normalizeConfig(config) {
|
|
|
161
161
|
|
|
162
162
|
return _.mapValues(mappedObj, (value, property) => {
|
|
163
163
|
const nextSection = section ? `${section}.${property}` : property;
|
|
164
|
-
return isSchemaTypeObject(
|
|
164
|
+
return isSchemaTypeObject(schema.properties?.[property])
|
|
165
|
+
? normalize(config, nextSection)
|
|
166
|
+
: value;
|
|
165
167
|
});
|
|
166
168
|
};
|
|
167
169
|
|
|
@@ -169,7 +171,7 @@ export function normalizeConfig(config) {
|
|
|
169
171
|
* Returns `true` if the schema prop references an object, or if it's an object itself
|
|
170
172
|
* @param {import('ajv').SchemaObject|object} schema - Referencing schema object
|
|
171
173
|
*/
|
|
172
|
-
const isSchemaTypeObject = (schema) => Boolean(schema
|
|
174
|
+
const isSchemaTypeObject = (schema) => Boolean(schema?.properties || schema?.type === 'object');
|
|
173
175
|
|
|
174
176
|
return normalize(config);
|
|
175
177
|
}
|
package/lib/config.js
CHANGED
|
@@ -3,7 +3,6 @@ import _ from 'lodash';
|
|
|
3
3
|
import {system, fs} from '@appium/support';
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import {exec} from 'teen_process';
|
|
6
|
-
import logger from './logger';
|
|
7
6
|
import semver from 'semver';
|
|
8
7
|
import findUp from 'find-up';
|
|
9
8
|
import {getDefaultsForSchema, getAllArgSpecs} from './schema/schema';
|
|
@@ -12,6 +11,7 @@ const npmPackage = fs.readPackageJsonFrom(__dirname);
|
|
|
12
11
|
|
|
13
12
|
const APPIUM_VER = npmPackage.version;
|
|
14
13
|
const MIN_NODE_VERSION = npmPackage.engines.node;
|
|
14
|
+
const MIN_NPM_VERSION = npmPackage.engines.npm;
|
|
15
15
|
|
|
16
16
|
const GIT_META_ROOT = '.git';
|
|
17
17
|
const GIT_BINARY = `git${system.isWindows() ? '.exe' : ''}`;
|
|
@@ -28,15 +28,27 @@ function getNodeVersion() {
|
|
|
28
28
|
return /** @type {import('semver').SemVer} */ (semver.coerce(process.version));
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Returns version of `npm`
|
|
33
|
+
* @returns {Promise<string>}
|
|
34
|
+
*/
|
|
35
|
+
async function getNpmVersion() {
|
|
36
|
+
const {stdout} = await exec(system.isWindows() ? 'npm.cmd' : 'npm', ['--version']);
|
|
37
|
+
return stdout.trim();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* @param {boolean} [useGithubApiFallback]
|
|
42
|
+
*/
|
|
31
43
|
async function updateBuildInfo(useGithubApiFallback = false) {
|
|
32
44
|
const sha = await getGitRev(useGithubApiFallback);
|
|
33
45
|
if (!sha) {
|
|
34
46
|
return;
|
|
35
47
|
}
|
|
36
48
|
BUILD_INFO['git-sha'] = sha;
|
|
37
|
-
const
|
|
38
|
-
if (
|
|
39
|
-
BUILD_INFO.built =
|
|
49
|
+
const buildTimestamp = await getGitTimestamp(sha, useGithubApiFallback);
|
|
50
|
+
if (buildTimestamp) {
|
|
51
|
+
BUILD_INFO.built = buildTimestamp;
|
|
40
52
|
}
|
|
41
53
|
}
|
|
42
54
|
|
|
@@ -51,6 +63,10 @@ async function findGitRoot() {
|
|
|
51
63
|
return await findUp(GIT_META_ROOT, {cwd: rootDir, type: 'directory'});
|
|
52
64
|
}
|
|
53
65
|
|
|
66
|
+
/**
|
|
67
|
+
* @param {boolean} [useGithubApiFallback]
|
|
68
|
+
* @returns {Promise<string?>}
|
|
69
|
+
*/
|
|
54
70
|
async function getGitRev(useGithubApiFallback = false) {
|
|
55
71
|
const gitRoot = await findGitRoot();
|
|
56
72
|
if (gitRoot) {
|
|
@@ -66,21 +82,16 @@ async function getGitRev(useGithubApiFallback = false) {
|
|
|
66
82
|
return null;
|
|
67
83
|
}
|
|
68
84
|
|
|
85
|
+
// If the package folder is not a valid git repository
|
|
86
|
+
// then fetch the corresponding tag info from GitHub
|
|
69
87
|
try {
|
|
70
|
-
|
|
71
|
-
await axios.get(`${GITHUB_API}/tags`, {
|
|
88
|
+
return (
|
|
89
|
+
await axios.get(`${GITHUB_API}/git/refs/tags/appium@${APPIUM_VER}`, {
|
|
72
90
|
headers: {
|
|
73
91
|
'User-Agent': `Appium ${APPIUM_VER}`,
|
|
74
92
|
},
|
|
75
93
|
})
|
|
76
|
-
).data;
|
|
77
|
-
if (_.isArray(resBodyObj)) {
|
|
78
|
-
for (const {name, commit} of resBodyObj) {
|
|
79
|
-
if (name === `v${APPIUM_VER}` && commit && commit.sha) {
|
|
80
|
-
return commit.sha;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
94
|
+
).data?.object?.sha;
|
|
84
95
|
} catch (ign) {}
|
|
85
96
|
return null;
|
|
86
97
|
}
|
|
@@ -106,21 +117,13 @@ async function getGitTimestamp(commitSha, useGithubApiFallback = false) {
|
|
|
106
117
|
}
|
|
107
118
|
|
|
108
119
|
try {
|
|
109
|
-
|
|
110
|
-
await axios.get(`${GITHUB_API}/
|
|
120
|
+
return (
|
|
121
|
+
await axios.get(`${GITHUB_API}/git/tags/${commitSha}`, {
|
|
111
122
|
headers: {
|
|
112
123
|
'User-Agent': `Appium ${APPIUM_VER}`,
|
|
113
124
|
},
|
|
114
125
|
})
|
|
115
|
-
).data;
|
|
116
|
-
if (resBodyObj && resBodyObj.commit) {
|
|
117
|
-
if (resBodyObj.commit.committer && resBodyObj.commit.committer.date) {
|
|
118
|
-
return resBodyObj.commit.committer.date;
|
|
119
|
-
}
|
|
120
|
-
if (resBodyObj.commit.author && resBodyObj.commit.author.date) {
|
|
121
|
-
return resBodyObj.commit.author.date;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
126
|
+
).data?.tagger?.date;
|
|
124
127
|
} catch (ign) {}
|
|
125
128
|
return null;
|
|
126
129
|
}
|
|
@@ -139,7 +142,18 @@ function getBuildInfo() {
|
|
|
139
142
|
function checkNodeOk() {
|
|
140
143
|
const version = getNodeVersion();
|
|
141
144
|
if (!semver.satisfies(version, MIN_NODE_VERSION)) {
|
|
142
|
-
|
|
145
|
+
throw new Error(
|
|
146
|
+
`Node version must be at least ${MIN_NODE_VERSION}; current is ${version.version}`
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export async function checkNpmOk() {
|
|
152
|
+
const npmVersion = await getNpmVersion();
|
|
153
|
+
if (!semver.satisfies(npmVersion, MIN_NPM_VERSION)) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
`npm version must be at least ${MIN_NPM_VERSION}; current is ${npmVersion}. Run "npm install -g npm" to upgrade.`
|
|
156
|
+
);
|
|
143
157
|
}
|
|
144
158
|
}
|
|
145
159
|
|
|
@@ -203,11 +203,9 @@ export class ExtensionConfig {
|
|
|
203
203
|
|
|
204
204
|
if (!_.isEmpty(errorSummaries)) {
|
|
205
205
|
log.error(
|
|
206
|
-
`Appium encountered ${util.pluralize(
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
true
|
|
210
|
-
)} while validating ${this.configKey} found in manifest ${this.manifestPath}`
|
|
206
|
+
`Appium encountered ${util.pluralize('error', errorMap.size, true)} while validating ${
|
|
207
|
+
this.configKey
|
|
208
|
+
} found in manifest ${this.manifestPath}`
|
|
211
209
|
);
|
|
212
210
|
for (const summary of errorSummaries) {
|
|
213
211
|
log.error(summary);
|
|
@@ -219,7 +217,7 @@ export class ExtensionConfig {
|
|
|
219
217
|
log.warn(
|
|
220
218
|
`Appium encountered ${util.pluralize(
|
|
221
219
|
'warning',
|
|
222
|
-
|
|
220
|
+
warningMap.size,
|
|
223
221
|
true
|
|
224
222
|
)} while validating ${this.configKey} found in manifest ${this.manifestPath}`
|
|
225
223
|
);
|
package/lib/main.js
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
showBuildInfo,
|
|
20
20
|
validateTmpDir,
|
|
21
21
|
warnNodeDeprecations,
|
|
22
|
+
checkNpmOk,
|
|
22
23
|
} from './config';
|
|
23
24
|
import {readConfigFile} from './config-file';
|
|
24
25
|
import {loadExtensions, getActivePlugins, getActiveDrivers} from './extension';
|
|
@@ -37,6 +38,7 @@ const {resolveAppiumHome} = env;
|
|
|
37
38
|
async function preflightChecks(args, throwInsteadOfExit = false) {
|
|
38
39
|
try {
|
|
39
40
|
checkNodeOk();
|
|
41
|
+
await checkNpmOk();
|
|
40
42
|
if (args.longStacktrace) {
|
|
41
43
|
require('longjohn').async_trace_limit = -1;
|
|
42
44
|
}
|
|
@@ -207,20 +209,7 @@ async function init(args) {
|
|
|
207
209
|
// 1. command line args
|
|
208
210
|
// 2. config file
|
|
209
211
|
// 3. defaults from config file.
|
|
210
|
-
if (
|
|
211
|
-
// if the user has requested the 'driver' CLI, don't run the normal server,
|
|
212
|
-
// but instead pass control to the driver CLI
|
|
213
|
-
if (preConfigArgs.subcommand === DRIVER_TYPE) {
|
|
214
|
-
await runExtensionCommand(preConfigArgs, driverConfig);
|
|
215
|
-
return {};
|
|
216
|
-
}
|
|
217
|
-
if (preConfigArgs.subcommand === PLUGIN_TYPE) {
|
|
218
|
-
await runExtensionCommand(preConfigArgs, pluginConfig);
|
|
219
|
-
return {};
|
|
220
|
-
}
|
|
221
|
-
/* istanbul ignore next */
|
|
222
|
-
return {}; // should never happen
|
|
223
|
-
} else {
|
|
212
|
+
if (areServerCommandArgs(preConfigArgs)) {
|
|
224
213
|
const defaults = getDefaultsForSchema(false);
|
|
225
214
|
|
|
226
215
|
/** @type {ParsedArgs} */
|
|
@@ -267,6 +256,22 @@ async function init(args) {
|
|
|
267
256
|
driverConfig,
|
|
268
257
|
pluginConfig,
|
|
269
258
|
});
|
|
259
|
+
} else {
|
|
260
|
+
const extensionCommandArgs = /** @type {Args<import('appium/types').WithExtSubcommand>} */ (
|
|
261
|
+
preConfigArgs
|
|
262
|
+
);
|
|
263
|
+
// if the user has requested the 'driver' CLI, don't run the normal server,
|
|
264
|
+
// but instead pass control to the driver CLI
|
|
265
|
+
if (preConfigArgs.subcommand === DRIVER_TYPE) {
|
|
266
|
+
await runExtensionCommand(extensionCommandArgs, driverConfig);
|
|
267
|
+
return {};
|
|
268
|
+
}
|
|
269
|
+
if (preConfigArgs.subcommand === PLUGIN_TYPE) {
|
|
270
|
+
await runExtensionCommand(extensionCommandArgs, pluginConfig);
|
|
271
|
+
return {};
|
|
272
|
+
}
|
|
273
|
+
/* istanbul ignore next */
|
|
274
|
+
return {}; // should never happen
|
|
270
275
|
}
|
|
271
276
|
}
|
|
272
277
|
|
|
@@ -299,6 +304,7 @@ async function main(args) {
|
|
|
299
304
|
const serverUpdaters = getServerUpdaters(driverClasses, pluginClasses);
|
|
300
305
|
const extraMethodMap = getExtraMethodMap(driverClasses, pluginClasses);
|
|
301
306
|
|
|
307
|
+
/** @type {import('@appium/base-driver').ServerOpts} */
|
|
302
308
|
const serverOpts = {
|
|
303
309
|
routeConfiguringFunction,
|
|
304
310
|
port: parsedArgs.port,
|
|
@@ -307,6 +313,7 @@ async function main(args) {
|
|
|
307
313
|
basePath: parsedArgs.basePath,
|
|
308
314
|
serverUpdaters,
|
|
309
315
|
extraMethodMap,
|
|
316
|
+
cliArgs: parsedArgs,
|
|
310
317
|
};
|
|
311
318
|
if (parsedArgs.keepAliveTimeout) {
|
|
312
319
|
serverOpts.keepAliveTimeout = parsedArgs.keepAliveTimeout * 1000;
|
package/lib/schema/arg-spec.js
CHANGED
package/lib/schema/schema.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appium",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.43",
|
|
4
4
|
"description": "Automation for Apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -49,33 +49,43 @@
|
|
|
49
49
|
"dev:docs": "npm run build:docs:assets && npm run dev:docs:en",
|
|
50
50
|
"dev:docs:en": "mkdocs serve -f ./docs/mkdocs-en.yml",
|
|
51
51
|
"dev:docs:ja": "mkdocs serve -f ./docs/mkdocs-ja.yml",
|
|
52
|
+
"dev:docs:zh": "mkdocs serve -f ./docs/mkdocs-zh.yml",
|
|
52
53
|
"fix": "npm run lint -- --fix",
|
|
53
54
|
"postinstall": "node ./scripts/autoinstall-extensions.js",
|
|
54
55
|
"lint": "eslint -c ../../.eslintrc --ignore-path ../../.eslintignore .",
|
|
55
56
|
"prepare": "npm run build",
|
|
56
|
-
"publish:docs": "APPIUM_DOCS_PUBLISH=1 npm run build:docs",
|
|
57
|
+
"publish:docs": "cross-env APPIUM_DOCS_PUBLISH=1 npm run build:docs",
|
|
57
58
|
"test": "npm run test:unit",
|
|
58
|
-
"test:e2e": "mocha --timeout
|
|
59
|
+
"test:e2e": "mocha --timeout 1m --slow 30s \"./test/e2e/**/*.spec.js\"",
|
|
60
|
+
"test:smoke": "cross-env APPIUM_HOME=./local_appium_home node ./index.js driver install uiautomator2 && cross-env APPIUM_HOME=./local_appium_home node ./index.js driver list",
|
|
59
61
|
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
|
60
62
|
},
|
|
61
63
|
"dependencies": {
|
|
62
|
-
"@appium/base-driver": "^8.
|
|
63
|
-
"@appium/base-plugin": "^1.
|
|
64
|
-
"@appium/docutils": "^0.0.
|
|
65
|
-
"@appium/schema": "^0.0.
|
|
66
|
-
"@appium/support": "^2.59.
|
|
67
|
-
"@appium/test-support": "^1.
|
|
68
|
-
"@
|
|
64
|
+
"@appium/base-driver": "^8.7.0",
|
|
65
|
+
"@appium/base-plugin": "^1.10.2",
|
|
66
|
+
"@appium/docutils": "^0.0.10",
|
|
67
|
+
"@appium/schema": "^0.0.9",
|
|
68
|
+
"@appium/support": "^2.59.5",
|
|
69
|
+
"@appium/test-support": "^1.5.0",
|
|
70
|
+
"@appium/types": "^0.4.0",
|
|
71
|
+
"@babel/runtime": "7.18.9",
|
|
69
72
|
"@sidvind/better-ajv-errors": "2.0.0",
|
|
73
|
+
"@types/argparse": "2.0.10",
|
|
74
|
+
"@types/bluebird": "3.5.36",
|
|
75
|
+
"@types/fancy-log": "2.0.0",
|
|
76
|
+
"@types/semver": "7.3.10",
|
|
77
|
+
"@types/teen_process": "1.16.1",
|
|
78
|
+
"@types/wrap-ansi": "3.0.0",
|
|
70
79
|
"ajv": "8.11.0",
|
|
71
80
|
"ajv-formats": "2.1.1",
|
|
72
81
|
"argparse": "2.0.1",
|
|
73
|
-
"async-lock": "1.3.
|
|
82
|
+
"async-lock": "1.3.2",
|
|
74
83
|
"asyncbox": "2.9.2",
|
|
75
84
|
"axios": "0.27.2",
|
|
76
85
|
"bluebird": "3.7.2",
|
|
86
|
+
"cross-env": "7.0.3",
|
|
77
87
|
"find-up": "5.0.0",
|
|
78
|
-
"lilconfig": "2.0.
|
|
88
|
+
"lilconfig": "2.0.6",
|
|
79
89
|
"lodash": "4.17.21",
|
|
80
90
|
"longjohn": "0.2.12",
|
|
81
91
|
"npmlog": "6.0.2",
|
|
@@ -84,19 +94,19 @@
|
|
|
84
94
|
"resolve-from": "5.0.0",
|
|
85
95
|
"semver": "7.3.7",
|
|
86
96
|
"source-map-support": "0.5.21",
|
|
87
|
-
"supports-color": "8.1.1",
|
|
88
97
|
"teen_process": "1.16.0",
|
|
89
|
-
"
|
|
90
|
-
"
|
|
98
|
+
"type-fest": "2.18.0",
|
|
99
|
+
"winston": "3.8.1",
|
|
100
|
+
"wrap-ansi": "7.0.0",
|
|
91
101
|
"yaml": "2.1.1"
|
|
92
102
|
},
|
|
93
103
|
"engines": {
|
|
94
104
|
"node": ">=14",
|
|
95
|
-
"npm": ">=
|
|
105
|
+
"npm": ">=8"
|
|
96
106
|
},
|
|
97
107
|
"publishConfig": {
|
|
98
108
|
"access": "public",
|
|
99
109
|
"tag": "next"
|
|
100
110
|
},
|
|
101
|
-
"gitHead": "
|
|
111
|
+
"gitHead": "c58f32441daba3aae9768a57d0a412fe92f4b587"
|
|
102
112
|
}
|
|
@@ -28,11 +28,17 @@ let PLUGIN_TYPE;
|
|
|
28
28
|
let loadExtensions;
|
|
29
29
|
|
|
30
30
|
const {env, util, logger} = require('@appium/support');
|
|
31
|
+
const _ = require('lodash');
|
|
32
|
+
const wrap = _.partial(
|
|
33
|
+
require('wrap-ansi'),
|
|
34
|
+
_,
|
|
35
|
+
process.stderr.columns ?? process.stdout.columns ?? 25
|
|
36
|
+
);
|
|
31
37
|
|
|
32
38
|
const ora = require('ora');
|
|
33
39
|
|
|
34
40
|
const log = (message) => {
|
|
35
|
-
console.error(`[Appium] ${message}`);
|
|
41
|
+
console.error(wrap(`[Appium] ${message}`));
|
|
36
42
|
};
|
|
37
43
|
|
|
38
44
|
const spinner = ora({
|
|
@@ -59,7 +65,8 @@ try {
|
|
|
59
65
|
}
|
|
60
66
|
|
|
61
67
|
async function main() {
|
|
62
|
-
if
|
|
68
|
+
// if we're doing `npm install -g appium` then we will assume we don't have a local appium.
|
|
69
|
+
if (!process.env.npm_config_global && (await env.hasAppiumDependency())) {
|
|
63
70
|
log(`Found local Appium installation; skipping automatic installation of extensions.`);
|
|
64
71
|
return;
|
|
65
72
|
}
|
|
@@ -74,7 +81,8 @@ async function main() {
|
|
|
74
81
|
|
|
75
82
|
if (!driverEnv && !pluginEnv) {
|
|
76
83
|
spinner.succeed(
|
|
77
|
-
|
|
84
|
+
wrap(`No drivers or plugins to automatically install.
|
|
85
|
+
If desired, provide arguments with comma-separated values "--drivers=<known_driver>[,known_driver...]" and/or "--plugins=<known_plugin>[,known_plugin...]" to the "npm install appium" command. The specified extensions will be installed automatically with Appium. Note: to see the list of known extensions, run "appium <driver|plugin> list".`)
|
|
78
86
|
);
|
|
79
87
|
return;
|
|
80
88
|
}
|
package/test.d.ts
ADDED
package/test.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// @ts-check
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This module is here to re-export `@appium/test-support` for Appium extensions.
|
|
7
|
+
*
|
|
8
|
+
* @see https://npm.im/@appium/test-support
|
|
9
|
+
* @example
|
|
10
|
+
* const { getPort } = require('appium/test');
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
module.exports = require('@appium/test-support');
|
package/types/cli.ts
CHANGED
|
@@ -1,18 +1,7 @@
|
|
|
1
1
|
import {ServerArgs} from '@appium/types';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
EXT_SUBCOMMAND_LIST,
|
|
6
|
-
EXT_SUBCOMMAND_RUN,
|
|
7
|
-
EXT_SUBCOMMAND_UNINSTALL,
|
|
8
|
-
EXT_SUBCOMMAND_UPDATE,
|
|
9
|
-
PLUGIN_TYPE as PLUGIN_SUBCOMMAND,
|
|
10
|
-
SERVER_SUBCOMMAND,
|
|
11
|
-
} from '../lib/constants';
|
|
12
|
-
|
|
13
|
-
export type ServerSubcommand = typeof SERVER_SUBCOMMAND;
|
|
14
|
-
export type DriverSubcommand = typeof DRIVER_SUBCOMMAND;
|
|
15
|
-
export type PluginSubcommand = typeof PLUGIN_SUBCOMMAND;
|
|
2
|
+
export type ServerSubcommand = 'server';
|
|
3
|
+
export type DriverSubcommand = 'driver';
|
|
4
|
+
export type PluginSubcommand = 'plugin';
|
|
16
5
|
|
|
17
6
|
/**
|
|
18
7
|
* Possible subcommands for the `appium` CLI.
|
|
@@ -24,11 +13,11 @@ export type CliSubcommand = ServerSubcommand | DriverSubcommand | PluginSubcomma
|
|
|
24
13
|
* {@linkcode PluginSubcommand}.
|
|
25
14
|
*/
|
|
26
15
|
export type CliExtensionSubcommand =
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
16
|
+
| 'install'
|
|
17
|
+
| 'list'
|
|
18
|
+
| 'run'
|
|
19
|
+
| 'uninstall'
|
|
20
|
+
| 'update';
|
|
32
21
|
|
|
33
22
|
/**
|
|
34
23
|
* Random stuff that may appear in the parsed args which has no equivalent in a
|
|
@@ -103,6 +92,21 @@ export interface ExtArgs extends WithExtSubcommand {
|
|
|
103
92
|
* Subcommands of `plugin` subcommand
|
|
104
93
|
*/
|
|
105
94
|
pluginCommand?: CliExtensionSubcommand;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Output JSON instead of human-readable text
|
|
98
|
+
*/
|
|
99
|
+
json?: boolean;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Output nothing
|
|
103
|
+
*/
|
|
104
|
+
suppressOutput?: boolean;
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Extra args to pass to extension scripts
|
|
108
|
+
*/
|
|
109
|
+
extraArgs?: string[];
|
|
106
110
|
}
|
|
107
111
|
|
|
108
112
|
/**
|