exports.isAppInstalled = function (req, res) {
if (checkMissingParams(req, res, {bundleId: req.body.bundleId}, true)) {
req.device.isAppInstalled(req.body.bundleId, function (error, stdout) {
if (error !== null) {
respondSuccess(req, res, false);
} else {
// We're examining the type of stdout because `isAppInstalled` uses
// node-idevice for real iOS devices. node-idevice passes a boolean
// value in the second parameter of the callback function. Other
// functions pass back an array. Changing the parameter type of the
// other functions is a deeper and more dangerous change than just
// type-checking here.
if ((req.appium.args.udid && req.appium.args.udid.length === 40) ||
(typeof stdout === "boolean" && stdout) ||
(typeof stdout[0] !== "undefined")) {
respondSuccess(req, res, true);
} else {
respondSuccess(req, res, false);
}
}
});
}
};
exports.startActivity = function (req, res) {
var onErr = function (err) {
respondError(req, res, "Unable to launch the app: " + err);
};
// 8/21/14: currently not supported on all devices
if (!req.device.startApp) {
onErr(new NotImplementedError());
} else {
req.device.startApp(req.body, function (err) {
if (err) return onErr(err);
respondSuccess(req, res, "Successfully launched the app.");
});
}
};
exports.launchApp = function (req, res) {
var onErr = function (err) {
respondError(req, res, "Unable to launch the app: " + err);
};
req.device.start(function (err) {
if (err) return onErr(err);
respondSuccess(req, res, "Successfully launched the app.");
}, function () {
onErr(new Error("UiAutomator died"));
});
};
exports.closeApp = function (req, res) {
req.device.stop(function () {
respondSuccess(req, res, "Successfully closed the [" + req.device.args.app + "] app.");
}, function () {
respondError(req, res, "Something went wrong whilst closing the [" + req.device.args.app + "] app.");
});
};
exports.createSession = function (req, res) {
if (typeof req.body === 'string') {
req.body = JSON.parse(req.body);
}
logger.info('Client User-Agent string:', req.headers['user-agent']);
var next = function (reqHost, sessionId) {
safely(req, function () {
res.set('Location', "http://" + reqHost + "/wd/hub/session/" + sessionId);
res.status(303).send("Appium session started with sessionId " + sessionId);
});
};
if (req.appium.preLaunched && req.appium.sessionId) {
req.appium.preLaunched = false;
next(req.headers.host, req.appium.sessionId, req.appium.device, true);
} else {
req.appium.start(req.body.desiredCapabilities, function (err, instance) {
if (err) {
logger.error("Failed to start an Appium session, err was: " + err);
logger.debug(err.stack);
delete err.stack;
respondError(req, res, status.codes.SessionNotCreatedException, err);
} else {
logger.debug("Appium session started with sessionId " + req.appium.sessionId);
next(req.headers.host, req.appium.sessionId, instance);
}
});
}
};
exports.getSession = function (req, res) {
// Return a static JSON object to the client
respondSuccess(req, res, req.device.capabilities);
};
exports.getSessions = function (req, res) {
var sessions = [];
if (req.appium.sessionId !== null) {
sessions.push({
id: req.appium.sessionId
, capabilities: req.device.capabilities
});
}
respondSuccess(req, res, sessions);
};
exports.reset = function (req, res) {
req.appium.reset(getResponseHandler(req, res));
};
exports.lock = function (req, res) {
var seconds = req.body.seconds;
if (checkMissingParams(req, res, {seconds: seconds})) {
req.device.lock(seconds, getResponseHandler(req, res));
}
};
exports.unlock = function (req, res) {
if (req.device.unlock) {
req.device.unlock(getResponseHandler(req, res));
} else {
notYetImplemented(req, res);
}
};
exports.isLocked = function (req, res) {
req.device.isLocked(getResponseHandler(req, res));
};
exports.background = function (req, res) {
var seconds = req.body.seconds;
if (checkMissingParams(req, res, {seconds: seconds})) {
req.device.background(seconds, getResponseHandler(req, res));
}
};
exports.deleteSession = function (req, res) {
req.appium.stop(getResponseHandler(req, res));
};
exports.equalsElement = function (req, res) {
var element = req.params.elementId
, other = req.params.otherId;
req.device.equalsWebElement(element, other, getResponseHandler(req, res));
};
exports.findElements = function (req, res) {
var strategy = req.body.using
, selector = req.body.value;
if (checkMissingParams(req, res, {strategy: strategy, selector: selector}, true)) {
req.device.findElements(strategy, selector, getResponseHandler(req, res));
}
};
exports.findElement = function (req, res) {
var strategy = req.body.using
, selector = req.body.value;
if (checkMissingParams(req, res, {strategy: strategy, selector: selector}, true)) {
req.device.findElement(strategy, selector, getResponseHandler(req, res));
}
};
exports.findElementFromElement = function (req, res) {
var element = req.params.elementId
, strategy = req.body.using
, selector = req.body.value;
req.device.findElementFromElement(element, strategy, selector, getResponseHandler(req, res));
};
exports.findElementsFromElement = function (req, res) {
var element = req.params.elementId
, strategy = req.body.using
, selector = req.body.value;
req.device.findElementsFromElement(element, strategy, selector, getResponseHandler(req, res));
};
exports.setValue = function (req, res) {
var elementId = req.params.elementId
// spec says value attribute is an array of strings;
// let's turn it into one string
, value = req.body.value.join('');
req.device.setValue(elementId, value, getResponseHandler(req, res));
};
exports.replaceValue = function (req, res) {
var elementId = req.params.elementId
// spec says value attribute is an array of strings;
// let's turn it into one string
, value = req.body.value.join('');
req.device.replaceValue(elementId, value, getResponseHandler(req, res));
};
exports.performTouch = function (req, res) {
// touch actions do not work in webview
if (req.device.isWebContext()) {
return notYetImplemented(req, res);
}
// first, assume that we are getting and array of gestures
var gestures = req.body;
// some clients, like Python, send an object in which there is an `actions`
// property that is the array of actions
// get the gestures from there if we don't already have an array
if (gestures && !Array.isArray(gestures)) {
gestures = gestures.actions;
}
// press-wait-moveTo-release is `swipe`, so use native method
if (gestures.length === 4 &&
gestures[0].action === 'press' &&
gestures[1].action === 'wait' &&
gestures[2].action === 'moveTo' &&
gestures[3].action === 'release') {
return exports.mobileSwipe(req, res, gestures);
}
req.device.performTouch(gestures, getResponseHandler(req, res));
};
exports.performMultiAction = function (req, res) {
// touch actions do not work in webview
if (req.device.isWebContext()) {
return notYetImplemented(req, res);
}
var elementId = req.body.elementId;
var actions = req.body.actions;
if (actions.length === 0) {
return respondError(req, res, status.codes.UnknownError.code,
new Error("Unable to perform Multi Pointer Gesture with no actions."));
}
req.device.performMultiAction(elementId, actions, getResponseHandler(req, res));
};
exports.doClick = function (req, res) {
var elementId = req.params.elementId || req.body.element;
req.device.click(elementId, getResponseHandler(req, res));
};
exports.touchLongClick = function (req, res) {
var element = req.body.element;
var x = req.body.x;
var y = req.body.y;
var duration = req.body.duration;
if (element && checkMissingParams(req, res, {element: element}, true)) {
req.device.touchLongClick(element, x, y, duration, getResponseHandler(req, res));
} else if (checkMissingParams(req, res, {x: x, y: y}, true)) {
req.device.touchLongClick(element, x, y, duration, getResponseHandler(req, res));
}
};
exports.touchDown = function (req, res) {
var element = req.body.element;
var x = req.body.x;
var y = req.body.y;
if (element && checkMissingParams(req, res, {element: element}, true)) {
req.device.touchDown(element, x, y, getResponseHandler(req, res));
} else if (checkMissingParams(req, res, {x: x, y: y}, true)) {
req.device.touchDown(element, x, y, getResponseHandler(req, res));
}
};
exports.touchUp = function (req, res) {
var element = req.body.element;
var x = req.body.x;
var y = req.body.y;
if (element && checkMissingParams(req, res, {element: element}, true)) {
req.device.touchUp(element, x, y, getResponseHandler(req, res));
} else if (checkMissingParams(req, res, {x: x, y: y}, true)) {
req.device.touchUp(element, x, y, getResponseHandler(req, res));
}
};
exports.touchMove = function (req, res) {
var element = req.body.element;
var x = req.body.x;
var y = req.body.y;
if (element && checkMissingParams(req, res, {element: element}, true)) {
req.device.touchMove(element, x, y, getResponseHandler(req, res));
} else if (checkMissingParams(req, res, {x: x, y: y}, true)) {
req.device.touchMove(element, x, y, getResponseHandler(req, res));
}
};
exports.mobileTap = function (req, res) {
req.body = _.defaults(req.body, {
tapCount: 1
, touchCount: 1
, duration: 0.1
, x: 0.5
, y: 0.5
, element: null
});
var tapCount = req.body.tapCount
, touchCount = req.body.touchCount
, duration = req.body.duration
, element = req.body.element
, x = req.body.x
, y = req.body.y;
req.device.complexTap(tapCount, touchCount, duration, x, y, element, getResponseHandler(req, res));
};
exports.mobileFlick = function (req, res) {
req.body = _.defaults(req.body, {
touchCount: 1
, startX: 0.5
, startY: 0.5
, endX: 0.5
, endY: 0.5
, element: null
});
var touchCount = req.body.touchCount
, element = req.body.element
, startX = req.body.startX
, startY = req.body.startY
, endX = req.body.endX
, endY = req.body.endY;
req.device.flick(startX, startY, endX, endY, touchCount, element, getResponseHandler(req, res));
};
exports.mobileDrag = function (req, res) {
req.body = _.defaults(req.body, {
startX: 0.5
, startY: 0.5
, endX: 0.5
, endY: 0.5
, duration: 1
, touchCount: 1
, element: null
, destEl: null
});
var touchCount = req.body.touchCount
, element = req.body.element
, destEl = req.body.destEl
, duration = req.body.duration
, startX = req.body.startX
, startY = req.body.startY
, endX = req.body.endX
, endY = req.body.endY;
req.device.drag(startX, startY, endX, endY, duration, touchCount, element, destEl, getResponseHandler(req, res));
};
var _getSwipeTouchDuration = function (waitGesture) {
// the touch action api uses ms, we want seconds
// 0.8 is the default time for the operation
var duration = 0.8;
if (typeof waitGesture.options.ms !== 'undefined' && waitGesture.options.ms) {
duration = waitGesture.options.ms / 1000;
if (duration === 0) {
// set to a very low number, since they wanted it fast
// but below 0.1 becomes 0 steps, which causes errors
duration = 0.1;
}
}
return duration;
};
exports.mobileSwipe = function (req, res, gestures) {
var getCoordDefault = function (val) {
// going the long way and checking for undefined and null since
// we can't be assured `elId` is a string and not an int. Same
// thing with destElement below.
return hasValue(val) ? val : 0.5;
};
var touchCount = req.body.touchCount || 1
, startX = getCoordDefault(gestures[0].options.x)
, startY = getCoordDefault(gestures[0].options.y)
, endX = getCoordDefault(gestures[2].options.x)
, endY = getCoordDefault(gestures[2].options.y)
, duration = _getSwipeTouchDuration(gestures[1])
, element = gestures[0].options.element
, destElement = gestures[2].options.element || gestures[0].options.element;
// there's no destination element handling in bootstrap and since it applies to all platforms, we handle it here
if (hasValue(destElement)) {
req.device.getLocation(destElement, function (err, locResult) {
if (err) {
respondError(req, res, err);
} else {
req.device.getSize(destElement, function (er, sizeResult) {
if (er) {
respondError(req, res, er);
} else {
var offsetX = (Math.abs(endX) < 1 && Math.abs(endX) > 0) ?
sizeResult.value.width * endX :
endX;
var offsetY = (Math.abs(endY) < 1 && Math.abs(endY) > 0) ?
sizeResult.value.height * endY :
endY;
var destX = locResult.value.x + offsetX;
var destY = locResult.value.y + offsetY;
// if the target element was provided, the coordinates for the destination need to be relative to it.
if (hasValue(element)) {
req.device.getLocation(element, function (e, firstElLocation) {
if (e) {
respondError(req, res, e);
} else {
destX -= firstElLocation.value.x;
destY -= firstElLocation.value.y;
req.device.swipe(startX, startY, destX, destY, duration, touchCount, element, getResponseHandler(req, res));
}
});
} else {
req.device.swipe(startX, startY, destX, destY, duration, touchCount, element, getResponseHandler(req, res));
}
}
});
}
});
} else {
req.device.swipe(startX, startY, endX, endY, duration, touchCount, element, getResponseHandler(req, res));
}
};
转载于:https://blog.51cto.com/10988776/1727933