mirror of
https://github.com/appium/appium.git
synced 2026-05-07 11:30:21 -05:00
0bd4e40b38
Previously, the value of any `Driver#supportedLogTypes` prop would ultimately be unaware of what format the log data is actually stored in (and thus, what the `GET /session/:sessionId/log` cmd responds with). Now this can be declared by using the `LogDef<C extends Constraints, LogEntry = string>` type.
Example:
```js
supportedLogTypes = {
debug: /** @type {import('@appium/types').LogDef<RokuDriverCapConstraints, string>} */ ({
description: 'Roku debug logs',
/** @param {RokuDriver} driver */
async getter(driver) {
return await ['foo'];
},
}),
};
```
This is a log named `debug` which stores strings. The `getter` function is always expected to return a type of `LogEntry[]` and receives a type of `Driver<C>`. In this case, it's the default log entry type (`string`) and `RokuDriver`, which implements `Driver<RokuDriverCapConstraints>` where `RokuDriverCapConstraints` extends `Constraints`.
It was kind of tricky since `supportedLogTypes` is an instance field and we don't have access to `this`, so cannot derive the type of the `driver` parameter from it, nor can we use `this` in the `ILogCommands` interface.
Renamed these various mixin interfaces to be prefixed with `I`. All of the mixins themselves (the implementations) are now driver-aware via the `C` type parameter and thus can reference driver-specific caps or options, if needed.
71 lines
2.8 KiB
JavaScript
71 lines
2.8 KiB
JavaScript
import _ from 'lodash';
|
|
import {errors, makeArgs, checkParams} from '../../protocol';
|
|
|
|
/**
|
|
* @template {Constraints} C
|
|
* @param {import('./session').SessionBase<C>} Base
|
|
* @returns {ExecuteBase<C>}
|
|
*/
|
|
export function ExecuteMixin(Base) {
|
|
/**
|
|
* @implements {IExecuteCommands}
|
|
*/
|
|
class ExecuteCommands extends Base {
|
|
/**
|
|
* @param {string} script
|
|
* @param {[Record<string, any>]|[]} protoArgs
|
|
*/
|
|
async executeMethod(script, protoArgs) {
|
|
// the w3c protocol will give us an array of arguments to apply to a javascript function.
|
|
// that's not what we're doing. we're going to look for a JS object as the first arg, so we
|
|
// can perform validation on it. we'll ignore everything else.
|
|
if (!protoArgs || !_.isArray(protoArgs) || protoArgs.length > 1) {
|
|
throw new errors.InvalidArgumentError(
|
|
`Did not get correct format of arguments for execute method. Expected zero or one ` +
|
|
`arguments to execute script and instead received: ${JSON.stringify(protoArgs)}`
|
|
);
|
|
}
|
|
let args = protoArgs[0] ?? {};
|
|
if (!_.isPlainObject(args)) {
|
|
throw new errors.InvalidArgumentError(
|
|
`Did not receive an appropriate execute method parameters object. It needs to be ` +
|
|
`deserializable as a plain JS object`
|
|
);
|
|
}
|
|
|
|
const Driver = /** @type {DriverClass} */ (this.constructor);
|
|
const availableScripts = _.keys(Driver.executeMethodMap);
|
|
const commandMetadata = Driver.executeMethodMap[script];
|
|
if (!commandMetadata) {
|
|
throw new errors.UnsupportedOperationError(
|
|
`Unsupported execute method '${script}'. Available methods ` +
|
|
`are: ${availableScripts.join(', ')}`
|
|
);
|
|
}
|
|
let argsToApply = [];
|
|
if (!commandMetadata.params) {
|
|
commandMetadata.params = {required: [], optional: []};
|
|
} else {
|
|
commandMetadata.params.required ??= [];
|
|
commandMetadata.params.optional ??= [];
|
|
checkParams(commandMetadata.params, args, null);
|
|
}
|
|
argsToApply = makeArgs({}, args, commandMetadata.params, null);
|
|
return await this[Driver.executeMethodMap[script].command](...argsToApply);
|
|
}
|
|
}
|
|
return ExecuteCommands;
|
|
}
|
|
|
|
/**
|
|
* @typedef {import('@appium/types').IExecuteCommands} IExecuteCommands
|
|
* @typedef {import('@appium/types').Driver} Driver
|
|
* @typedef {import('@appium/types').DriverClass} DriverClass
|
|
* @typedef {import('@appium/types').Constraints} Constraints
|
|
*/
|
|
|
|
/**
|
|
* @template {Constraints} C
|
|
* @typedef {import('../driver').BaseDriverBase<C, import('@appium/types').ITimeoutCommands & import('@appium/types').IEventCommands & import('@appium/types').IFindCommands & import('@appium/types').ILogCommands<C> & import('@appium/types').ISettingsCommands & import('@appium/types').SessionCommands & IExecuteCommands>} ExecuteBase
|
|
*/
|