UNPKG

@appium/base-plugin

Version:

The base plugin used to create Appium 2.0 plugins

108 lines (96 loc) 3.5 kB
import {ExtensionCore, generateDriverLogPrefix, validateExecuteMethodParams} from '@appium/base-driver'; /** * @implements {Plugin} */ class BasePlugin extends ExtensionCore { /** * @deprecated Use this.log instead of this.logger * @type {import('@appium/types').AppiumLogger} */ logger; /** * Subclasses should use type `import('@appium/types').MethodMap<SubclassName>`. * * This will verify that the commands in the `newMethodMap` property are * valid. It is impossible to use a generic type param here; the type of this should really * be something like `MethodMap<T extends BasePlugin>` but that isn't a thing TS does. * * ```ts * static newMethodMap = { * '/session/:sessionId/fake_data': { * GET: {command: 'getFakeSessionData', neverProxy: true}, * } * } as const; * ``` */ static newMethodMap = {}; /** * Subclasses should use type `import('@appium/types').ExecuteMethodMap<SubclassName>`. * * Building up this map allows the use of the convenience function `executeMethod`, which * basically does verification of names and parameters for execute methods implemented by this * plugin. * * ```ts * static executeMethodMap = { * 'foo: bar': { * command: 'commandName', * params: {required: ['thing1', 'thing2'], optional: ['thing3']}, * }, * } as const; * ``` */ static executeMethodMap = {}; /** * @param {string} name * @param {Record<string,unknown>} [cliArgs] * @param {string|null} driverId */ constructor(name, cliArgs = {}, driverId = null) { super(); if (driverId) { this.updateLogPrefix(`${generateDriverLogPrefix(this)} <${driverId}>`); } this.name = name; this.cliArgs = cliArgs; this.logger = this.log; } /** * A convenience method that can be called by plugins who implement their own `executeMethodMap`. * Only useful if your plugin has defined `executeMethodMap`. This helper requires passing in the * `next` and `driver` objects since naturally we'd want to make sure to trigger the driver's own * `executeMethod` call if an execute method is not found on the plugin itself. * * @template {Constraints} C * @param {NextPluginCallback} next * @param {Driver<C>} driver * @param {string} script * @param {readonly [import('@appium/types').StringRecord<unknown>] | readonly any[]} protoArgs */ async executeMethod(next, driver, script, protoArgs) { const Plugin = /** @type {import('@appium/types').PluginClass<Plugin>} */ (this.constructor); const commandMetadata = {...Plugin.executeMethodMap?.[script]}; if (!commandMetadata.command || !(commandMetadata.command in this)) { this.logger.info( `Plugin did not know how to handle method '${script}'. Passing control to next` ); return await next(); } const command = /** @type {import('@appium/types').PluginCommand<Driver<C>>} */ ( this[commandMetadata.command] ); const args = validateExecuteMethodParams(protoArgs, commandMetadata.params); return await command.call(this, next, driver, ...args); } } export default BasePlugin; export {BasePlugin}; /** * @typedef {import('@appium/types').Plugin} Plugin * @typedef {import('@appium/types').NextPluginCallback} NextPluginCallback * @typedef {import('@appium/types').Constraints} Constraints */ /** * @template {Constraints} C * @typedef {import('@appium/types').Driver<C>} Driver */