appium-xcuitest-driver
Version:
Appium driver for iOS using XCUITest for backend
103 lines • 4.18 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.execute = execute;
exports.executeAsync = executeAsync;
const lodash_1 = __importDefault(require("lodash"));
const driver_1 = require("../driver");
const driver_2 = require("appium/driver");
const support_1 = require("appium/support");
/**
* @template TReturn
* @param script - Either a script to run, or in the case of an Execute Method, the name of the script to execute.
* @param args
*/
async function execute(script, args) {
// TODO: create a type that converts args to the parameters of the associated method using the `command` prop of `executeMethodMap`
script = script.trim().replace(/^mobile:\s*/, 'mobile: ');
if (isExecuteMethod(script)) {
const executeMethodArgs = preprocessExecuteMethodArgs(script, args);
return await this.executeMethod(script, [executeMethodArgs]);
}
else if (this.isWebContext()) {
const atomsArgs = this.convertElementsForAtoms(args);
const result = await this.executeAtom('execute_script', [script, atomsArgs]);
return this.cacheWebElements(result);
}
else {
throw new driver_2.errors.NotImplementedError();
}
}
/**
* @group Mobile Web Only
*/
async function executeAsync(script, args) {
if (!this.isWebContext()) {
throw new driver_2.errors.NotImplementedError();
}
args = this.convertElementsForAtoms(args);
this.asyncWaitMs = this.asyncWaitMs || 0;
const promise = this.remote.executeAtomAsync('execute_async_script', [script, args, this.asyncWaitMs], this.curWebFrames);
return this.cacheWebElements(await this.waitForAtom(promise));
}
/**
* Checks if script expects a particular parameter (either optional or required).
* @template Script
* @param script - Script name
* @param param - Parameter name
* @returns {boolean}
*/
function executeMethodExpectsParam(script, param) {
let required;
let optional;
const execMethodDef = driver_1.XCUITestDriver.executeMethodMap[script];
if ('params' in execMethodDef) {
if ('required' in execMethodDef.params) {
required = execMethodDef.params.required;
}
if ('optional' in execMethodDef.params) {
optional = execMethodDef.params.optional;
}
}
const allParams = new Set(lodash_1.default.flatten([...(required ?? []), ...(optional ?? [])]));
return allParams.has(param);
}
/**
* @param script
* @returns {script is keyof XCUITestDriver.executeMethodMap}
*/
function isExecuteMethod(script) {
return script in driver_1.XCUITestDriver.executeMethodMap;
}
/**
* Massages the arguments going into an execute method.
* @param script
* @param args
*/
function preprocessExecuteMethodArgs(script, args) {
if (lodash_1.default.isArray(args)) {
args = lodash_1.default.first(args);
}
const executeMethodArgs = (args ?? {});
/**
* Renames the deprecated `element` key to `elementId`. Historically,
* all of the pre-Execute-Method-Map execute methods accepted an `element` _or_ and `elementId` param.
* This assigns the `element` value to `elementId` if `elementId` is not already present.
*/
if (!('elementId' in executeMethodArgs) && 'element' in executeMethodArgs) {
executeMethodArgs.elementId = executeMethodArgs.element;
delete executeMethodArgs.element;
}
/**
* Automatically unwraps the `elementId` prop _if and only if_ the execute method expects it.
*
* Most of these Execute Methods (typically beginning with `mobile*`) will accept an `Element|string` for `elementId`, in practice they will only ever get a `string`. `Element|string` in the method's docstring is simply for documentation purposes.
*/
if ('elementId' in executeMethodArgs && executeMethodExpectsParam(script, 'elementId')) {
executeMethodArgs.elementId = support_1.util.unwrapElement(executeMethodArgs.elementId);
}
return executeMethodArgs;
}
//# sourceMappingURL=execute.js.map