chore: update MethodMap/ExecuteMethodMap to support plugins
MODIFY
packages/appium/lib/main.js
packages/appium/lib/main.js
@@ -139,7 +139,7 @@ function getServerUpdaters(driverClasses, pluginClasses) {
* Makes a big `MethodMap` from all the little `MethodMap`s in the extensions
* @param {DriverNameMap} driverClasses
* @param {PluginNameMap} pluginClasses
- * @returns {import('@appium/types').MethodMap}
+ * @returns {import('@appium/types').MethodMap<import('@appium/types').Driver>}
*/
function getExtraMethodMap(driverClasses, pluginClasses) {
return [...driverClasses.keys(), ...pluginClasses.keys()].reduce(

MODIFY
packages/base-plugin/lib/plugin.js
packages/base-plugin/lib/plugin.js
@@ -56,22 +56,28 @@ class BasePlugin {
* `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 {Driver} D
* @param {NextPluginCallback} next
- * @param {Driver} driver
+ * @param {D} driver
* @param {string} script
* @param {[Record<string, any>]|[]} protoArgs
+ * @this {Plugin}
*/
async executeMethod(next, driver, script, protoArgs) {
const Plugin = /** @type {PluginClass} */ (this.constructor);
const commandMetadata = {...Plugin.executeMethodMap?.[script]};
- if (!commandMetadata.command) {
+
+ /** @type {import('@appium/types').PluginCommand<D>|undefined} */
+ let command;
+
+ if (!commandMetadata.command || !(command = this[commandMetadata.command])) {
this.logger.info(
`Plugin did not know how to handle method '${script}'. Passing control to next`
);
return await next();
}
const args = validateExecuteMethodParams(protoArgs, commandMetadata.params);
- return await this[commandMetadata.command](next, driver, ...args);
+ return await command.call(this, next, driver, ...args);
}
}

MODIFY
packages/types/lib/driver.ts
packages/types/lib/driver.ts
@@ -12,6 +12,7 @@ import {
BaseDriverCapConstraints,
W3CCapabilities,
Capabilities,
+ ExecuteMethodMap,
} from '.';
import {ServerArgs} from './config';
import {AsyncReturnType, ConditionalPick} from 'type-fest';
@@ -185,14 +186,6 @@ export interface IExecuteCommands {
executeMethod(script: string, args: [StringRecord] | []): Promise<any>;
}
-export interface ExecuteMethodDef<D> {
- command: keyof ConditionalPick<Required<D>, DriverCommand>;
- params?: {
- required?: ReadonlyArray<string>;
- optional?: ReadonlyArray<string>;
- };
-}
-export type ExecuteMethodMap<D> = Readonly<Record<string, Readonly<ExecuteMethodDef<D>>>>;
export interface MultiSessionData<
C extends Constraints = BaseDriverCapConstraints,
Extra extends StringRecord | void = void

MODIFY
packages/types/lib/index.ts
packages/types/lib/index.ts
@@ -5,6 +5,8 @@ import type {Logger} from 'npmlog';
import type {Class as _Class, ConditionalPick, MultidimensionalReadonlyArray} from 'type-fest';
import type {Server as WSServer} from 'ws';
import {ServerArgs} from './config';
+import {Driver} from './driver';
+import {Plugin, PluginCommand} from './plugin';
export * from './action';
export * from './appium-config';
@@ -82,11 +84,14 @@ export interface AppiumServerSocket extends Socket {
* The definition of an extension method, which will be provided via Appium's API.
*
*/
-export interface MethodDef<Ext> {
+export interface MethodDef<Ext extends Plugin | Driver> {
/**
* Name of the command.
*/
- readonly command?: keyof ConditionalPick<Required<Ext>, DriverCommand>;
+ readonly command?: keyof ConditionalPick<
+ Required<Ext>,
+ Ext extends Plugin ? PluginCommand : Ext extends Driver ? DriverCommand : never
+ >;
/**
* If true, this `Method` will never proxy.
*/
@@ -97,6 +102,20 @@ export interface MethodDef<Ext> {
readonly payloadParams?: PayloadParams;
}
+export interface ExecuteMethodDef<Ext extends Driver | Plugin> {
+ command: keyof ConditionalPick<
+ Required<Ext>,
+ Ext extends Plugin ? PluginCommand : Ext extends Driver ? DriverCommand : never
+ >;
+ params?: {
+ required?: ReadonlyArray<string>;
+ optional?: ReadonlyArray<string>;
+ };
+}
+export type ExecuteMethodMap<Ext extends Driver | Plugin> = Readonly<
+ Record<string, Readonly<ExecuteMethodDef<Ext>>>
+>;
+
/**
* An instance method of a driver class, whose name may be referenced by {@linkcode MethodDef.command}, and serves as an Appium command.
*
@@ -118,7 +137,7 @@ export interface PayloadParams {
/**
* A mapping of URL paths to HTTP methods to {@linkcode MethodDef}s.
*/
-export type MethodMap<Ext = any> = Readonly<
+export type MethodMap<Ext extends Plugin | Driver> = Readonly<
Record<
string,
{

chore: update MethodMap/ExecuteMethodMap to support plugins