Bug 786032 - Make search timeouts fail successfully, r=mdas, DONTBUILD because NPOTB
authorJonathan Griffin <jgriffin@mozilla.com>
Mon, 27 Aug 2012 13:50:34 -0700
changeset 105722 8a41f262b382442039e32a1d619dfad09913ce60
parent 105721 e6cc3b189dcf840566d6b8f7f7930a741744b7fe
child 105723 16f3f0aab884a061d073e6fbe422500ea330356a
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersmdas, DONTBUILD
bugs786032
milestone18.0a1
Bug 786032 - Make search timeouts fail successfully, r=mdas, DONTBUILD because NPOTB
testing/marionette/client/marionette/tests/unit/test_findelement.py
testing/marionette/marionette-actors.js
testing/marionette/marionette-elements.js
testing/marionette/marionette-listener.js
--- a/testing/marionette/client/marionette/tests/unit/test_findelement.py
+++ b/testing/marionette/client/marionette/tests/unit/test_findelement.py
@@ -111,16 +111,19 @@ class TestElements(MarionetteTestCase):
         self.assertEqual(el, found_el)
         found_el = self.marionette.find_elements("xpath", "id('mozLink')")[0]
         self.assertEqual(HTMLElement, type(found_el))
         self.assertEqual(el, found_el)
 
     def test_not_found(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
+        self.marionette.set_search_timeout(1000)
+        self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "I'm not on the page")
+        self.marionette.set_search_timeout(0)
         self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "I'm not on the page")
 
     def test_timeout(self):
         test_html = self.marionette.absolute_url("test.html")
         self.marionette.navigate(test_html)
         self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "newDiv")
         self.assertTrue(True, self.marionette.set_search_timeout(4000))
         self.marionette.navigate(test_html)
@@ -172,17 +175,19 @@ class TestElementsChrome(MarionetteTestC
 
     def test_xpath(self):
         el = self.marionette.execute_script("return window.document.getElementById('testBox');")
         found_el = self.marionette.find_element("xpath", "id('testBox')")
         self.assertEqual(HTMLElement, type(found_el));
         self.assertEqual(el, found_el)
 
     def test_not_found(self):
+        self.marionette.set_search_timeout(1000)
         self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "I'm not on the page")
-
+        self.marionette.set_search_timeout(0)
+        self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "I'm not on the page")
 
     def test_timeout(self):
         self.assertRaises(NoSuchElementException, self.marionette.find_element, "id", "myid")
         self.assertTrue(True, self.marionette.set_search_timeout(4000))
         self.marionette.execute_script("window.setTimeout(function() {var b = window.document.createElement('button'); b.id = 'myid'; document.getElementById('things').appendChild(b);}, 1000)")
         self.assertEqual(HTMLElement, type(self.marionette.find_element("id", "myid")))
         self.marionette.execute_script("window.document.getElementById('things').removeChild(window.document.getElementById('myid'));")
--- a/testing/marionette/marionette-actors.js
+++ b/testing/marionette/marionette-actors.js
@@ -976,18 +976,19 @@ MarionetteDriverActor.prototype = {
    * @param object aRequest
    *        'using' member indicates which search method to use
    *        'value' member is the value the client is looking for
    */
   findElement: function MDA_findElement(aRequest) {
     if (this.context == "chrome") {
       let id;
       try {
-        let notify = this.sendResponse.bind(this);
-        id = this.curBrowser.elementManager.find(this.getCurrentWindow(),aRequest, notify, false);
+        let on_success = this.sendResponse.bind(this);
+        let on_error = this.sendError.bind(this);
+        id = this.curBrowser.elementManager.find(this.getCurrentWindow(),aRequest, on_success, on_error, false);
       }
       catch (e) {
         this.sendError(e.message, e.code, e.stack);
         return;
       }
     }
     else {
       this.sendAsync("findElementContent", {value: aRequest.value, using: aRequest.using, element: aRequest.element});
@@ -1000,18 +1001,19 @@ MarionetteDriverActor.prototype = {
    * @param object aRequest
    *        'using' member indicates which search method to use
    *        'value' member is the value the client is looking for
    */
   findElements: function MDA_findElements(aRequest) {
     if (this.context == "chrome") {
       let id;
       try {
-        let notify = this.sendResponse.bind(this);
-        id = this.curBrowser.elementManager.find(this.getCurrentWindow(), aRequest, notify, true);
+        let on_success = this.sendResponse.bind(this);
+        let on_error = this.sendError.bind(this);
+        id = this.curBrowser.elementManager.find(this.getCurrentWindow(), aRequest, on_success, on_error, true);
       }
       catch (e) {
         this.sendError(e.message, e.code, e.stack);
         return;
       }
     }
     else {
       this.sendAsync("findElementsContent", {value: aRequest.value, using: aRequest.using, element: aRequest.element});
--- a/testing/marionette/marionette-elements.js
+++ b/testing/marionette/marionette-elements.js
@@ -230,52 +230,54 @@ ElementManager.prototype = {
    * @param object values
    *        The 'using' member of values will tell us which search
    *        method to use. The 'value' member tells us the value we
    *        are looking for.
    *        If this object has an 'element' member, this will be used
    *        as the start node instead of the document root
    *        If this object has a 'time' member, this number will be
    *        used to see if we have hit the search timelimit.
-   * @param function notify
-   *        The notification callback used when we are returning
+   * @param function on_success
+   *        The notification callback used when we are returning successfully.
+   * @param function on_error
+            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 notify function.
+   *        Returns the element(s) by calling the on_success function.
    */
-  find: function EM_find(win, values, notify, all) {
+  find: function EM_find(win, values, on_success, on_error, all) {
     let startTime = values.time ? values.time : new Date().getTime();
     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);
     if (found) {
       let type = Object.prototype.toString.call(found);
       if ((type == '[object Array]') || (type == '[object HTMLCollection]')) {
         let ids = []
         for (let i = 0 ; i < found.length ; i++) {
           ids.push(this.addToKnownElements(found[i]));
         }
-        notify(ids);
+        on_success(ids);
       }
       else {
         let id = this.addToKnownElements(found);
-        notify(id);
+        on_success(id);
       }
       return;
     } else {
       if (this.searchTimeout == 0 || new Date().getTime() - startTime > this.searchTimeout) {
-        throw new ElementException("Unable to locate element: " + values.value, 7, null);
+        on_error("Unable to locate element: " + values.value, 7, null);
       } else {
         values.time = startTime;
-        this.timer.initWithCallback(this.find.bind(this, win, values, notify, all), 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
+        this.timer.initWithCallback(this.find.bind(this, win, values, on_success, on_error, all), 100, Components.interfaces.nsITimer.TYPE_ONE_SHOT);
       }
     }
   },
 
   /**
    * Find a value by XPATH
    * 
    * @param nsIDOMElement root
--- a/testing/marionette/marionette-listener.js
+++ b/testing/marionette/marionette-listener.js
@@ -557,34 +557,34 @@ function refresh(msg) {
   let listen = function() { removeEventListener("DOMContentLoaded", arguments.callee, false); sendOk() } ;
   addEventListener("DOMContentLoaded", listen, false);
 }
 
 /**
  * Find an element in the document using requested search strategy 
  */
 function findElementContent(msg) {
-  let id;
   try {
-    let notify = function(id) { sendResponse({value:id});};
-    id = elementManager.find(curWindow, msg.json, notify, false);
+    let on_success = function(id) { sendResponse({value:id}); };
+    let on_error = sendError;
+    elementManager.find(curWindow, msg.json, on_success, on_error, false);
   }
   catch (e) {
     sendError(e.message, e.code, e.stack);
   }
 }
 
 /**
  * Find elements in the document using requested search strategy 
  */
 function findElementsContent(msg) {
-  let id;
   try {
-    let notify = function(id) { sendResponse({value:id});};
-    id = elementManager.find(curWindow, msg.json, notify, true);
+    let on_success = function(id) { sendResponse({value:id}); };
+    let on_error = sendError;
+    elementManager.find(curWindow, msg.json, on_success, on_error, true);
   }
   catch (e) {
     sendError(e.message, e.code, e.stack);
   }
 }
 
 /**
  * Send click event to element