Bug 1257153 - Cancel implicit wait timers on rejection; r?automatedtester draft
authorAndreas Tolfsen <ato@mozilla.com>
Wed, 16 Mar 2016 12:27:36 +0000
changeset 341071 a6626ea0f527e70e5dddc9f2ef2a0b9e075d5a06
parent 340999 341344bdec8f10bf50646cd6ef2355361435cbf6
child 516322 2f4c2d3aa34fe630838b82d76a95f3099a18fe37
push id13128
push userbmo:ato@mozilla.com
push dateWed, 16 Mar 2016 12:35:15 +0000
reviewersautomatedtester
bugs1257153
milestone48.0a1
Bug 1257153 - Cancel implicit wait timers on rejection; r?automatedtester This fixes a leak where timers were not cancelled upon promise rejection. When the function passed to implicitlyWaitFor is rejected for not finding elements after the timeout has elapsed, the elementSearch callback is no longer called because the timer is cancelled when it calls reject(). MozReview-Commit-ID: FR2iA8s1NjX
testing/marionette/element.js
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -667,17 +667,17 @@ ElementManager.prototype = {
  */
 function implicitlyWaitFor(func, timeout, interval = 100) {
   let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 
   return new Promise((resolve, reject) => {
     let startTime = new Date().getTime();
     let endTime = startTime + timeout;
 
-    let onTimer = function() {
+    let elementSearch = function() {
       let res;
       try {
         res = func();
       } catch (e) {
         reject(e);
       }
 
       // empty arrays evaluate to true in JS,
@@ -687,26 +687,29 @@ function implicitlyWaitFor(func, timeout
       // allowing |func| to be evaluated at least once
       let col = element.isElementCollection(res);
       if (((col && res.length > 0 ) || (!col && !!res)) ||
           (startTime == endTime || new Date().getTime() >= endTime)) {
         resolve(res);
       }
     };
 
-    // Run a check immediately so we do not cause a delay in execution
-    // due to the set timer interval.
-    onTimer();
+    // the repeating slack timer waits |interval|
+    // before invoking |elementSearch|
+    elementSearch();
 
-    timer.init(onTimer, interval, Ci.nsITimer.TYPE_REPEATING_SLACK);
+    timer.init(elementSearch, interval, Ci.nsITimer.TYPE_REPEATING_SLACK);
 
-  // cancel timer and return result for yielding
+  // cancel timer and propagate result
   }).then(res => {
     timer.cancel();
     return res;
+  }, err => {
+    timer.cancel();
+    throw err;
   });
 }
 
 element.isElementCollection = function(seq) {
   if (seq === null) {
     return false;
   }