appium-xcuitest-driver
Version:
Appium driver for iOS using XCUITest for backend
126 lines • 5.18 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.receiveAsyncResponse = receiveAsyncResponse;
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");
/**
* Collect the response of an async script execution
* @deprecated
* @privateRemarks It's unclear what this is for. Don't use it.
*/
async function receiveAsyncResponse(status, value) {
this.log.debug(`Received async response: ${JSON.stringify(value)}`);
if (!support_1.util.hasValue(this.asyncPromise)) {
this.log.warn(`Received async response when we were not expecting one! ` +
`Response was: ${JSON.stringify(value)}`);
return;
}
if (support_1.util.hasValue(status) && status !== 0) {
// MJSONWP
return this.asyncPromise.reject((0, driver_2.errorFromCode)(status, value.message));
}
if (!support_1.util.hasValue(status) && value && lodash_1.default.isString(value.error)) {
// W3C
return this.asyncPromise.reject((0, driver_2.errorFromW3CJsonCode)(value.error, value.message, value.stacktrace));
}
return this.asyncPromise.resolve(value);
}
/**
* @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