appium 2.0.0-beta.41 → 2.0.0-beta.44
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 +0 -1
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +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 +5 -4
- 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 +5 -3
- package/build/lib/config.d.ts +1 -0
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +19 -4
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +21 -31
- package/build/lib/schema/cli-transformers.d.ts.map +1 -1
- package/build/lib/schema/cli-transformers.js +2 -2
- package/build/lib/utils.d.ts +8 -0
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +62 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/cli.d.ts +12 -0
- package/build/types/cli.d.ts.map +1 -1
- package/lib/appium.js +5 -0
- package/lib/cli/args.js +2 -2
- package/lib/cli/driver-command.js +2 -2
- package/lib/cli/extension-command.js +5 -3
- 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 +22 -2
- package/lib/main.js +25 -31
- package/lib/schema/cli-transformers.js +3 -2
- package/lib/utils.js +60 -0
- package/package.json +15 -16
- package/types/cli.ts +15 -0
- package/test.d.ts +0 -7
- package/test.js +0 -13
|
@@ -576,13 +576,14 @@ class ExtensionCommand {
|
|
|
576
576
|
// this is a helper method, 'ext' is assumed to already be installed here, and of the npm
|
|
577
577
|
// install type
|
|
578
578
|
const {version, pkgName} = this.config.installedExtensions[ext];
|
|
579
|
+
/** @type {string?} */
|
|
579
580
|
let unsafeUpdate = await npm.getLatestVersion(this.config.appiumHome, pkgName);
|
|
580
581
|
let safeUpdate = await npm.getLatestSafeUpgradeVersion(
|
|
581
582
|
this.config.appiumHome,
|
|
582
583
|
pkgName,
|
|
583
584
|
version
|
|
584
585
|
);
|
|
585
|
-
if (!util.compareVersions(unsafeUpdate, '>', version)) {
|
|
586
|
+
if (unsafeUpdate !== null && !util.compareVersions(unsafeUpdate, '>', version)) {
|
|
586
587
|
// the latest version is not greater than the current version, so there's no possible update
|
|
587
588
|
unsafeUpdate = null;
|
|
588
589
|
safeUpdate = null;
|
|
@@ -628,7 +629,7 @@ class ExtensionCommand {
|
|
|
628
629
|
* @param {RunOptions} opts
|
|
629
630
|
* @return {Promise<RunOutput>}
|
|
630
631
|
*/
|
|
631
|
-
async _run({installSpec, scriptName}) {
|
|
632
|
+
async _run({installSpec, scriptName, extraArgs = []}) {
|
|
632
633
|
if (!this.config.isInstalled(installSpec)) {
|
|
633
634
|
throw this._createFatalError(`The ${this.type} "${installSpec}" is not installed`);
|
|
634
635
|
}
|
|
@@ -657,7 +658,7 @@ class ExtensionCommand {
|
|
|
657
658
|
);
|
|
658
659
|
}
|
|
659
660
|
|
|
660
|
-
const runner = new SubProcess(process.execPath, [extScripts[scriptName]], {
|
|
661
|
+
const runner = new SubProcess(process.execPath, [extScripts[scriptName], ...extraArgs], {
|
|
661
662
|
cwd: this.config.getInstallPath(installSpec),
|
|
662
663
|
});
|
|
663
664
|
|
|
@@ -755,6 +756,7 @@ export {ExtensionCommand};
|
|
|
755
756
|
* @typedef RunOptions
|
|
756
757
|
* @property {string} installSpec - name of the extension to run a script from
|
|
757
758
|
* @property {string} scriptName - name of the script to run
|
|
759
|
+
* @property {string[]} [extraArgs] - arguments to pass to the script
|
|
758
760
|
*/
|
|
759
761
|
|
|
760
762
|
/**
|
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,6 +28,15 @@ 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
|
+
|
|
31
40
|
/**
|
|
32
41
|
* @param {boolean} [useGithubApiFallback]
|
|
33
42
|
*/
|
|
@@ -133,7 +142,18 @@ function getBuildInfo() {
|
|
|
133
142
|
function checkNodeOk() {
|
|
134
143
|
const version = getNodeVersion();
|
|
135
144
|
if (!semver.satisfies(version, MIN_NODE_VERSION)) {
|
|
136
|
-
|
|
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
|
+
);
|
|
137
157
|
}
|
|
138
158
|
}
|
|
139
159
|
|
package/lib/main.js
CHANGED
|
@@ -4,7 +4,7 @@ import {init as logsinkInit} from './logsink'; // this import needs to come firs
|
|
|
4
4
|
import logger from './logger'; // logger needs to remain second
|
|
5
5
|
// @ts-ignore
|
|
6
6
|
import {routeConfiguringFunction as makeRouter, server as baseServer} from '@appium/base-driver';
|
|
7
|
-
import {logger as logFactory, util, env
|
|
7
|
+
import {logger as logFactory, util, env} from '@appium/support';
|
|
8
8
|
import {asyncify} from 'asyncbox';
|
|
9
9
|
import _ from 'lodash';
|
|
10
10
|
import {AppiumDriver} from './appium';
|
|
@@ -15,21 +15,20 @@ import {
|
|
|
15
15
|
checkNodeOk,
|
|
16
16
|
getGitRev,
|
|
17
17
|
getNonDefaultServerArgs,
|
|
18
|
-
rootDir,
|
|
19
18
|
showConfig,
|
|
20
19
|
showBuildInfo,
|
|
21
20
|
validateTmpDir,
|
|
22
21
|
warnNodeDeprecations,
|
|
22
|
+
checkNpmOk,
|
|
23
23
|
} from './config';
|
|
24
24
|
import {readConfigFile} from './config-file';
|
|
25
25
|
import {loadExtensions, getActivePlugins, getActiveDrivers} from './extension';
|
|
26
26
|
import {DRIVER_TYPE, PLUGIN_TYPE, SERVER_SUBCOMMAND} from './constants';
|
|
27
27
|
import registerNode from './grid-register';
|
|
28
28
|
import {getDefaultsForSchema, validate} from './schema/schema';
|
|
29
|
-
import {inspect} from './utils';
|
|
30
|
-
import path from 'path';
|
|
29
|
+
import {inspect, adjustNodePath} from './utils';
|
|
31
30
|
|
|
32
|
-
const {resolveAppiumHome
|
|
31
|
+
const {resolveAppiumHome} = env;
|
|
33
32
|
|
|
34
33
|
/**
|
|
35
34
|
*
|
|
@@ -39,6 +38,7 @@ const {resolveAppiumHome, hasAppiumDependency} = env;
|
|
|
39
38
|
async function preflightChecks(args, throwInsteadOfExit = false) {
|
|
40
39
|
try {
|
|
41
40
|
checkNodeOk();
|
|
41
|
+
await checkNpmOk();
|
|
42
42
|
if (args.longStacktrace) {
|
|
43
43
|
require('longjohn').async_trace_limit = -1;
|
|
44
44
|
}
|
|
@@ -172,18 +172,7 @@ function areServerCommandArgs(args) {
|
|
|
172
172
|
async function init(args) {
|
|
173
173
|
const appiumHome = args?.appiumHome ?? (await resolveAppiumHome());
|
|
174
174
|
|
|
175
|
-
|
|
176
|
-
// of `appium`, which lives wherever it lives (see `rootDir`).
|
|
177
|
-
if (!(await hasAppiumDependency(appiumHome))) {
|
|
178
|
-
try {
|
|
179
|
-
await fs.mkdirp(path.join(appiumHome, 'node_modules'));
|
|
180
|
-
await fs.symlink(rootDir, path.join(appiumHome, 'node_modules', 'appium'), 'junction');
|
|
181
|
-
} catch (err) {
|
|
182
|
-
if (err.code !== 'EEXIST') {
|
|
183
|
-
throw new Error(`Unable to create symlink to appium: ${err.message}`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
175
|
+
adjustNodePath();
|
|
187
176
|
|
|
188
177
|
const {driverConfig, pluginConfig} = await loadExtensions(appiumHome);
|
|
189
178
|
|
|
@@ -222,20 +211,7 @@ async function init(args) {
|
|
|
222
211
|
// 1. command line args
|
|
223
212
|
// 2. config file
|
|
224
213
|
// 3. defaults from config file.
|
|
225
|
-
if (
|
|
226
|
-
// if the user has requested the 'driver' CLI, don't run the normal server,
|
|
227
|
-
// but instead pass control to the driver CLI
|
|
228
|
-
if (preConfigArgs.subcommand === DRIVER_TYPE) {
|
|
229
|
-
await runExtensionCommand(preConfigArgs, driverConfig);
|
|
230
|
-
return {};
|
|
231
|
-
}
|
|
232
|
-
if (preConfigArgs.subcommand === PLUGIN_TYPE) {
|
|
233
|
-
await runExtensionCommand(preConfigArgs, pluginConfig);
|
|
234
|
-
return {};
|
|
235
|
-
}
|
|
236
|
-
/* istanbul ignore next */
|
|
237
|
-
return {}; // should never happen
|
|
238
|
-
} else {
|
|
214
|
+
if (areServerCommandArgs(preConfigArgs)) {
|
|
239
215
|
const defaults = getDefaultsForSchema(false);
|
|
240
216
|
|
|
241
217
|
/** @type {ParsedArgs} */
|
|
@@ -282,6 +258,22 @@ async function init(args) {
|
|
|
282
258
|
driverConfig,
|
|
283
259
|
pluginConfig,
|
|
284
260
|
});
|
|
261
|
+
} else {
|
|
262
|
+
const extensionCommandArgs = /** @type {Args<import('appium/types').WithExtSubcommand>} */ (
|
|
263
|
+
preConfigArgs
|
|
264
|
+
);
|
|
265
|
+
// if the user has requested the 'driver' CLI, don't run the normal server,
|
|
266
|
+
// but instead pass control to the driver CLI
|
|
267
|
+
if (preConfigArgs.subcommand === DRIVER_TYPE) {
|
|
268
|
+
await runExtensionCommand(extensionCommandArgs, driverConfig);
|
|
269
|
+
return {};
|
|
270
|
+
}
|
|
271
|
+
if (preConfigArgs.subcommand === PLUGIN_TYPE) {
|
|
272
|
+
await runExtensionCommand(extensionCommandArgs, pluginConfig);
|
|
273
|
+
return {};
|
|
274
|
+
}
|
|
275
|
+
/* istanbul ignore next */
|
|
276
|
+
return {}; // should never happen
|
|
285
277
|
}
|
|
286
278
|
}
|
|
287
279
|
|
|
@@ -314,6 +306,7 @@ async function main(args) {
|
|
|
314
306
|
const serverUpdaters = getServerUpdaters(driverClasses, pluginClasses);
|
|
315
307
|
const extraMethodMap = getExtraMethodMap(driverClasses, pluginClasses);
|
|
316
308
|
|
|
309
|
+
/** @type {import('@appium/base-driver').ServerOpts} */
|
|
317
310
|
const serverOpts = {
|
|
318
311
|
routeConfiguringFunction,
|
|
319
312
|
port: parsedArgs.port,
|
|
@@ -322,6 +315,7 @@ async function main(args) {
|
|
|
322
315
|
basePath: parsedArgs.basePath,
|
|
323
316
|
serverUpdaters,
|
|
324
317
|
extraMethodMap,
|
|
318
|
+
cliArgs: parsedArgs,
|
|
325
319
|
};
|
|
326
320
|
if (parsedArgs.keepAliveTimeout) {
|
|
327
321
|
serverOpts.keepAliveTimeout = parsedArgs.keepAliveTimeout * 1000;
|
|
@@ -94,8 +94,9 @@ export const transformers = {
|
|
|
94
94
|
json = readFileSync(jsonOrPath, 'utf8');
|
|
95
95
|
loadedFromFile = true;
|
|
96
96
|
} catch (err) {
|
|
97
|
-
// unreadable files don't count
|
|
98
|
-
if
|
|
97
|
+
// unreadable files don't count.
|
|
98
|
+
// also `ENAMETOOLONG` can happen if we try to open a file that's a huge JSON string.
|
|
99
|
+
if (err.code !== 'ENOENT' && err.code !== 'ENAMETOOLONG') {
|
|
99
100
|
throw err;
|
|
100
101
|
}
|
|
101
102
|
}
|
package/lib/utils.js
CHANGED
|
@@ -2,6 +2,8 @@ import _ from 'lodash';
|
|
|
2
2
|
import logger from './logger';
|
|
3
3
|
import {processCapabilities, PROTOCOLS} from '@appium/base-driver';
|
|
4
4
|
import {inspect as dump} from 'util';
|
|
5
|
+
import {node} from '@appium/support';
|
|
6
|
+
import path from 'path';
|
|
5
7
|
|
|
6
8
|
const W3C_APPIUM_PREFIX = 'appium';
|
|
7
9
|
|
|
@@ -209,6 +211,63 @@ function getPackageVersion(pkgName) {
|
|
|
209
211
|
return pkgInfo.version;
|
|
210
212
|
}
|
|
211
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Adjusts NODE_PATH environment variable,
|
|
216
|
+
* so drivers and plugins could load their peer dependencies.
|
|
217
|
+
* Read https://nodejs.org/api/modules.html#loading-from-the-global-folders
|
|
218
|
+
* for more details.
|
|
219
|
+
* @returns {void}
|
|
220
|
+
*/
|
|
221
|
+
function adjustNodePath() {
|
|
222
|
+
const selfRoot = node.getModuleRootSync('appium', __filename);
|
|
223
|
+
if (!selfRoot || path.dirname(selfRoot).length >= selfRoot.length) {
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
const nodeModulesRoot = path.dirname(selfRoot);
|
|
227
|
+
|
|
228
|
+
const refreshRequirePaths = () => {
|
|
229
|
+
try {
|
|
230
|
+
// ! This hack allows us to avoid modification of import
|
|
231
|
+
// ! statements in client modules. It uses a private API though,
|
|
232
|
+
// ! so it could break (maybe, eventually).
|
|
233
|
+
// See https://gist.github.com/branneman/8048520#7-the-hack
|
|
234
|
+
// @ts-ignore
|
|
235
|
+
require('module').Module._initPaths();
|
|
236
|
+
return true;
|
|
237
|
+
} catch (e) {
|
|
238
|
+
logger.info(`Module init paths cannot be refreshed. Original error: ${e.message}`);
|
|
239
|
+
return false;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
if (!process.env.NODE_PATH) {
|
|
244
|
+
process.env.NODE_PATH = nodeModulesRoot;
|
|
245
|
+
if (refreshRequirePaths()) {
|
|
246
|
+
logger.info(`Setting NODE_PATH to '${nodeModulesRoot}'`);
|
|
247
|
+
process.env.APPIUM_OMIT_PEER_DEPS = '1';
|
|
248
|
+
} else {
|
|
249
|
+
delete process.env.NODE_PATH;
|
|
250
|
+
}
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const nodePathParts = process.env.NODE_PATH.split(path.delimiter);
|
|
255
|
+
if (nodePathParts.includes(nodeModulesRoot)) {
|
|
256
|
+
logger.info(`NODE_PATH already includes '${nodeModulesRoot}'`);
|
|
257
|
+
process.env.APPIUM_OMIT_PEER_DEPS = '1';
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
nodePathParts.push(nodeModulesRoot);
|
|
262
|
+
process.env.NODE_PATH = nodePathParts.join(path.delimiter);
|
|
263
|
+
if (refreshRequirePaths()) {
|
|
264
|
+
logger.info(`Adding '${nodeModulesRoot}' to NODE_PATH`);
|
|
265
|
+
process.env.APPIUM_OMIT_PEER_DEPS = '1';
|
|
266
|
+
} else {
|
|
267
|
+
process.env.NODE_PATH = _.without(nodePathParts, nodeModulesRoot).join(path.delimiter);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
212
271
|
/**
|
|
213
272
|
* Pulls the initial values of Appium settings from the given capabilities argument.
|
|
214
273
|
* Each setting item must satisfy the following format:
|
|
@@ -250,6 +309,7 @@ export {
|
|
|
250
309
|
getPackageVersion,
|
|
251
310
|
pullSettings,
|
|
252
311
|
removeAppiumPrefixes,
|
|
312
|
+
adjustNodePath,
|
|
253
313
|
};
|
|
254
314
|
|
|
255
315
|
/**
|
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.44",
|
|
4
4
|
"description": "Automation for Apps.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"automation",
|
|
@@ -37,7 +37,6 @@
|
|
|
37
37
|
"driver.*",
|
|
38
38
|
"support.*",
|
|
39
39
|
"plugin.*",
|
|
40
|
-
"test.*",
|
|
41
40
|
"scripts/autoinstall-extensions.js",
|
|
42
41
|
"types"
|
|
43
42
|
],
|
|
@@ -54,26 +53,25 @@
|
|
|
54
53
|
"postinstall": "node ./scripts/autoinstall-extensions.js",
|
|
55
54
|
"lint": "eslint -c ../../.eslintrc --ignore-path ../../.eslintignore .",
|
|
56
55
|
"prepare": "npm run build",
|
|
57
|
-
"publish:docs": "APPIUM_DOCS_PUBLISH=1 npm run build:docs",
|
|
56
|
+
"publish:docs": "cross-env APPIUM_DOCS_PUBLISH=1 npm run build:docs",
|
|
58
57
|
"test": "npm run test:unit",
|
|
59
58
|
"test:e2e": "mocha --timeout 1m --slow 30s \"./test/e2e/**/*.spec.js\"",
|
|
60
|
-
"test:smoke": "node ./index.js
|
|
59
|
+
"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",
|
|
61
60
|
"test:unit": "mocha \"./test/unit/**/*.spec.js\""
|
|
62
61
|
},
|
|
63
62
|
"dependencies": {
|
|
64
|
-
"@appium/base-driver": "^8.
|
|
65
|
-
"@appium/base-plugin": "^1.10.
|
|
66
|
-
"@appium/docutils": "^0.0.
|
|
67
|
-
"@appium/schema": "^0.0.
|
|
68
|
-
"@appium/support": "^2.
|
|
69
|
-
"@appium/
|
|
70
|
-
"@
|
|
71
|
-
"@babel/runtime": "7.18.9",
|
|
63
|
+
"@appium/base-driver": "^8.7.1",
|
|
64
|
+
"@appium/base-plugin": "^1.10.3",
|
|
65
|
+
"@appium/docutils": "^0.0.11",
|
|
66
|
+
"@appium/schema": "^0.0.9",
|
|
67
|
+
"@appium/support": "^2.60.0",
|
|
68
|
+
"@appium/types": "^0.4.1",
|
|
69
|
+
"@babel/runtime": "7.19.0",
|
|
72
70
|
"@sidvind/better-ajv-errors": "2.0.0",
|
|
73
71
|
"@types/argparse": "2.0.10",
|
|
74
72
|
"@types/bluebird": "3.5.36",
|
|
75
73
|
"@types/fancy-log": "2.0.0",
|
|
76
|
-
"@types/semver": "7.3.
|
|
74
|
+
"@types/semver": "7.3.12",
|
|
77
75
|
"@types/teen_process": "1.16.1",
|
|
78
76
|
"@types/wrap-ansi": "3.0.0",
|
|
79
77
|
"ajv": "8.11.0",
|
|
@@ -83,6 +81,7 @@
|
|
|
83
81
|
"asyncbox": "2.9.2",
|
|
84
82
|
"axios": "0.27.2",
|
|
85
83
|
"bluebird": "3.7.2",
|
|
84
|
+
"cross-env": "7.0.3",
|
|
86
85
|
"find-up": "5.0.0",
|
|
87
86
|
"lilconfig": "2.0.6",
|
|
88
87
|
"lodash": "4.17.21",
|
|
@@ -94,18 +93,18 @@
|
|
|
94
93
|
"semver": "7.3.7",
|
|
95
94
|
"source-map-support": "0.5.21",
|
|
96
95
|
"teen_process": "1.16.0",
|
|
97
|
-
"type-fest": "2.
|
|
96
|
+
"type-fest": "2.19.0",
|
|
98
97
|
"winston": "3.8.1",
|
|
99
98
|
"wrap-ansi": "7.0.0",
|
|
100
99
|
"yaml": "2.1.1"
|
|
101
100
|
},
|
|
102
101
|
"engines": {
|
|
103
102
|
"node": ">=14",
|
|
104
|
-
"npm": ">=
|
|
103
|
+
"npm": ">=8"
|
|
105
104
|
},
|
|
106
105
|
"publishConfig": {
|
|
107
106
|
"access": "public",
|
|
108
107
|
"tag": "next"
|
|
109
108
|
},
|
|
110
|
-
"gitHead": "
|
|
109
|
+
"gitHead": "c26af8f85230ac65cbc19f08f763942f74b0eb0c"
|
|
111
110
|
}
|
package/types/cli.ts
CHANGED
|
@@ -92,6 +92,21 @@ export interface ExtArgs extends WithExtSubcommand {
|
|
|
92
92
|
* Subcommands of `plugin` subcommand
|
|
93
93
|
*/
|
|
94
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[];
|
|
95
110
|
}
|
|
96
111
|
|
|
97
112
|
/**
|
package/test.d.ts
DELETED
package/test.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
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');
|