refactor(appium): reduce duplication in cli arg setting
chore(appium): add docstrings to cli arg related methods
MODIFY
packages/appium/lib/appium.js
packages/appium/lib/appium.js
@@ -111,6 +111,26 @@ class AppiumDriver extends BaseDriver {
return findMatchingDriver(...args);
}
+ /**
+ * Validate and assign CLI args for a driver or plugin
+ * @param {string} extType 'driver' or 'plugin'
+ * @param {string} extName the name of the extension
+ * @param {ObjectConstructor} extClass the class of the extension
+ * @param {Object} extInstance the driver or plugin instance
+ */
+ assignCliArgsToExtension (extType, extName, extClass, extInstance) {
+ const cliArgs = getExtensionArgs(this.args[`${extType}Args`], extName);
+ if (!_.isEmpty(cliArgs)) {
+ if (!_.has(extClass, 'argsConstraints')) {
+ throw new Error(`You sent in CLI args for the ${extName} ${extType}, but it ` +
+ `does not define any`);
+ }
+ validateExtensionArgs(cliArgs, extClass.argsConstraints);
+ extInstance.cliArgs = cliArgs;
+ log.debug(`Set CLI arguments on ${extName} ${extType} instance: ${JSON.stringify(cliArgs)}`);
+ }
+ }
+
/**
* Create a new session
* @param {Object} jsonwpCaps JSONWP formatted desired capabilities
@@ -193,17 +213,7 @@ class AppiumDriver extends BaseDriver {
// Likewise, any driver-specific CLI args that were passed in should be assigned directly to
// the driver so that they cannot be mimicked by a malicious user sending in capabilities
- const driverCliArgs = getExtensionArgs(this.args.driverArgs, driverName);
- if (!_.isEmpty(driverCliArgs)) {
- if (!_.has(InnerDriver, 'argsConstraints')) {
- throw new Error(`You sent in CLI args for the ${driverName} driver, but the driver ` +
- `does not define any`);
- }
- // parse/verify CLI args and merge them to this.args if OK or throw an exception
- validateExtensionArgs(driverCliArgs, InnerDriver.argsConstraints);
- driverInstance.cliArgs = driverCliArgs;
- log.debug(`Set CLI arguments on ${driverName} driver instance: ${JSON.stringify(driverCliArgs)}`);
- }
+ this.assignCliArgsToExtension('driver', driverName, InnerDriver, driverInstance);
// This assignment is required for correct web sockets functionality inside the driver
@@ -424,17 +434,7 @@ class AppiumDriver extends BaseDriver {
const generalName = PluginClass.pluginName;
const name = `${generalName} (${sessionId})`;
const plugin = new PluginClass(name);
- const pluginCliArgs = getExtensionArgs(this.args.pluginArgs, generalName);
- if (!_.isEmpty(pluginCliArgs)) {
- if (!_.has(PluginClass, 'argsConstraints')) {
- throw new Error(`You sent in CLI args for the ${generalName} plugin, but the plugin ` +
- `does not define any`);
- }
- validateExtensionArgs(pluginCliArgs, PluginClass.argsConstraints);
- plugin.cliArgs = pluginCliArgs;
- log.debug(`Set CLI arguments on ${name} plugin for session '${sessionId}': ` +
- JSON.stringify(pluginCliArgs));
- }
+ this.assignCliArgsToExtension('plugin', generalName, PluginClass, plugin);
return plugin;
});
}

MODIFY
packages/appium/lib/utils.js
packages/appium/lib/utils.js
@@ -33,20 +33,33 @@ function inspectObject (args) {
}
}
+/**
+ * Given a set of CLI args and the name of a driver or plugin, extract those args for that plugin
+ * @param {Object} extensionArgs - arguments of the form {[extName]: {[argName]: [argValue]}}
+ * @param {string} extensionName - the name of the extension
+ * @return {Object} the arg object for that extension alone
+ */
function getExtensionArgs (extensionArgs, extensionName) {
if (!_.has(extensionArgs, extensionName)) {
return {};
}
if (!_.isPlainObject(extensionArgs[extensionName])) {
- throw new Error(`Driver or plugin arguments must be plain objects`);
+ throw new TypeError(`Driver or plugin arguments must be plain objects`);
}
return extensionArgs[extensionName];
}
+/**
+ * Given a set of args and a set of constraints, throw an error if any args are not mentioned in
+ * the set of constraints
+ * @param {Object} extensionArgs the args
+ * @param {Object} argsConstraints the constraints object
+ * @throws {Error} if any args were not recognized
+ */
function ensureNoUnknownArgs (extensionArgs, argsConstraints) {
const knownArgNames = Object.keys(argsConstraints);
- const unknownArgs = _.difference(Object.keys(extensionArgs), Object.keys(argsConstraints));
+ const unknownArgs = _.difference(Object.keys(extensionArgs), knownArgNames);
if (unknownArgs.length > 0) {
throw new Error(`Some arguments were not recognized: ${JSON.stringify(unknownArgs)}. ` +
`Are you sure they are in the list of supported args? ${JSON.stringify(knownArgNames)}`);
@@ -59,6 +72,7 @@ function ensureNoUnknownArgs (extensionArgs, argsConstraints) {
*
* @param {object} extensionArgs - Driver or Plugin specific args
* @param {object} argsConstraints - Constraints for arguments
+ * @throws {Error} if any args are not recognized or are of an invalid type
*/
function validateExtensionArgs (extensionArgs, argsConstraints) {
if (!_.isEmpty(extensionArgs) && !_.isEmpty(argsConstraints)) {

refactor(appium): reduce duplication in cli arg setting
chore(appium): add docstrings to cli arg related methods