appium 2.0.0-beta.46 → 2.0.0-beta.48
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/README.md +145 -44
- package/build/lib/appium.d.ts +3 -103
- package/build/lib/appium.d.ts.map +1 -1
- package/build/lib/appium.js +679 -549
- package/build/lib/appium.js.map +1 -1
- package/build/lib/cli/args.js +247 -127
- package/build/lib/cli/args.js.map +1 -1
- package/build/lib/cli/driver-command.d.ts +24 -5
- package/build/lib/cli/driver-command.d.ts.map +1 -1
- package/build/lib/cli/driver-command.js +78 -88
- package/build/lib/cli/driver-command.js.map +1 -1
- package/build/lib/cli/extension-command.d.ts +33 -24
- package/build/lib/cli/extension-command.d.ts.map +1 -1
- package/build/lib/cli/extension-command.js +729 -512
- package/build/lib/cli/extension-command.js.map +1 -1
- package/build/lib/cli/extension.d.ts +7 -6
- package/build/lib/cli/extension.d.ts.map +1 -1
- package/build/lib/cli/extension.js +68 -65
- package/build/lib/cli/extension.js.map +1 -1
- package/build/lib/cli/parser.d.ts +3 -3
- package/build/lib/cli/parser.d.ts.map +1 -1
- package/build/lib/cli/parser.js +234 -192
- package/build/lib/cli/parser.js.map +1 -1
- package/build/lib/cli/plugin-command.js +58 -87
- package/build/lib/cli/plugin-command.js.map +1 -1
- package/build/lib/cli/utils.js +66 -69
- package/build/lib/cli/utils.js.map +1 -1
- package/build/lib/config-file.d.ts.map +1 -1
- package/build/lib/config-file.js +189 -120
- package/build/lib/config-file.js.map +1 -1
- package/build/lib/config.d.ts.map +1 -1
- package/build/lib/config.js +254 -213
- package/build/lib/config.js.map +1 -1
- package/build/lib/constants.d.ts +6 -5
- package/build/lib/constants.d.ts.map +1 -1
- package/build/lib/constants.js +65 -59
- package/build/lib/constants.js.map +1 -1
- package/build/lib/extension/driver-config.js +199 -164
- package/build/lib/extension/driver-config.js.map +1 -1
- package/build/lib/extension/extension-config.d.ts +33 -26
- package/build/lib/extension/extension-config.d.ts.map +1 -1
- package/build/lib/extension/extension-config.js +541 -396
- package/build/lib/extension/extension-config.js.map +1 -1
- package/build/lib/extension/index.js +98 -68
- package/build/lib/extension/index.js.map +1 -1
- 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 +118 -0
- package/build/lib/extension/manifest-migrations.js.map +1 -0
- package/build/lib/extension/manifest.d.ts +35 -63
- package/build/lib/extension/manifest.d.ts.map +1 -1
- package/build/lib/extension/manifest.js +500 -240
- package/build/lib/extension/manifest.js.map +1 -1
- package/build/lib/extension/package-changed.js +57 -61
- package/build/lib/extension/package-changed.js.map +1 -1
- package/build/lib/extension/plugin-config.d.ts +2 -3
- package/build/lib/extension/plugin-config.d.ts.map +1 -1
- package/build/lib/extension/plugin-config.js +94 -70
- package/build/lib/extension/plugin-config.js.map +1 -1
- package/build/lib/grid-register.js +119 -137
- package/build/lib/grid-register.js.map +1 -1
- package/build/lib/logger.d.ts +1 -1
- package/build/lib/logger.d.ts.map +1 -1
- package/build/lib/logger.js +5 -15
- package/build/lib/logger.js.map +1 -1
- package/build/lib/logsink.d.ts.map +1 -1
- package/build/lib/logsink.js +189 -183
- package/build/lib/logsink.js.map +1 -1
- package/build/lib/main.d.ts +19 -12
- package/build/lib/main.d.ts.map +1 -1
- package/build/lib/main.js +330 -304
- package/build/lib/main.js.map +1 -1
- package/build/lib/schema/arg-spec.js +153 -108
- package/build/lib/schema/arg-spec.js.map +1 -1
- package/build/lib/schema/cli-args.js +203 -164
- package/build/lib/schema/cli-args.js.map +1 -1
- package/build/lib/schema/cli-transformers.js +117 -72
- package/build/lib/schema/cli-transformers.js.map +1 -1
- package/build/lib/schema/index.js +17 -32
- package/build/lib/schema/index.js.map +1 -1
- package/build/lib/schema/keywords.js +125 -67
- package/build/lib/schema/keywords.js.map +1 -1
- package/build/lib/schema/schema.d.ts.map +1 -1
- package/build/lib/schema/schema.js +582 -417
- package/build/lib/schema/schema.js.map +1 -1
- package/build/lib/utils.d.ts +41 -255
- package/build/lib/utils.d.ts.map +1 -1
- package/build/lib/utils.js +342 -193
- package/build/lib/utils.js.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/types/cli.d.ts +45 -34
- package/build/types/cli.d.ts.map +1 -1
- package/build/types/cli.js +3 -0
- package/build/types/cli.js.map +1 -0
- package/build/types/index.d.ts +1 -2
- package/build/types/index.d.ts.map +1 -1
- 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 +19 -0
- package/build/types/manifest/index.d.ts.map +1 -0
- package/build/types/manifest/index.js +40 -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/lib/appium.js +1 -1
- package/lib/cli/args.js +1 -1
- package/lib/cli/driver-command.js +17 -0
- package/lib/cli/extension-command.js +119 -65
- package/lib/cli/extension.js +9 -8
- package/lib/cli/parser.js +2 -2
- package/lib/config-file.js +2 -3
- package/lib/config.js +3 -2
- package/lib/constants.js +7 -5
- package/lib/extension/extension-config.js +52 -47
- package/lib/extension/manifest-migrations.js +120 -0
- package/lib/extension/manifest.js +184 -103
- package/lib/extension/plugin-config.js +1 -2
- package/lib/logsink.js +26 -5
- package/lib/main.js +58 -50
- package/lib/schema/schema.js +6 -1
- package/lib/utils.js +62 -0
- package/package.json +24 -25
- package/scripts/autoinstall-extensions.js +78 -26
- package/types/cli.ts +81 -42
- package/types/index.ts +1 -2
- package/types/manifest/README.md +30 -0
- package/types/manifest/base.ts +158 -0
- package/types/manifest/index.ts +27 -0
- package/types/manifest/v3.ts +161 -0
- package/build/types/appium-manifest.d.ts +0 -59
- package/build/types/appium-manifest.d.ts.map +0 -1
- package/build/types/extension-manifest.d.ts +0 -55
- package/build/types/extension-manifest.d.ts.map +0 -1
- package/types/appium-manifest.ts +0 -73
- package/types/extension-manifest.ts +0 -64
|
@@ -18,6 +18,16 @@ const UPDATE_ALL = 'installed';
|
|
|
18
18
|
class NotUpdatableError extends Error {}
|
|
19
19
|
class NoUpdatesAvailableError extends Error {}
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Omits `driverName`/`pluginName` props from the receipt to make a {@linkcode ExtManifest}
|
|
23
|
+
* @template {ExtensionType} ExtType
|
|
24
|
+
* @param {ExtInstallReceipt<ExtType>} receipt
|
|
25
|
+
* @returns {ExtManifest<ExtType>}
|
|
26
|
+
*/
|
|
27
|
+
function receiptToManifest(receipt) {
|
|
28
|
+
return /** @type {ExtManifest<ExtType>} */ (_.omit(receipt, 'driverName', 'pluginName'));
|
|
29
|
+
}
|
|
30
|
+
|
|
21
31
|
/**
|
|
22
32
|
* @template {ExtensionType} ExtType
|
|
23
33
|
*/
|
|
@@ -128,10 +138,14 @@ class ExtensionCommand {
|
|
|
128
138
|
// also don't need to check for updates on non-npm exts
|
|
129
139
|
continue;
|
|
130
140
|
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
141
|
+
try {
|
|
142
|
+
const updates = await this.checkForExtensionUpdate(ext);
|
|
143
|
+
data.updateVersion = updates.safeUpdate;
|
|
144
|
+
data.unsafeUpdateVersion = updates.unsafeUpdate;
|
|
145
|
+
data.upToDate = updates.safeUpdate === null && updates.unsafeUpdate === null;
|
|
146
|
+
} catch (e) {
|
|
147
|
+
data.updateError = e.message;
|
|
148
|
+
}
|
|
135
149
|
}
|
|
136
150
|
});
|
|
137
151
|
|
|
@@ -149,8 +163,15 @@ class ExtensionCommand {
|
|
|
149
163
|
let upToDateTxt = '';
|
|
150
164
|
let unsafeUpdateTxt = '';
|
|
151
165
|
if (data.installed) {
|
|
152
|
-
const {
|
|
153
|
-
|
|
166
|
+
const {
|
|
167
|
+
installType,
|
|
168
|
+
installSpec,
|
|
169
|
+
updateVersion,
|
|
170
|
+
unsafeUpdateVersion,
|
|
171
|
+
version,
|
|
172
|
+
upToDate,
|
|
173
|
+
updateError,
|
|
174
|
+
} = data;
|
|
154
175
|
let typeTxt;
|
|
155
176
|
switch (installType) {
|
|
156
177
|
case INSTALL_TYPE_GIT:
|
|
@@ -166,14 +187,18 @@ class ExtensionCommand {
|
|
|
166
187
|
installTxt = `@${version.yellow} ${('[installed ' + typeTxt + ']').green}`;
|
|
167
188
|
|
|
168
189
|
if (showUpdates) {
|
|
169
|
-
if (
|
|
170
|
-
updateTxt = ` [${
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
190
|
+
if (updateError) {
|
|
191
|
+
updateTxt = ` [Cannot check for updates: ${updateError}]`.red;
|
|
192
|
+
} else {
|
|
193
|
+
if (updateVersion) {
|
|
194
|
+
updateTxt = ` [${updateVersion} available]`.magenta;
|
|
195
|
+
}
|
|
196
|
+
if (upToDate) {
|
|
197
|
+
upToDateTxt = ` [Up to date]`.green;
|
|
198
|
+
}
|
|
199
|
+
if (unsafeUpdateVersion) {
|
|
200
|
+
unsafeUpdateTxt = ` [${unsafeUpdateVersion} available (potentially unsafe)]`.cyan;
|
|
201
|
+
}
|
|
177
202
|
}
|
|
178
203
|
}
|
|
179
204
|
}
|
|
@@ -187,12 +212,12 @@ class ExtensionCommand {
|
|
|
187
212
|
/**
|
|
188
213
|
* Install an extension
|
|
189
214
|
*
|
|
190
|
-
* @param {
|
|
215
|
+
* @param {InstallOpts} opts
|
|
191
216
|
* @return {Promise<ExtRecord<ExtType>>} map of all installed extension names to extension data
|
|
192
217
|
*/
|
|
193
218
|
async _install({installSpec, installType, packageName}) {
|
|
194
|
-
/** @type {
|
|
195
|
-
let
|
|
219
|
+
/** @type {ExtInstallReceipt<ExtType>} */
|
|
220
|
+
let receipt;
|
|
196
221
|
|
|
197
222
|
if (packageName && [INSTALL_TYPE_LOCAL, INSTALL_TYPE_NPM].includes(installType)) {
|
|
198
223
|
throw this._createFatalError(`When using --source=${installType}, cannot also use --package`);
|
|
@@ -205,7 +230,7 @@ class ExtensionCommand {
|
|
|
205
230
|
/**
|
|
206
231
|
* @type {InstallViaNpmArgs}
|
|
207
232
|
*/
|
|
208
|
-
let
|
|
233
|
+
let installViaNpmOpts;
|
|
209
234
|
|
|
210
235
|
/**
|
|
211
236
|
* The probable (?) name of the extension derived from the install spec.
|
|
@@ -223,8 +248,9 @@ class ExtensionCommand {
|
|
|
223
248
|
'it should be of the form <org>/<repo>'
|
|
224
249
|
);
|
|
225
250
|
}
|
|
226
|
-
|
|
251
|
+
installViaNpmOpts = {
|
|
227
252
|
installSpec,
|
|
253
|
+
installType,
|
|
228
254
|
pkgName: /** @type {string} */ (packageName),
|
|
229
255
|
};
|
|
230
256
|
probableExtName = installSpec;
|
|
@@ -232,8 +258,9 @@ class ExtensionCommand {
|
|
|
232
258
|
// git urls can have '.git' at the end, but this is not necessary and would complicate the
|
|
233
259
|
// way we download and name directories, so we can just remove it
|
|
234
260
|
installSpec = installSpec.replace(/\.git$/, '');
|
|
235
|
-
|
|
261
|
+
installViaNpmOpts = {
|
|
236
262
|
installSpec,
|
|
263
|
+
installType,
|
|
237
264
|
pkgName: /** @type {string} */ (packageName),
|
|
238
265
|
};
|
|
239
266
|
probableExtName = installSpec;
|
|
@@ -279,7 +306,7 @@ class ExtensionCommand {
|
|
|
279
306
|
installType = INSTALL_TYPE_NPM;
|
|
280
307
|
}
|
|
281
308
|
}
|
|
282
|
-
|
|
309
|
+
installViaNpmOpts = {installSpec, pkgName, pkgVer, installType};
|
|
283
310
|
}
|
|
284
311
|
|
|
285
312
|
// fail fast here if we can
|
|
@@ -291,11 +318,12 @@ class ExtensionCommand {
|
|
|
291
318
|
);
|
|
292
319
|
}
|
|
293
320
|
|
|
294
|
-
|
|
321
|
+
receipt = await this.installViaNpm(installViaNpmOpts);
|
|
295
322
|
|
|
296
323
|
// this _should_ be the same as `probablyExtName` as the one derived above unless
|
|
297
324
|
// install type is local.
|
|
298
|
-
|
|
325
|
+
/** @type {string} */
|
|
326
|
+
const extName = receipt[/** @type {string} */ (`${this.type}Name`)];
|
|
299
327
|
|
|
300
328
|
// check _a second time_ with the more-accurate extName
|
|
301
329
|
if (this.config.isInstalled(extName)) {
|
|
@@ -308,10 +336,9 @@ class ExtensionCommand {
|
|
|
308
336
|
|
|
309
337
|
// this field does not exist as such in the manifest (it's used as a property name instead)
|
|
310
338
|
// so that's why it's being removed here.
|
|
311
|
-
delete extData[/** @type {string} */ (`${this.type}Name`)];
|
|
312
|
-
|
|
313
339
|
/** @type {ExtManifest<ExtType>} */
|
|
314
|
-
const extManifest =
|
|
340
|
+
const extManifest = receiptToManifest(receipt);
|
|
341
|
+
|
|
315
342
|
const [errors, warnings] = await B.all([
|
|
316
343
|
this.config.getProblems(extName, extManifest),
|
|
317
344
|
this.config.getWarnings(extName, extManifest),
|
|
@@ -334,13 +361,13 @@ class ExtensionCommand {
|
|
|
334
361
|
|
|
335
362
|
await this.config.addExtension(extName, extManifest);
|
|
336
363
|
|
|
337
|
-
// update the if we've changed the local `package.json`
|
|
364
|
+
// update the hash if we've changed the local `package.json`
|
|
338
365
|
if (await env.hasAppiumDependency(this.config.appiumHome)) {
|
|
339
366
|
await packageDidChange(this.config.appiumHome);
|
|
340
367
|
}
|
|
341
368
|
|
|
342
369
|
// log info for the user
|
|
343
|
-
this.log.info(this.getPostInstallText({extName, extData}));
|
|
370
|
+
this.log.info(this.getPostInstallText({extName, extData: receipt}));
|
|
344
371
|
|
|
345
372
|
return this.config.installedExtensions;
|
|
346
373
|
}
|
|
@@ -349,21 +376,28 @@ class ExtensionCommand {
|
|
|
349
376
|
* Install an extension via NPM
|
|
350
377
|
*
|
|
351
378
|
* @param {InstallViaNpmArgs} args
|
|
379
|
+
* @returns {Promise<ExtInstallReceipt<ExtType>>}
|
|
352
380
|
*/
|
|
353
|
-
async installViaNpm({installSpec, pkgName, pkgVer}) {
|
|
381
|
+
async installViaNpm({installSpec, pkgName, pkgVer, installType}) {
|
|
354
382
|
const npmSpec = `${pkgName}${pkgVer ? '@' + pkgVer : ''}`;
|
|
355
383
|
const specMsg = npmSpec === installSpec ? '' : ` using NPM install spec '${npmSpec}'`;
|
|
356
384
|
const msg = `Installing '${installSpec}'${specMsg}`;
|
|
357
385
|
try {
|
|
358
|
-
const
|
|
359
|
-
const
|
|
386
|
+
const {pkg, path} = await spinWith(this.isJsonOutput, msg, async () => {
|
|
387
|
+
const {pkg, installPath: path} = await npm.installPackage(this.config.appiumHome, pkgName, {
|
|
360
388
|
pkgVer,
|
|
389
|
+
installType,
|
|
361
390
|
});
|
|
362
|
-
this.validatePackageJson(
|
|
363
|
-
return
|
|
391
|
+
this.validatePackageJson(pkg, installSpec);
|
|
392
|
+
return {pkg, path};
|
|
364
393
|
});
|
|
365
394
|
|
|
366
|
-
return this.
|
|
395
|
+
return this.getInstallationReceipt({
|
|
396
|
+
pkg,
|
|
397
|
+
installPath: path,
|
|
398
|
+
installType,
|
|
399
|
+
installSpec,
|
|
400
|
+
});
|
|
367
401
|
} catch (err) {
|
|
368
402
|
throw this._createFatalError(`Encountered an error when installing package: ${err.message}`);
|
|
369
403
|
}
|
|
@@ -382,25 +416,31 @@ class ExtensionCommand {
|
|
|
382
416
|
}
|
|
383
417
|
|
|
384
418
|
/**
|
|
385
|
-
*
|
|
386
|
-
* 'appium' field in the JSON data. We need this information to e.g. determine which class to
|
|
387
|
-
* load as the main driver class, or to be able to detect incompatibilities between driver and
|
|
388
|
-
* appium versions.
|
|
419
|
+
* Once a package is installed on-disk, this gathers some necessary metadata for validation.
|
|
389
420
|
*
|
|
390
|
-
* @param {
|
|
391
|
-
* @returns {
|
|
421
|
+
* @param {GetInstallationReceiptOpts<ExtType>} opts
|
|
422
|
+
* @returns {ExtInstallReceipt<ExtType>}
|
|
392
423
|
*/
|
|
393
|
-
|
|
394
|
-
const {appium, name, version, peerDependencies} =
|
|
424
|
+
getInstallationReceipt({pkg, installPath, installType, installSpec}) {
|
|
425
|
+
const {appium, name, version, peerDependencies} = pkg;
|
|
395
426
|
|
|
396
|
-
/** @type {
|
|
397
|
-
const
|
|
398
|
-
...appium,
|
|
427
|
+
/** @type {import('appium/types').InternalMetadata} */
|
|
428
|
+
const internal = {
|
|
399
429
|
pkgName: name,
|
|
400
430
|
version,
|
|
431
|
+
installType,
|
|
432
|
+
installSpec,
|
|
433
|
+
installPath,
|
|
401
434
|
appiumVersion: peerDependencies?.appium,
|
|
402
435
|
};
|
|
403
|
-
|
|
436
|
+
|
|
437
|
+
/** @type {ExtMetadata<ExtType>} */
|
|
438
|
+
const extMetadata = appium;
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
...internal,
|
|
442
|
+
...extMetadata,
|
|
443
|
+
};
|
|
404
444
|
}
|
|
405
445
|
|
|
406
446
|
/**
|
|
@@ -410,13 +450,13 @@ class ExtensionCommand {
|
|
|
410
450
|
* - `name`
|
|
411
451
|
* - `version`
|
|
412
452
|
* - `appium`
|
|
413
|
-
* @param {import('type-fest').PackageJson}
|
|
453
|
+
* @param {import('type-fest').PackageJson} pkg - `package.json` of extension
|
|
414
454
|
* @param {string} installSpec - Extension name/spec
|
|
415
455
|
* @throws {ReferenceError} If `package.json` has a missing or invalid field
|
|
416
|
-
* @returns {
|
|
456
|
+
* @returns {pkg is ExtPackageJson<ExtType>}
|
|
417
457
|
*/
|
|
418
|
-
validatePackageJson(
|
|
419
|
-
const {appium, name, version} = /** @type {ExtPackageJson<ExtType>} */ (
|
|
458
|
+
validatePackageJson(pkg, installSpec) {
|
|
459
|
+
const {appium, name, version} = /** @type {ExtPackageJson<ExtType>} */ (pkg);
|
|
420
460
|
|
|
421
461
|
/**
|
|
422
462
|
*
|
|
@@ -608,9 +648,10 @@ class ExtensionCommand {
|
|
|
608
648
|
* @returns {Promise<void>}
|
|
609
649
|
*/
|
|
610
650
|
async updateExtension(installSpec, version) {
|
|
611
|
-
const {pkgName} = this.config.installedExtensions[installSpec];
|
|
651
|
+
const {pkgName, installType} = this.config.installedExtensions[installSpec];
|
|
612
652
|
const extData = await this.installViaNpm({
|
|
613
653
|
installSpec,
|
|
654
|
+
installType,
|
|
614
655
|
pkgName,
|
|
615
656
|
pkgVer: version,
|
|
616
657
|
});
|
|
@@ -637,7 +678,7 @@ class ExtensionCommand {
|
|
|
637
678
|
const extConfig = this.config.installedExtensions[installSpec];
|
|
638
679
|
|
|
639
680
|
// note: TS cannot understand that _.has() is a type guard
|
|
640
|
-
if (!extConfig
|
|
681
|
+
if (!('scripts' in extConfig)) {
|
|
641
682
|
throw this._createFatalError(
|
|
642
683
|
`The ${this.type} named '${installSpec}' does not contain the ` +
|
|
643
684
|
`"scripts" field underneath the "appium" field in its package.json`
|
|
@@ -646,13 +687,13 @@ class ExtensionCommand {
|
|
|
646
687
|
|
|
647
688
|
const extScripts = extConfig.scripts;
|
|
648
689
|
|
|
649
|
-
if (!_.isPlainObject(extScripts)) {
|
|
690
|
+
if (!extScripts || !_.isPlainObject(extScripts)) {
|
|
650
691
|
throw this._createFatalError(
|
|
651
692
|
`The ${this.type} named '${installSpec}' "scripts" field must be a plain object`
|
|
652
693
|
);
|
|
653
694
|
}
|
|
654
695
|
|
|
655
|
-
if (!
|
|
696
|
+
if (!(scriptName in extScripts)) {
|
|
656
697
|
throw this._createFatalError(
|
|
657
698
|
`The ${this.type} named '${installSpec}' does not support the script: '${scriptName}'`
|
|
658
699
|
);
|
|
@@ -701,6 +742,7 @@ export {ExtensionCommand};
|
|
|
701
742
|
* @property {string?} updateVersion - If the extension is installed, the version it can be updated to
|
|
702
743
|
* @property {string?} unsafeUpdateVersion - Same as above, but a major version bump
|
|
703
744
|
* @property {boolean} upToDate - If the extension is installed and the latest
|
|
745
|
+
* @property {string?} updateError - Update check error message (if present)
|
|
704
746
|
*/
|
|
705
747
|
|
|
706
748
|
/**
|
|
@@ -734,11 +776,14 @@ export {ExtensionCommand};
|
|
|
734
776
|
* @typedef {import('appium/types').ExtPackageJson<ExtType>} ExtPackageJson
|
|
735
777
|
*/
|
|
736
778
|
|
|
779
|
+
/**
|
|
780
|
+
* @template {ExtensionType} ExtType
|
|
781
|
+
* @typedef {import('appium/types').ExtInstallReceipt<ExtType>} ExtInstallReceipt
|
|
782
|
+
*/
|
|
783
|
+
|
|
737
784
|
/**
|
|
738
785
|
* Possible return value for {@linkcode ExtensionCommand.list}
|
|
739
|
-
* @typedef UninstalledExtensionListData
|
|
740
|
-
* @property {string} pkgName
|
|
741
|
-
* @property {false} installed
|
|
786
|
+
* @typedef {Partial<InstalledExtensionListData> & {pkgName: string, installed: false}} UninstalledExtensionListData
|
|
742
787
|
*/
|
|
743
788
|
|
|
744
789
|
/**
|
|
@@ -806,6 +851,7 @@ export {ExtensionCommand};
|
|
|
806
851
|
* @typedef InstallViaNpmArgs
|
|
807
852
|
* @property {string} installSpec - the name or spec of an extension to install
|
|
808
853
|
* @property {string} pkgName - the NPM package name of the extension
|
|
854
|
+
* @property {import('appium/types').InstallType} installType - type of install
|
|
809
855
|
* @property {string} [pkgVer] - the specific version of the NPM package
|
|
810
856
|
*/
|
|
811
857
|
|
|
@@ -819,18 +865,12 @@ export {ExtensionCommand};
|
|
|
819
865
|
|
|
820
866
|
/**
|
|
821
867
|
* Options for {@linkcode ExtensionCommand._install}
|
|
822
|
-
* @typedef
|
|
868
|
+
* @typedef InstallOpts
|
|
823
869
|
* @property {string} installSpec - the name or spec of an extension to install
|
|
824
|
-
* @property {
|
|
870
|
+
* @property {InstallType} installType - how to install this extension. One of the INSTALL_TYPES
|
|
825
871
|
* @property {string} [packageName] - for git/github installs, the extension node package name
|
|
826
872
|
*/
|
|
827
873
|
|
|
828
|
-
/**
|
|
829
|
-
* Returned by {@linkcode ExtensionCommand.getExtensionFields}
|
|
830
|
-
* @template {ExtensionType} ExtType
|
|
831
|
-
* @typedef {ExtMetadata<ExtType> & { pkgName: string, version: string, appiumVersion: string } & import('appium/types').CommonExtMetadata} ExtensionFields
|
|
832
|
-
*/
|
|
833
|
-
|
|
834
874
|
/**
|
|
835
875
|
* @template {ExtensionType} ExtType
|
|
836
876
|
* @typedef {ExtType extends DriverType ? typeof import('../constants').KNOWN_DRIVERS : ExtType extends PluginType ? typeof import('../constants').KNOWN_PLUGINS : never} KnownExtensions
|
|
@@ -841,3 +881,17 @@ export {ExtensionCommand};
|
|
|
841
881
|
* @property {boolean} showInstalled - whether should show only installed extensions
|
|
842
882
|
* @property {boolean} showUpdates - whether should show available updates
|
|
843
883
|
*/
|
|
884
|
+
|
|
885
|
+
/**
|
|
886
|
+
* Opts for {@linkcode ExtensionCommand.getInstallationReceipt}
|
|
887
|
+
* @template {ExtensionType} ExtType
|
|
888
|
+
* @typedef GetInstallationReceiptOpts
|
|
889
|
+
* @property {string} installPath
|
|
890
|
+
* @property {string} installSpec
|
|
891
|
+
* @property {ExtPackageJson<ExtType>} pkg
|
|
892
|
+
* @property {InstallType} installType
|
|
893
|
+
*/
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* @typedef {import('appium/types').InstallType} InstallType
|
|
897
|
+
*/
|
package/lib/cli/extension.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
|
+
import {DRIVER_TYPE, PLUGIN_TYPE} from '../constants';
|
|
3
|
+
import {isExtensionCommandArgs} from '../utils';
|
|
2
4
|
import DriverCommand from './driver-command';
|
|
3
5
|
import PluginCommand from './plugin-command';
|
|
4
|
-
import {DRIVER_TYPE, PLUGIN_TYPE} from '../constants';
|
|
5
6
|
import {errAndQuit, JSON_SPACES} from './utils';
|
|
6
7
|
|
|
7
8
|
export const commandClasses = Object.freeze(
|
|
@@ -15,18 +16,18 @@ export const commandClasses = Object.freeze(
|
|
|
15
16
|
* Run a subcommand of the 'appium driver' type. Each subcommand has its own set of arguments which
|
|
16
17
|
* can be represented as a JS object.
|
|
17
18
|
*
|
|
18
|
-
* @
|
|
19
|
+
* @template {import('appium/types').CliExtensionCommand} Cmd
|
|
20
|
+
* @template {import('appium/types').CliExtensionSubcommand} SubCmd
|
|
21
|
+
* @param {import('appium/types').Args<Cmd, SubCmd>} args - JS object where the key is the parameter name (as defined in
|
|
19
22
|
* driver-parser.js)
|
|
20
|
-
* @
|
|
21
|
-
* @param {import('../extension/extension-config').ExtensionConfig<ExtType>} config - Extension config object
|
|
23
|
+
* @param {import('../extension/extension-config').ExtensionConfig<Cmd>} config - Extension config object
|
|
22
24
|
*/
|
|
23
25
|
async function runExtensionCommand(args, config) {
|
|
24
26
|
// TODO driver config file should be locked while any of these commands are
|
|
25
27
|
// running to prevent weird situations
|
|
26
28
|
let jsonResult = null;
|
|
27
|
-
const {extensionType: type} = config;
|
|
28
|
-
|
|
29
|
-
if (!extCmd) {
|
|
29
|
+
const {extensionType: type} = config; // NOTE this is the same as `args.subcommand`
|
|
30
|
+
if (!isExtensionCommandArgs(args)) {
|
|
30
31
|
throw new TypeError(`Cannot call ${type} command without a subcommand like 'install'`);
|
|
31
32
|
}
|
|
32
33
|
let {json, suppressOutput} = args;
|
|
@@ -34,7 +35,7 @@ async function runExtensionCommand(args, config) {
|
|
|
34
35
|
if (suppressOutput) {
|
|
35
36
|
json = true;
|
|
36
37
|
}
|
|
37
|
-
const CommandClass = /** @type {ExtCommand<
|
|
38
|
+
const CommandClass = /** @type {ExtCommand<Cmd>} */ (commandClasses[type]);
|
|
38
39
|
const cmd = new CommandClass({config, json});
|
|
39
40
|
try {
|
|
40
41
|
jsonResult = await cmd.execute(args);
|
package/lib/cli/parser.js
CHANGED
|
@@ -89,9 +89,9 @@ class ArgParser {
|
|
|
89
89
|
* If no subcommand is passed in, this method will inject the `server` subcommand.
|
|
90
90
|
*
|
|
91
91
|
* `ArgParser.prototype.parse_args` is an alias of this method.
|
|
92
|
-
* @template [
|
|
92
|
+
* @template {import('appium/types').CliCommand} [Cmd=import('appium/types').ServerCommand]
|
|
93
93
|
* @param {string[]} [args] - Array of arguments, ostensibly from `process.argv`. Gathers args from `process.argv` if not provided.
|
|
94
|
-
* @returns {import('appium/types').Args<
|
|
94
|
+
* @returns {import('appium/types').Args<Cmd>} - The parsed arguments
|
|
95
95
|
*/
|
|
96
96
|
parseArgs(args = process.argv.slice(2)) {
|
|
97
97
|
if (!NON_SERVER_ARGS.has(args[0])) {
|
package/lib/config-file.js
CHANGED
|
@@ -154,9 +154,8 @@ export function normalizeConfig(config) {
|
|
|
154
154
|
const normalize = (config, section) => {
|
|
155
155
|
const obj = _.isUndefined(section) ? config : _.get(config, section, config);
|
|
156
156
|
|
|
157
|
-
const mappedObj = _.mapKeys(
|
|
158
|
-
|
|
159
|
-
(__, prop) => schema.properties[prop]?.appiumCliDest ?? _.camelCase(prop)
|
|
157
|
+
const mappedObj = _.mapKeys(obj, (__, prop) =>
|
|
158
|
+
_.get(schema, `properties.server.properties[${prop}].appiumCliDest`, _.camelCase(prop))
|
|
160
159
|
);
|
|
161
160
|
|
|
162
161
|
return _.mapValues(mappedObj, (value, property) => {
|
package/lib/config.js
CHANGED
|
@@ -298,11 +298,12 @@ function showConfig(nonDefaultPreConfigParsedArgs, configResult, defaults, parse
|
|
|
298
298
|
} else {
|
|
299
299
|
console.log(`\n(no configuration file loaded)`);
|
|
300
300
|
}
|
|
301
|
-
|
|
301
|
+
const compactedNonDefaultPreConfigArgs = compactConfig(nonDefaultPreConfigParsedArgs);
|
|
302
|
+
if (_.isEmpty(compactedNonDefaultPreConfigArgs)) {
|
|
302
303
|
console.log(`\n(no CLI parameters provided)`);
|
|
303
304
|
} else {
|
|
304
305
|
console.log('\nvia CLI or function call:\n');
|
|
305
|
-
console.dir(
|
|
306
|
+
console.dir(compactedNonDefaultPreConfigArgs);
|
|
306
307
|
}
|
|
307
308
|
console.log('\nfinal configuration:\n');
|
|
308
309
|
console.dir(compactConfig(parsedArgs));
|
package/lib/constants.js
CHANGED
|
@@ -29,6 +29,7 @@ export const KNOWN_PLUGINS = Object.freeze(
|
|
|
29
29
|
images: '@appium/images-plugin',
|
|
30
30
|
'execute-driver': '@appium/execute-driver-plugin',
|
|
31
31
|
'relaxed-caps': '@appium/relaxed-caps-plugin',
|
|
32
|
+
'universal-xml': '@appium/universal-xml-plugin',
|
|
32
33
|
})
|
|
33
34
|
);
|
|
34
35
|
|
|
@@ -40,15 +41,11 @@ export const KNOWN_DRIVERS = Object.freeze(
|
|
|
40
41
|
/** @type {const} */ ({
|
|
41
42
|
uiautomator2: 'appium-uiautomator2-driver',
|
|
42
43
|
xcuitest: 'appium-xcuitest-driver',
|
|
43
|
-
youiengine: 'appium-youiengine-driver',
|
|
44
|
-
windows: 'appium-windows-driver',
|
|
45
|
-
mac: 'appium-mac-driver',
|
|
46
44
|
mac2: 'appium-mac2-driver',
|
|
47
45
|
espresso: 'appium-espresso-driver',
|
|
48
|
-
tizen: 'appium-tizen-driver',
|
|
49
|
-
flutter: 'appium-flutter-driver',
|
|
50
46
|
safari: 'appium-safari-driver',
|
|
51
47
|
gecko: 'appium-geckodriver',
|
|
48
|
+
chromium: 'appium-chromium-driver',
|
|
52
49
|
})
|
|
53
50
|
);
|
|
54
51
|
|
|
@@ -67,3 +64,8 @@ export const EXT_SUBCOMMAND_INSTALL = 'install';
|
|
|
67
64
|
export const EXT_SUBCOMMAND_UNINSTALL = 'uninstall';
|
|
68
65
|
export const EXT_SUBCOMMAND_UPDATE = 'update';
|
|
69
66
|
export const EXT_SUBCOMMAND_RUN = 'run';
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Current revision of the manifest (`extensions.yaml`) schema
|
|
70
|
+
*/
|
|
71
|
+
export const CURRENT_SCHEMA_REV = 3;
|