Permalink
Browse files

Merge pull request #297 from jlipps/master

window maneuvering magic in safari
  • Loading branch information...
admc committed Mar 21, 2013
2 parents 39ad87e + 1cfa8c0 commit 5fb3dc5b6f758c6ad90bb73a35983c262337adaf
Showing with 304 additions and 51 deletions.
  1. +11 −0 app/controller.js
  2. +27 −14 app/hybrid/ios/remote-debugger.js
  3. +83 −17 app/ios.js
  4. +1 −0 app/routing.js
  5. +131 −0 app/test/guinea-pig.html
  6. +22 −1 test/functional/safari/safari.js
  7. +29 −19 test/helpers/webview.js
View
@@ -4,6 +4,8 @@
var status = require('./uiauto/lib/status')
, logger = require('../logger.js').get('appium')
, _s = require("underscore.string")
+ , fs = require('fs')
+ , path = require('path')
, _ = require('underscore');
function getResponseHandler(req, res) {
@@ -629,3 +631,12 @@ exports.produceError = function(req, res) {
exports.crash = function() {
throw new Error("We just tried to crash Appium!");
};
+
+exports.guineaPig = function(req, res) {
+ var file = path.resolve(__dirname, "test/guinea-pig.html");
+ fs.readFile(file, function(err, data) {
+ if (err) return res.send(500);
+ res.set('Content-Type', 'text/html');
+ res.send(data);
+ });
+};
@@ -43,6 +43,7 @@ var RemoteDebugger = function(onDisconnect) {
this.curMsgId = 0;
this.dataCbs = [];
this.onAppDisconnect = onDisconnect || noop;
+ this.pageChangeCb = noop;
this.specialCbs = {
'_rpc_reportIdentifier:': noop
, '_rpc_forwardGetListing:': noop
@@ -58,8 +59,9 @@ var RemoteDebugger = function(onDisconnect) {
// API
// ====================================
-RemoteDebugger.prototype.connect = function(cb) {
+RemoteDebugger.prototype.connect = function(cb, pageChangeCb) {
var me = this;
+ this.pageChangeCb = pageChangeCb;
this.socket = new net.Socket({type: 'tcp6'});
this.socket.on('close', function() {
logger.info('Debugger socket disconnected');
@@ -99,17 +101,21 @@ RemoteDebugger.prototype.selectApp = function(appIdKey, cb) {
this.appIdKey = appIdKey;
var connectToApp = messages.connectToApp(this.connId, this.appIdKey);
logger.info("Selecting app");
- this.send(connectToApp, function(pageDict) {
- var newPageArray = [];
- _.each(pageDict, function(dict) {
- newPageArray.push({
- id: dict.WIRPageIdentifierKey
- , title: dict.WIRTitleKey
- , url: dict.WIRURLKey
- });
+ this.send(connectToApp, _.bind(function(pageDict) {
+ cb(this.pageArrayFromDict(pageDict));
+ }, this));
+};
+
+RemoteDebugger.prototype.pageArrayFromDict = function(pageDict) {
+ var newPageArray = [];
+ _.each(pageDict, function(dict) {
+ newPageArray.push({
+ id: dict.WIRPageIdentifierKey
+ , title: dict.WIRTitleKey
+ , url: dict.WIRURLKey
});
- cb(newPageArray);
});
+ return newPageArray;
};
RemoteDebugger.prototype.selectPage = function(pageIdKey, cb) {
@@ -127,12 +133,17 @@ RemoteDebugger.prototype.selectPage = function(pageIdKey, cb) {
if (err || res.result.value == 'loading') {
me.pageUnload();
}
+ me.specialCbs['_rpc_forwardGetListing:'] = _.bind(me.onPageChange, me);
cb();
}, 0);
});
});
};
+RemoteDebugger.prototype.onPageChange = function(pageDict) {
+ this.pageChangeCb(this.pageArrayFromDict(pageDict));
+};
+
RemoteDebugger.prototype.executeAtom = function(atom, args, cb) {
var atomSrc = atoms.get(atom);
args = _.map(args, JSON.stringify);
@@ -198,9 +209,9 @@ RemoteDebugger.prototype.pageLoad = function() {
};
RemoteDebugger.prototype.pageUnload = function() {
- logger.debug("Page loading");
- this.pageLoading = true;
- this.waitForDom(noop);
+ logger.debug("Page loading");
+ this.pageLoading = true;
+ this.waitForDom(noop);
};
RemoteDebugger.prototype.waitForDom = function(cb) {
@@ -229,7 +240,9 @@ RemoteDebugger.prototype.handleMessage = function(plist) {
RemoteDebugger.prototype.handleSpecialMessage = function(specialCb) {
var fn = this.specialCbs[specialCb];
if (fn) {
- this.specialCbs[specialCb] = null;
+ if (specialCb != "_rpc_forwardGetListing:") {
+ this.specialCbs[specialCb] = null;
+ }
fn.apply(this, _.rest(arguments));
}
};
View
@@ -259,10 +259,6 @@ IOS.prototype.cleanupAppState = function(cb) {
IOS.prototype.listWebFrames = function(cb, exitCb) {
var me = this;
- if (this.remote) {
- logger.error("Can't enter a web frame when we're already in one!");
- throw new Error("Tried to enter a web frame when we were in one");
- }
if (!this.bundleId) {
logger.error("Can't enter web frame without a bundle ID");
throw new Error("Tried to enter web frame without a bundle ID");
@@ -281,11 +277,36 @@ IOS.prototype.listWebFrames = function(cb, exitCb) {
} else {
me.remote.selectApp(me.bundleId, cb);
}
- }, function() {
- logger.error("Remote debugger crashed before we shut it down!");
- me.stopRemote();
- exitCb();
+ }, _.bind(me.onPageChange, me));
+};
+
+IOS.prototype.onPageChange = function(pageArray) {
+ logger.info("Remote debugger notified us of a new page listing");
+ var newIds = []
+ , me = this;
+ _.each(pageArray, function(page) {
+ newIds.push(page.id.toString());
+ });
+ var newPages = [];
+ _.each(newIds, function(id) {
+ if (!_.contains(me.windowHandleCache, id)) {
+ newPages.push(id);
+ }
});
+ if (this.curWindowHandle === null) {
+ logger.info("We don't appear to have window set yet, ignoring");
+ } else if (newPages.length) {
+ logger.info("We have new pages, going to select page " + newPages[0]);
+ this.remote.selectPage(newPages[0], function() {
+ me.curWindowHandle = newPages[0];
+ });
+ } else if (!_.contains(me.windowHandleCache, me.curWindowHandle.toString())) {
+ logger.error("New page listing from remote debugger doesn't contain " +
+ "current window, not sure how to proceed");
+ } else {
+ logger.info("New page listing is same as old, doing nothing");
+ }
+ this.windowHandleCache = newIds;
};
IOS.prototype.getAtomsElement = function(wdId) {
@@ -507,8 +528,11 @@ IOS.prototype.findAndAct = function(strategy, selector, index, action, actionPar
// if you change these, also change in
// app/uiauto/appium/app.js:elemForAction
, supportedActions = ["tap", "isEnabled", "isValid", "isVisible",
- "value", "name", "label", "setValue"]
+ "value", "name", "label", "setValue", "click",
+ "selectPage"]
, many = index > 0;
+
+ if (action === "click") { action = "tap"; }
var doAction = function(findCb) {
var cmd = ["au.elemForAction(au.getElement", (many ? 's': ''), "By",
stratMap[strategy], "('", selector, "'), ", index].join('');
@@ -593,7 +617,6 @@ IOS.prototype.click = function(elementId, cb) {
};
IOS.prototype.clickCurrent = function(button, cb) {
- //console.log("clicking current loc");
var noMoveToErr = {
status: status.codes.UnknownError.code
, value: "Cannot call click() before calling moveTo() to set coords"
@@ -613,7 +636,6 @@ IOS.prototype.clickCurrent = function(button, cb) {
};
IOS.prototype.clickCoords = function(coords, cb) {
- //console.log("native-tapping coords");
var opts = coords;
opts.tapCount = 1;
opts.duration = 0.3;
@@ -1122,18 +1144,62 @@ IOS.prototype.setWindow = function(name, cb) {
var me = this;
if (_.contains(this.windowHandleCache, name)) {
var pageIdKey = parseInt(name, 10);
- me.remote.selectPage(pageIdKey, function() {
- me.curWindowHandle = pageIdKey;
- cb(null, {
- status: status.codes.Success.code
- , value: ''
+ var next = function() {
+ me.remote.selectPage(pageIdKey, function() {
+ me.curWindowHandle = pageIdKey;
+ cb(null, {
+ status: status.codes.Success.code
+ , value: ''
+ });
});
- });
+ };
+ //if (me.autoWebview) {
+ //me.setSafariWindow(pageIdKey - 1, function(err, res) {
+ //if (err) {
+ //cb(err);
+ //} else if (res.status !== status.codes.Success.code) {
+ //cb(res.status);
+ //} else {
+ //next();
+ //}
+ //});
+ //} else {
+ next();
+ //}
} else {
cb(status.codes.NoSuchWindow.code, null);
}
};
+IOS.prototype.setSafariWindow = function(windowId, cb) {
+ var me = this;
+ var success = function(err, res, cb) {
+ if (err || res.status !== status.codes.Success.code) {
+ cb(err, res);
+ return false;
+ }
+ return true;
+ };
+
+ me.findAndAct('name', 'Pages', 0, 'value', [], function(err, res) {
+ if (success(err, res, cb)) {
+ if (res.value === "") {
+ cb(err, res);
+ } else {
+ me.findAndAct('name', 'Pages', 0, 'tap', [], function(err, res) {
+ if (success(err, res, cb)) {
+ me.findAndAct('tag name', 'pageIndicator', 0, 'selectPage', [windowId], function(err, res) {
+ if (success(err, res, cb)) {
+ me.findAndAct('name', 'Done', 0, 'tap', [], cb);
+ }
+ });
+ }
+ });
+ }
+ }
+ });
+};
+
IOS.prototype.clearWebView = function(cb) {
if (this.curWindowHandle === null) {
cb(new NotImplementedError(), null);
View
@@ -68,6 +68,7 @@ module.exports = function(appium) {
// these are for testing purposes only
rest.post('/wd/hub/produce_error', controller.produceError);
rest.post('/wd/hub/crash', controller.crash);
+ rest.get('/guinea-pig', controller.guineaPig);
// appium-specific extensions to JSONWP
// these aren't part of JSONWP but we want them or something like them to be
Oops, something went wrong.

0 comments on commit 5fb3dc5

Please sign in to comment.