Bug 1257153 - Cancel implicit wait timers on rejection; r=automatedtester
authorAndreas Tolfsen <ato@mozilla.com>
Wed, 16 Mar 2016 12:27:36 +0000
changeset 289230 1fdf06c430110676ac5feaf35a0462239b805cff
parent 289229 cd6d52ddb5751e51c6272b9846144156f8844803
child 289231 ed56694589bed39601f0c5c09a1e676bc023db56
push id30099
push usercbook@mozilla.com
push dateFri, 18 Mar 2016 14:52:23 +0000
treeherdermozilla-central@9c5d494d0548 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersautomatedtester
bugs1257153
milestone48.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 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;
   }