UNPKG

appium

Version:

Automation for Apps.

164 lines 8.13 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.loadExtensions = loadExtensions; exports.getActivePlugins = getActivePlugins; exports.getActiveDrivers = getActiveDrivers; const lodash_1 = __importDefault(require("lodash")); const constants_1 = require("../constants"); const logger_1 = __importDefault(require("../logger")); const driver_config_1 = require("./driver-config"); const manifest_1 = require("./manifest"); const support_1 = require("@appium/support"); const plugin_config_1 = require("./plugin-config"); const bluebird_1 = __importDefault(require("bluebird")); /** * Loads extensions and creates `ExtensionConfig` instances. * * - Reads the manifest file, creating if necessary * - Using the parsed extension data, creates/gets the `ExtensionConfig` subclass instances * - Returns these instances * * If `appiumHome` is needed, use `resolveAppiumHome` from the `env` module in `@appium/support`. * @param {string} appiumHome * @returns {Promise<ExtensionConfigs>} */ async function loadExtensions(appiumHome) { const manifest = manifest_1.Manifest.getInstance(appiumHome); await manifest.read(); const driverConfig = driver_config_1.DriverConfig.getInstance(manifest) ?? driver_config_1.DriverConfig.create(manifest); const pluginConfig = plugin_config_1.PluginConfig.getInstance(manifest) ?? plugin_config_1.PluginConfig.create(manifest); await bluebird_1.default.all([driverConfig.validate(), pluginConfig.validate()]); return { driverConfig, pluginConfig }; } /** * @template {'driver'|'plugin'} TExtType * @param {TExtType} extType * @param {import('./extension-config').ExtensionConfig} config * @param {string[]} extNames * @param {number} asyncImportChunkSize * @returns {Promise<[TExtType extends 'driver' ? DriverClass : PluginClass, string][]>} */ async function importExtensions(extType, config, extNames, asyncImportChunkSize) { /** @type {B[]} */ const allPromises = []; /** @type {B[]} */ const activePromisesChunk = []; for (const extName of extNames) { lodash_1.default.remove(activePromisesChunk, (p) => p.isFulfilled()); if (activePromisesChunk.length >= asyncImportChunkSize) { await bluebird_1.default.any(activePromisesChunk); } const promise = bluebird_1.default.resolve((async () => { logger_1.default.info(`Attempting to load ${extType} ${extName}...`); const timer = new support_1.timing.Timer().start(); try { const extClass = await config.requireAsync(extName); logger_1.default.debug(`${extClass.name} has been successfully loaded in ${timer.getDuration().asSeconds.toFixed(3)}s`); return extClass; } catch (err) { logger_1.default.error(`Could not load ${extType} '${extName}', so it will not be available. Error ` + `in loading the ${extType} was: ${err.message}`); logger_1.default.debug(err.stack); } })()); activePromisesChunk.push(promise); allPromises.push(promise); } return /** @type {[TExtType extends 'driver' ? DriverClass : PluginClass, string][]} */ (lodash_1.default.zip(await bluebird_1.default.all(allPromises), extNames).filter(([extClass,]) => Boolean(extClass))); } /** * Find any plugin name which has been installed, and which has been requested for activation by * using the --use-plugins flag, and turn each one into its class, so we can send them as objects * to the server init. We also want to send/assign them to the umbrella driver so it can use them * to wrap command execution * * @param {import('./plugin-config').PluginConfig} pluginConfig - a plugin extension config * @param {number} maxParallelImports the maximum amount of plugins to import in parallel * @param {string[]} usePlugins * @returns {Promise<PluginNameMap>} Mapping of PluginClass to name */ async function getActivePlugins(pluginConfig, maxParallelImports, usePlugins = []) { if (lodash_1.default.isEmpty(usePlugins)) { return new Map(); } /** @type {string[]} */ let filteredPluginNames = []; if (usePlugins.length === 1 && usePlugins[0] === constants_1.USE_ALL_PLUGINS) { filteredPluginNames = lodash_1.default.keys(pluginConfig.installedExtensions); } else { // It is important to load plugins in the same order that was used while enumerating them for (const pluginName of usePlugins) { if (pluginName in pluginConfig.installedExtensions) { filteredPluginNames.push(pluginName); } else if (pluginName === constants_1.USE_ALL_PLUGINS) { throw new Error(`The reserved plugin name '${pluginName}' cannot be combined with other names.`); } else { const suffix = lodash_1.default.isEmpty(pluginConfig.installedExtensions) ? `You don't have any plugins installed yet.` : `Only the following ${lodash_1.default.size(pluginConfig.installedExtensions) === 1 ? `plugin is` : `plugins are`} ` + `available: ${lodash_1.default.keys(pluginConfig.installedExtensions)}`; throw new Error(`Could not load the plugin '${pluginName}' because it is not installed. ${suffix}`); } } } return new Map(await importExtensions('plugin', pluginConfig, filteredPluginNames, maxParallelImports)); } /** * Find any driver name which has been installed, and turn each one into its class, so we can send * them as objects to the server init in case they need to add methods/routes or update the server. * If the --drivers flag was given, this method only loads the given drivers. * * @param {import('./driver-config').DriverConfig} driverConfig - a driver extension config * @param {number} maxParallelImports the maximum amount of plugins to import in parallel * @param {string[]} [useDrivers] - optional list of drivers to load * @returns {Promise<DriverNameMap>} */ async function getActiveDrivers(driverConfig, maxParallelImports, useDrivers = []) { /** @type {string[]} */ let filteredDriverNames = []; if (lodash_1.default.isEmpty(useDrivers)) { // load all drivers if none are requested filteredDriverNames = lodash_1.default.keys(driverConfig.installedExtensions); } else { // Load drivers in the same order that was used while enumerating them for (const driverName of useDrivers) { if (driverName in driverConfig.installedExtensions) { filteredDriverNames.push(driverName); } else { const suffix = lodash_1.default.isEmpty(driverConfig.installedExtensions) ? `You don't have any drivers installed yet.` : `Only the following ${lodash_1.default.size(driverConfig.installedExtensions) === 1 ? `driver is` : `drivers are`} ` + `available: ${lodash_1.default.keys(driverConfig.installedExtensions)}`; throw new Error(`Could not load the driver '${driverName}' because it is not installed. ${suffix}`); } } } return new Map(await importExtensions('driver', driverConfig, filteredDriverNames, maxParallelImports)); } /** * A mapping of {@linkcode PluginClass} classes to their names. * @typedef {Map<PluginClass,string>} PluginNameMap */ /** * A mapping of {@linkcode DriverClass} classes to their names. * @typedef {Map<DriverClass,string>} DriverNameMap */ /** * @typedef {import('@appium/types').PluginClass} PluginClass * @typedef {import('@appium/types').DriverClass} DriverClass */ /** * @typedef ExtensionConfigs * @property {import('./driver-config').DriverConfig} driverConfig * @property {import('./plugin-config').PluginConfig} pluginConfig */ //# sourceMappingURL=index.js.map