Bug 867220 - Make setSearchTimeout behave globally, r=mdas
authorJonathan Griffin <jgriffin@mozilla.com>
Wed, 01 May 2013 10:16:49 -0700
changeset 141440 95993aae5d96683971f22d8a06beca27ff1be599
parent 141439 fab7a1635246e1a18d113c8d48208ba72d1b2b9d
child 141441 4fbf994a4b1f5876281c4dc921ababf43d791258
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmdas
bugs867220
milestone23.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 867220 - Make setSearchTimeout behave globally, r=mdas
testing/marionette/marionette-actors.js
testing/marionette/marionette-elements.js
testing/marionette/marionette-listener.js
--- a/testing/marionette/marionette-actors.js
+++ b/testing/marionette/marionette-actors.js
@@ -183,16 +183,17 @@ function MarionetteDriverActor(aConnecti
   this.conn = aConnection;
   this.globalMessageManager = Cc["@mozilla.org/globalmessagemanager;1"]
                              .getService(Ci.nsIMessageBroadcaster);
   this.messageManager = this.globalMessageManager;
   this.browsers = {}; //holds list of BrowserObjs
   this.curBrowser = null; // points to current browser
   this.context = "content";
   this.scriptTimeout = null;
+  this.searchTimeout = null;
   this.pageTimeout = null;
   this.timer = null;
   this.marionetteLog = new MarionetteLogObj();
   this.command_id = null;
   this.mainFrame = null; //topmost chrome frame
   this.curFrame = null; //subframe that currently has focus
   this.importedScripts = FileUtils.getFile('TmpD', ['marionettescriptchrome']);
   this.currentRemoteFrame = null; // a member of remoteFrames
@@ -1284,29 +1285,23 @@ MarionetteDriverActor.prototype = {
   /**
    * Set timeout for searching for elements
    *
    * @param object aRequest
    *        'value' holds the search timeout in milliseconds
    */
   setSearchTimeout: function MDA_setSearchTimeout(aRequest) {
     this.command_id = this.getCommandId();
-    if (this.context == "chrome") {
-      try {
-        this.curBrowser.elementManager.setSearchTimeout(aRequest.value);
-        this.sendOk(this.command_id);
-      }
-      catch (e) {
-        this.sendError(e.message, e.code, e.stack, this.command_id);
-      }
+    let timeout = parseInt(aRequest.value);
+    if (isNaN(timeout)) {
+      this.sendError("Not a Number", 500, null, this.command_id);
     }
     else {
-      this.sendAsync("setSearchTimeout",
-                     { value: aRequest.value },
-                     this.command_id);
+      this.searchTimeout = timeout;
+      this.sendOk(this.command_id);
     }
   },
 
 /**
  * Set a value to decide if sending mouse event
  *
  * @param object aRequest
  *        'value' holds the boolean value
@@ -1435,32 +1430,34 @@ MarionetteDriverActor.prototype = {
     if (this.context == "chrome") {
       let id;
       try {
         let on_success = this.sendResponse.bind(this);
         let on_error = this.sendError.bind(this);
         id = this.curBrowser.elementManager.find(
                               this.getCurrentWindow(),
                               aRequest,
+                              this.searchTimeout,
                               on_success,
                               on_error,
                               false,
                               command_id);
       }
       catch (e) {
         this.sendError(e.message, e.code, e.stack, command_id);
         return;
       }
     }
     else {
       this.sendAsync("findElementContent",
                      {
                        value: aRequest.value,
                        using: aRequest.using,
-                       element: aRequest.element
+                       element: aRequest.element,
+                       searchTimeout: this.searchTimeout
                      },
                      command_id);
     }
   },
 
   /**
    * Find elements using the indicated search strategy.
    *
@@ -1472,32 +1469,34 @@ MarionetteDriverActor.prototype = {
     let command_id = this.command_id = this.getCommandId();
     if (this.context == "chrome") {
       let id;
       try {
         let on_success = this.sendResponse.bind(this);
         let on_error = this.sendError.bind(this);
         id = this.curBrowser.elementManager.find(this.getCurrentWindow(),
                                                  aRequest,
+                                                 this.searchTimeout,
                                                  on_success,
                                                  on_error,
                                                  true,
                                                  command_id);
       }
       catch (e) {
         this.sendError(e.message, e.code, e.stack, command_id);
         return;
       }
     }
     else {
       this.sendAsync("findElementsContent",
                      {
                        value: aRequest.value,
                        using: aRequest.using,
-                       element: aRequest.element
+                       element: aRequest.element,
+                       searchTimeout: this.searchTimeout
                      },
                      command_id);
     }
   },
 
   /**
    * Return the active element on the page
    */
@@ -2139,22 +2138,17 @@ MarionetteDriverActor.prototype = {
           // independent window list.  So, it will either be null (!listenerWindow)
           // or it will point to some random window, which will hopefully 
           // cause an href mistmach.  Currently this only happens
           // in B2G for OOP frames registered in Marionette:switchToFrame, so
           // we'll acknowledge the switchToFrame message here.
           // XXX: Should have a better way of determining that this message
           // is from a remote frame.
           this.currentRemoteFrame.targetFrameId = this.generateFrameId(message.json.value);
-          this.sendAsync("setState",
-                         {
-                           scriptTimeout: this.scriptTimeout,
-                           searchTimeout: this.curBrowser.elementManager.searchTimeout
-                         },
-                         this.currentRemoteFrame.command_id);
+          this.sendOk(this.currentRemoteFrame.command_id);
         }
 
         let browserType;
         try {
           browserType = message.target.getAttribute("type");
         } catch (ex) {
           // browserType remains undefined.
         }
--- a/testing/marionette/marionette-elements.js
+++ b/testing/marionette/marionette-elements.js
@@ -37,31 +37,29 @@ this.XPATH = "xpath";
 
 function ElementException(msg, num, stack) {
   this.message = msg;
   this.code = num;
   this.stack = stack;
 }
 
 this.ElementManager = function ElementManager(notSupported) {
-  this.searchTimeout = 0;
   this.seenItems = {};
   this.timer = Components.classes["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer);
   this.elementStrategies = [CLASS_NAME, SELECTOR, ID, NAME, LINK_TEXT, PARTIAL_LINK_TEXT, TAG, XPATH];
   for (let i = 0; i < notSupported.length; i++) {
     this.elementStrategies.splice(this.elementStrategies.indexOf(notSupported[i]), 1);
   }
 }
 
 ElementManager.prototype = {
   /**
    * Reset values
    */
   reset: function EM_clear() {
-    this.searchTimeout = 0;
     this.seenItems = {};
   },
 
   /**
   * Add element to list of seen elements
   *
   * @param nsIDOMElement element
   *        The element to add
@@ -263,43 +261,46 @@ ElementManager.prototype = {
             The callback to invoke when an error occurs.
    * @param boolean all
    *        If true, all found elements will be returned.
    *        If false, only the first element will be returned.
    *
    * @return nsIDOMElement or list of nsIDOMElements
    *        Returns the element(s) by calling the on_success function.
    */
-  find: function EM_find(win, values, on_success, on_error, all, command_id) {
+  find: function EM_find(win, values, searchTimeout, on_success, on_error, all, command_id) {
     let startTime = values.time ? values.time : new Date().getTime();
-    let startNode = (values.element != undefined) ? this.getKnownElement(values.element, win) : win.document;
+    let startNode = (values.element != undefined) ?
+                    this.getKnownElement(values.element, win) : win.document;
     if (this.elementStrategies.indexOf(values.using) < 0) {
       throw new ElementException("No such strategy.", 17, null);
     }
-    let found = all ? this.findElements(values.using, values.value, win.document, startNode) : this.findElement(values.using, values.value, win.document, startNode);
+    let found = all ? this.findElements(values.using, values.value, win.document, startNode) :
+                      this.findElement(values.using, values.value, win.document, startNode);
     if (found) {
       let type = Object.prototype.toString.call(found);
       if ((type == '[object Array]') || (type == '[object HTMLCollection]') || (type == '[object NodeList]')) {
         let ids = []
         for (let i = 0 ; i < found.length ; i++) {
           ids.push(this.addToKnownElements(found[i]));
         }
         on_success(ids, command_id);
       }
       else {
         let id = this.addToKnownElements(found);
         on_success(id, command_id);
       }
       return;
     } else {
-      if (this.searchTimeout == 0 || new Date().getTime() - startTime > this.searchTimeout) {
+      if (!searchTimeout || new Date().getTime() - startTime > searchTimeout) {
         on_error("Unable to locate element: " + values.value, 7, null, command_id);
       } else {
         values.time = startTime;
         this.timer.initWithCallback(this.find.bind(this, win, values,
+                                                   searchTimeout,
                                                    on_success, on_error, all,
                                                    command_id),
                                     100,
                                     Components.interfaces.nsITimer.TYPE_ONE_SHOT);
       }
     }
   },
 
@@ -457,22 +458,9 @@ ElementManager.prototype = {
       case SELECTOR:
         elements = Array.slice(startNode.querySelectorAll(value));
         break;
       default:
         throw new ElementException("No such strategy", 500, null);
     }
     return elements;
   },
-
-  /**
-   * Sets the timeout for searching for elements with find element
-   * 
-   * @param number value
-   *        Timeout value in milliseconds
-   */
-  setSearchTimeout: function EM_setSearchTimeout(value) {
-    this.searchTimeout = parseInt(value);
-    if(isNaN(this.searchTimeout)){
-      throw new ElementException("Not a Number", 500, null);
-    }
-  },
 }
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -107,17 +107,16 @@ function startListeners() {
   addMessageListenerId("Marionette:newSession", newSession);
   addMessageListenerId("Marionette:executeScript", executeScript);
   addMessageListenerId("Marionette:executeAsyncScript", executeAsyncScript);
   addMessageListenerId("Marionette:executeJSScript", executeJSScript);
   addMessageListenerId("Marionette:singleTap", singleTap);
   addMessageListenerId("Marionette:actionChain", actionChain);
   addMessageListenerId("Marionette:multiAction", multiAction);
   addMessageListenerId("Marionette:sendMouseEvent", sendMouseEvent);
-  addMessageListenerId("Marionette:setSearchTimeout", setSearchTimeout);
   addMessageListenerId("Marionette:goUrl", goUrl);
   addMessageListenerId("Marionette:getUrl", getUrl);
   addMessageListenerId("Marionette:getTitle", getTitle);
   addMessageListenerId("Marionette:getPageSource", getPageSource);
   addMessageListenerId("Marionette:goBack", goBack);
   addMessageListenerId("Marionette:goForward", goForward);
   addMessageListenerId("Marionette:refresh", refresh);
   addMessageListenerId("Marionette:findElementContent", findElementContent);
@@ -136,17 +135,16 @@ function startListeners() {
   addMessageListenerId("Marionette:clearElement", clearElement);
   addMessageListenerId("Marionette:switchToFrame", switchToFrame);
   addMessageListenerId("Marionette:deleteSession", deleteSession);
   addMessageListenerId("Marionette:sleepSession", sleepSession);
   addMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
   addMessageListenerId("Marionette:importScript", importScript);
   addMessageListenerId("Marionette:getAppCacheStatus", getAppCacheStatus);
   addMessageListenerId("Marionette:setTestName", setTestName);
-  addMessageListenerId("Marionette:setState", setState);
   addMessageListenerId("Marionette:screenShot", screenShot);
   addMessageListenerId("Marionette:addCookie", addCookie);
   addMessageListenerId("Marionette:getAllCookies", getAllCookies);
   addMessageListenerId("Marionette:deleteAllCookies", deleteAllCookies);
   addMessageListenerId("Marionette:deleteCookie", deleteCookie);
 }
 
 /**
@@ -164,31 +162,16 @@ function newSession(msg) {
  * alive for reuse in B2G instead of reloading it each time.
  */
 function sleepSession(msg) {
   deleteSession();
   addMessageListener("Marionette:restart", restart);
 }
 
 /**
- * Sets script-wide state variables; used after frame switching.
- */
-function setState(msg) {
-  marionetteTimeout = msg.json.scriptTimeout;
-  try {
-    elementManager.setSearchTimeout(msg.json.searchTimeout);
-  }
-  catch (e) {
-    sendError(e.message, e.code, e.stack, msg.json.command_id);
-    return;
-  }
-  sendOk(msg.json.command_id);
-}
-
-/**
  * Restarts all our listeners after this listener was put to sleep
  */
 function restart(msg) {
   removeMessageListener("Marionette:restart", restart);
   registerSelf();
 }
 
 /**
@@ -198,17 +181,16 @@ function deleteSession(msg) {
   removeMessageListenerId("Marionette:newSession", newSession);
   removeMessageListenerId("Marionette:executeScript", executeScript);
   removeMessageListenerId("Marionette:executeAsyncScript", executeAsyncScript);
   removeMessageListenerId("Marionette:executeJSScript", executeJSScript);
   removeMessageListenerId("Marionette:singleTap", singleTap);
   removeMessageListenerId("Marionette:actionChain", actionChain);
   removeMessageListenerId("Marionette:multiAction", multiAction);
   removeMessageListenerId("Marionette:sendMouseEvent", sendMouseEvent);
-  removeMessageListenerId("Marionette:setSearchTimeout", setSearchTimeout);
   removeMessageListenerId("Marionette:goUrl", goUrl);
   removeMessageListenerId("Marionette:getTitle", getTitle);
   removeMessageListenerId("Marionette:getPageSource", getPageSource);
   removeMessageListenerId("Marionette:getUrl", getUrl);
   removeMessageListenerId("Marionette:goBack", goBack);
   removeMessageListenerId("Marionette:goForward", goForward);
   removeMessageListenerId("Marionette:refresh", refresh);
   removeMessageListenerId("Marionette:findElementContent", findElementContent);
@@ -226,17 +208,16 @@ function deleteSession(msg) {
   removeMessageListenerId("Marionette:clearElement", clearElement);
   removeMessageListenerId("Marionette:switchToFrame", switchToFrame);
   removeMessageListenerId("Marionette:deleteSession", deleteSession);
   removeMessageListenerId("Marionette:sleepSession", sleepSession);
   removeMessageListenerId("Marionette:emulatorCmdResult", emulatorCmdResult);
   removeMessageListenerId("Marionette:importScript", importScript);
   removeMessageListenerId("Marionette:getAppCacheStatus", getAppCacheStatus);
   removeMessageListenerId("Marionette:setTestName", setTestName);
-  removeMessageListenerId("Marionette:setState", setState);
   removeMessageListenerId("Marionette:screenShot", screenShot);
   removeMessageListenerId("Marionette:addCookie", addCookie);
   removeMessageListenerId("Marionette:getAllCookies", getAllCookies);
   removeMessageListenerId("Marionette:deleteAllCookies", deleteAllCookies);
   removeMessageListenerId("Marionette:deleteCookie", deleteCookie);
   this.elementManager.reset();
   // reset frame to the top-most frame
   curWindow = content;
@@ -1231,30 +1212,16 @@ function multiAction(msg) {
     setDispatch(concurrentEvent, pendingTouches, command_id);
   }
   catch (e) {
     sendError(e.message, e.code, e.stack, msg.json.command_id);
   }
 }
 
 /**
- * Function to set the timeout period for element searching 
- */
-function setSearchTimeout(msg) {
-  try {
-    elementManager.setSearchTimeout(msg.json.value);
-  }
-  catch (e) {
-    sendError(e.message, e.code, e.stack, msg.json.command_id);
-    return;
-  }
-  sendOk(msg.json.command_id);
-}
-
-/**
  * Navigate to URI. Handles the case where we navigate within an iframe.
  * All other navigation is handled by the server (in chrome space).
  */
 function goUrl(msg) {
   let command_id = msg.json.command_id;
   // Prevent DOMContentLoaded events from frames from invoking this code,
   // unless the event is coming from the frame associated with the current
   // window (i.e., someone has used switch_to_frame).
@@ -1339,32 +1306,34 @@ function refresh(msg) {
 /**
  * Find an element in the document using requested search strategy 
  */
 function findElementContent(msg) {
   let command_id = msg.json.command_id;
   try {
     let on_success = function(id, cmd_id) { sendResponse({value:id}, cmd_id); };
     let on_error = sendError;
-    elementManager.find(curWindow, msg.json, on_success, on_error, false, command_id);
+    elementManager.find(curWindow, msg.json, msg.json.searchTimeout,
+                        on_success, on_error, false, command_id);
   }
   catch (e) {
     sendError(e.message, e.code, e.stack, command_id);
   }
 }
 
 /**
  * Find elements in the document using requested search strategy 
  */
 function findElementsContent(msg) {
   let command_id = msg.json.command_id;
   try {
     let on_success = function(id, cmd_id) { sendResponse({value:id}, cmd_id); };
     let on_error = sendError;
-    elementManager.find(curWindow, msg.json, on_success, on_error, true, command_id);
+    elementManager.find(curWindow, msg.json, msg.json.searchTimeout,
+                        on_success, on_error, true, command_id);
   }
   catch (e) {
     sendError(e.message, e.code, e.stack, command_id);
   }
 }
 
 /**
  * Find and return the active element on the page