chore: update MethodMap/ExecuteMethodMap to support plugins

This commit is contained in:
Christopher Hiller
2023-01-18 14:45:03 -08:00
committed by Jonathan Lipps
parent 84abed920a
commit 9cd228247a
4 changed files with 33 additions and 15 deletions

View File

@@ -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(

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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,
{