From 06e711237a91550f1027be7ebbf1abdb886573da Mon Sep 17 00:00:00 2001 From: Jonathan Lipps Date: Wed, 18 Dec 2013 16:56:02 -0800 Subject: [PATCH] support automation of safari on ios7 --- lib/appium.js | 51 +++++++++++++----------------- lib/devices/ios/ios-controller.js | 26 +++++++-------- lib/devices/ios/ios.js | 5 ++- lib/devices/ios/remote-debugger.js | 8 ++++- lib/devices/ios/safari.js | 43 +++++++++++++------------ 5 files changed, 69 insertions(+), 64 deletions(-) diff --git a/lib/appium.js b/lib/appium.js index 15798cb37..939494859 100644 --- a/lib/appium.js +++ b/lib/appium.js @@ -10,6 +10,7 @@ var routing = require('./server/routing.js') , checkSafari = helpers.checkSafari , cleanSafari = helpers.cleanSafari , copyLocalZip = helpers.copyLocalZip + , getiOSSDKVersion = helpers.getiOSSDKVersion , UUID = require('uuid-js') , _ = require('underscore') , fs = require('fs') @@ -354,52 +355,44 @@ Appium.prototype.configureDownloadedApp = function(appPath, origin, cb) { Appium.prototype.configureSafari = function(desiredCaps, cb) { this.desiredCapabilities.safari = true; - var safariVer = "6.1"; - var usingDefaultVer = true; + var safariVer = null; if (typeof desiredCaps.version !== "undefined") { safariVer = desiredCaps.version; - usingDefaultVer = false; } logger.info("Trying to use mobile safari, version " + safariVer); - var checkSuccess = function(attemptedApp) { + var checkNext = function(attemptedApp, origApp, safariVer) { logger.info("Using mobile safari app at " + attemptedApp); this.args.app = attemptedApp; - cleanSafariNext(); - }.bind(this); - var cleanSafariNext = function() { logger.info("Cleaning mobile safari data files"); cleanSafari(safariVer, function(err) { if (err) { logger.error(err.message); cb(err); } else { + this.origAppPath = origApp; cb(null); } + }.bind(this)); + }.bind(this); + var sdkNext = function(safariVer) { + checkSafari(safariVer, function(err, attemptedApp, origApp) { + if (err) { + logger.error("Could not prepare mobile safari with version '" + + safariVer + "': " + err); + return cb(err); + } + checkNext(attemptedApp, origApp, safariVer); }); }; - checkSafari(safariVer, function(err, attemptedApp) { - if (err) { - logger.warn("Could not find mobile safari with version '" + safariVer + - "': " + err); - if (usingDefaultVer) { - safariVer = "6.1"; - logger.info("Retrying with safari ver " + safariVer); - checkSafari(safariVer, function(err, attemptedApp) { - if (err) { - logger.warn("Could not find this one either: " + err); - cb(err); - } else { - checkSuccess(attemptedApp); - } - }.bind(this)); - } else { - cb(err); - } - } else { - checkSuccess(attemptedApp); - } - }.bind(this)); + if (safariVer === null) { + getiOSSDKVersion(function(err, safariVer) { + if (err) return cb(err); + sdkNext(safariVer); + }); + } else { + sdkNext(safariVer); + } }; Appium.prototype.configureSafariForLauncher = function (desiredCaps, cb) { diff --git a/lib/devices/ios/ios-controller.js b/lib/devices/ios/ios-controller.js index cbbb4fcef..56afc8610 100644 --- a/lib/devices/ios/ios-controller.js +++ b/lib/devices/ios/ios-controller.js @@ -221,18 +221,18 @@ iOSController.click = function(elementId, cb) { this.executeAtom('tap', [atomsElement], cb); }.bind(this)); } else { - if (this.useRobot) { - var locCmd = "au.getElement('" + elementId + "').rect()"; - this.proxy(locCmd, function(err, res) { - if (err) return cb(err, res); - var rect = res.value; - var pos = {x: rect.origin.x, y: rect.origin.y}; - var size = {w: rect.size.width, h: rect.size.height}; - var tapPoint = { x: pos.x + (size.w/2), y: pos.y + (size.h/2) }; - var tapUrl = this.robotUrl + "/tap/x/" + tapPoint.x + "/y/" + tapPoint.y; - request.get(tapUrl, {}, cb); - }.bind(this)); - } else { + if (this.useRobot) { + var locCmd = "au.getElement('" + elementId + "').rect()"; + this.proxy(locCmd, function(err, res) { + if (err) return cb(err, res); + var rect = res.value; + var pos = {x: rect.origin.x, y: rect.origin.y}; + var size = {w: rect.size.width, h: rect.size.height}; + var tapPoint = { x: pos.x + (size.w/2), y: pos.y + (size.h/2) }; + var tapUrl = this.robotUrl + "/tap/x/" + tapPoint.x + "/y/" + tapPoint.y; + request.get(tapUrl, {}, cb); + }.bind(this)); + } else { var command = ["au.tapById('", elementId, "')"].join(''); this.proxy(command, cb); } @@ -1138,7 +1138,7 @@ iOSController.setWindow = function(name, cb) { var pageIdKey = parseInt(name, 10); var next = function() { this.processingRemoteCmd = true; - if(this.udid === null) { + if (this.udid === null) { this.remote.selectPage(pageIdKey, function() { this.curWindowHandle = pageIdKey.toString(); cb(null, { diff --git a/lib/devices/ios/ios.js b/lib/devices/ios/ios.js index 5e37875d0..8c1ed1869 100644 --- a/lib/devices/ios/ios.js +++ b/lib/devices/ios/ios.js @@ -825,7 +825,10 @@ IOS.prototype.shutdown = function(code, traceDir, cb) { } }.bind(this); - async.series([removeTraceDir, this.postCleanup.bind(this)], function() { + async.series([ + removeTraceDir, + this.postCleanup.bind(this) + ], function() { cb(); }); diff --git a/lib/devices/ios/remote-debugger.js b/lib/devices/ios/remote-debugger.js index bbc58c189..57c6a9f67 100644 --- a/lib/devices/ios/remote-debugger.js +++ b/lib/devices/ios/remote-debugger.js @@ -371,13 +371,19 @@ RemoteDebugger.prototype.pageLoad = function() { }); } else { logger.debug("Page was not ready, retrying"); - setTimeout(verify, intMs); + this.loadingTimeout = setTimeout(verify, intMs); } }.bind(this)); }.bind(this); verify(); }; +RemoteDebugger.prototype.cancelPageLoad = function() { + this.pageLoadedCbs = []; + this.pageLoading = false; + clearTimeout(this.loadingTimeout); +}; + RemoteDebugger.prototype.frameNavigated = function() { logger.info("Frame navigated, calling cbs"); clearTimeout(this.navigatingTimeout); diff --git a/lib/devices/ios/safari.js b/lib/devices/ios/safari.js index 5d4331812..62d70e626 100644 --- a/lib/devices/ios/safari.js +++ b/lib/devices/ios/safari.js @@ -31,27 +31,30 @@ Safari.prototype.navToInitialWebview = function(cb) { Safari.prototype.navToLatestAvailableWebview = function(cb) { logger.info("Navigating to most recently opened webview"); - var start = Date.now(); - var spinHandles = function() { - this.getWindowHandles(function(err, res) { - if (res.status !== 0) { - cb(new Error("Could not navigate to webview! Code: " + res.status)); - } else if (res.value.length < 1) { - if ((Date.now() - start) < 6000) { - logger.warn("Could not find any webviews yet, retrying"); - return setTimeout(spinHandles, 500); + this.complexTap(1, 1, 0.4, 0.14, 0.23, null, function() { + var start = Date.now(); + var spinHandles = function() { + this.getWindowHandles(function(err, res) { + if (res.status !== 0) { + cb(new Error("Could not navigate to webview! Code: " + res.status)); + } else if (res.value.length < 1) { + if ((Date.now() - start) < 6000) { + logger.warn("Could not find any webviews yet, retrying"); + return setTimeout(spinHandles, 500); + } + cb(new Error("Could not navigate to webview; there aren't any!")); + } else { + logger.info("Picking webview " + res.value[0]); + this.setWindow(res.value[res.value.length - 1], function(err) { + if (err) return cb(err); + this.remote.cancelPageLoad(); + cb(); + }.bind(this)); } - cb(new Error("Could not navigate to webview; there aren't any!")); - } else { - logger.info("Picking webview " + res.value[0]); - this.setWindow(res.value[res.value.length - 1], function(err) { - if (err) return cb(err); - cb(); - }); - } - }.bind(this)); - }.bind(this); - spinHandles(); + }.bind(this)); + }.bind(this); + spinHandles(); + }.bind(this)); }; module.exports = Safari;