Bug 1404946 - Rename wait.until to PollPromise. r?whimboo draft
authorAndreas Tolfsen <ato@sny.no>
Mon, 02 Oct 2017 16:50:11 +0100
changeset 676760 4d2d091759054721e6276942bd1dc0bffb923f19
parent 676757 119153f4d16f4bb1331b53bcadfe749c5dab607d
child 676761 ebad552e29c7e1aa27ef3b52201761380dd0fe04
push id83632
push userbmo:ato@sny.no
push dateMon, 09 Oct 2017 17:09:49 +0000
reviewerswhimboo
bugs1404946
milestone58.0a1
Bug 1404946 - Rename wait.until to PollPromise. r?whimboo In formalising our synchronisation module, this renames wait.until to PollPromise. It is a specialisation of a promise, just like TimedPromise, that poll-waits a condition for a given amount of time before either resolving (passing) or rejecting (failing) the poll-wait. Also fix and improve documentation. MozReview-Commit-ID: AcP3C1qCgKA
testing/marionette/driver.js
testing/marionette/element.js
testing/marionette/sync.js
testing/marionette/test_sync.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -42,17 +42,20 @@ Cu.import("chrome://marionette/content/e
 Cu.import("chrome://marionette/content/event.js");
 Cu.import("chrome://marionette/content/interaction.js");
 Cu.import("chrome://marionette/content/l10n.js");
 Cu.import("chrome://marionette/content/legacyaction.js");
 Cu.import("chrome://marionette/content/modal.js");
 Cu.import("chrome://marionette/content/proxy.js");
 Cu.import("chrome://marionette/content/reftest.js");
 Cu.import("chrome://marionette/content/session.js");
-const {wait, TimedPromise} = Cu.import("chrome://marionette/content/sync.js", {});
+const {
+  PollPromise,
+  TimedPromise,
+} = Cu.import("chrome://marionette/content/sync.js", {});
 
 Cu.importGlobalProperties(["URL"]);
 
 this.EXPORTED_SYMBOLS = ["GeckoDriver", "Context"];
 
 const FRAME_SCRIPT = "chrome://marionette/content/listener.js";
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
@@ -1483,30 +1486,30 @@ GeckoDriver.prototype.setWindowRect = as
       win.resizeTo(width, height);
     });
   }
 
   // Wait until window size has changed.  We can't wait for the
   // user-requested window size as this may not be achievable on the
   // current system.
   const windowResizeChange = async () => {
-    return wait.until((resolve, reject) => {
+    return new PollPromise((resolve, reject) => {
       let curRect = this.curBrowser.rect;
       if (curRect.width != origRect.width &&
           curRect.height != origRect.height) {
         resolve();
       } else {
         reject();
       }
     });
   };
 
   // Wait for the window position to change.
   async function windowPosition(x, y) {
-    return wait.until((resolve, reject) => {
+    return new PollPromise((resolve, reject) => {
       if ((x == win.screenX && y == win.screenY) ||
           (win.screenX != origRect.x || win.screenY != origRect.y)) {
         resolve();
       } else {
         reject();
       }
     });
   }
@@ -3044,17 +3047,17 @@ GeckoDriver.prototype.maximizeWindow = a
 
   const origSize = {
     outerWidth: win.outerWidth,
     outerHeight: win.outerHeight,
   };
 
   // Wait for the window size to change.
   async function windowSizeChange() {
-    return wait.until((resolve, reject) => {
+    return new PollPromise((resolve, reject) => {
       let curSize = {
         outerWidth: win.outerWidth,
         outerHeight: win.outerHeight,
       };
       if (curSize.outerWidth != origSize.outerWidth ||
           curSize.outerHeight != origSize.outerHeight) {
         resolve();
       } else {
--- a/testing/marionette/element.js
+++ b/testing/marionette/element.js
@@ -10,17 +10,17 @@ const {classes: Cc, interfaces: Ci, util
 Cu.import("chrome://marionette/content/assert.js");
 Cu.import("chrome://marionette/content/atom.js");
 const {
   InvalidSelectorError,
   NoSuchElementError,
   pprint,
   StaleElementReferenceError,
 } = Cu.import("chrome://marionette/content/error.js", {});
-const {wait} = Cu.import("chrome://marionette/content/sync.js", {});
+const {PollPromise} = Cu.import("chrome://marionette/content/sync.js", {});
 
 this.EXPORTED_SYMBOLS = ["element"];
 
 const XMLNS = "http://www.w3.org/1999/xhtml";
 const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
 
 const uuidGen = Cc["@mozilla.org/uuid-generator;1"]
     .getService(Ci.nsIUUIDGenerator);
@@ -244,17 +244,17 @@ element.find = function(container, strat
   let searchFn;
   if (opts.all) {
     searchFn = findElements.bind(this);
   } else {
     searchFn = findElement.bind(this);
   }
 
   return new Promise((resolve, reject) => {
-    let findElements = wait.until((resolve, reject) => {
+    let findElements = new PollPromise((resolve, reject) => {
       let res = find_(container, strategy, selector, searchFn, opts);
       if (res.length > 0) {
         resolve(Array.from(res));
       } else {
         reject([]);
       }
     }, opts.timeout);
 
--- a/testing/marionette/sync.js
+++ b/testing/marionette/sync.js
@@ -6,25 +6,18 @@
 
 const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
 
 const {
   error,
   TimeoutError,
 } = Cu.import("chrome://marionette/content/error.js", {});
 
-/* exported TimedPromise */
-this.EXPORTED_SYMBOLS = ["wait", "TimedPromise"];
-
-/**
- * Poll-waiting utilities.
- *
- * @namespace
- */
-this.wait = {};
+/* exported PollPromise, TimedPromise */
+this.EXPORTED_SYMBOLS = ["PollPromise", "TimedPromise"];
 
 const {TYPE_ONE_SHOT, TYPE_REPEATING_SLACK} = Ci.nsITimer;
 
 /**
  * @callback Condition
  *
  * @param {function(*)} resolve
  *     To be called when the condition has been met.  Will return the
@@ -34,63 +27,67 @@ const {TYPE_ONE_SHOT, TYPE_REPEATING_SLA
  *     the condition to be revaluated or time out.
  *
  * @return {*}
  *     The value from calling <code>resolve</code>.
  */
 
 /**
  * Runs a promise-like function off the main thread until it is resolved
- * through |resolve| or |rejected| callbacks.  The function is guaranteed
- * to be run at least once, irregardless of the timeout.
+ * through <code>resolve</code> or <code>rejected</code> callbacks.
+ * The function is guaranteed to be run at least once, irregardless of
+ * the timeout.
  *
- * The |func| is evaluated every |interval| for as long as its runtime
- * duration does not exceed |interval|.  Evaluations occur sequentially,
- * meaning that evaluations of |func| are queued if the runtime evaluation
- * duration of |func| is greater than |interval|.
+ * The <var>func</var> is evaluated every <var>interval</var> for as
+ * long as its runtime duration does not exceed <var>interval</var>.
+ * Evaluations occur sequentially, meaning that evaluations of
+ * <var>func</var> are queued if the runtime evaluation duration of
+ * <var>func</var> is greater than <var>interval</var>.
  *
- * |func| is given two arguments, |resolve| and |reject|, of which one
- * must be called for the evaluation to complete.  Calling |resolve| with
- * an argument indicates that the expected wait condition was met and
- * will return the passed value to the caller.  Conversely, calling
- * |reject| will evaluate |func| again until the |timeout| duration has
- * elapsed or |func| throws.  The passed value to |reject| will also be
+ * <var>func</var> is given two arguments, <code>resolve</code> and
+ * <code>reject</code>, of which one must be called for the evaluation
+ * to complete.  Calling <code>resolve</code> with an argument
+ * indicates that the expected wait condition was met and will return
+ * the passed value to the caller.  Conversely, calling
+ * <code>reject</code> will evaluate <var>func</var> again until
+ * the <var>timeout</var> duration has elapsed or <var>func</var>
+ * throws.  The passed value to <code>reject</code> will also be
  * returned to the caller once the wait has expired.
  *
  * Usage:
  *
  * <pre><code>
- *     let els = wait.until((resolve, reject) => {
+ *     let els = new PollPromise((resolve, reject) => {
  *       let res = document.querySelectorAll("p");
  *       if (res.length > 0) {
  *         resolve(Array.from(res));
  *       } else {
  *         reject([]);
  *       }
  *     });
  * </pre></code>
  *
  * @param {Condition} func
  *     Function to run off the main thread.
- * @param {number=} timeout
- *     Desired timeout.  If 0 or less than the runtime evaluation time
- *     of |func|, |func| is guaranteed to run at least once.  The default
- *     is 2000 milliseconds.
- * @param {number=} interval
- *     Duration between each poll of |func| in milliseconds.  Defaults to
- *     10 milliseconds.
+ * @param {number=} [timeout=2000] timeout
+ *     Desired timeout.  If 0 or less than the runtime evaluation
+ *     time of <var>func</var>, <var>func</var> is guaranteed to run
+ *     at least once.  The default is 2000 milliseconds.
+ * @param {number=} [interval=10] interval
+ *     Duration between each poll of <var>func</var> in milliseconds.
+ *     Defaults to 10 milliseconds.
  *
  * @return {Promise.<*>}
- *     Yields the value passed to |func|'s |resolve| or |reject|
- *     callbacks.
+ *     Yields the value passed to <var>func</var>'s
+ *     <code>resolve</code> or <code>reject</code> callbacks.
  *
  * @throws {*}
- *     If |func| throws, its error is propagated.
+ *     If <var>func</var> throws, its error is propagated.
  */
-wait.until = function(func, timeout = 2000, interval = 10) {
+function PollPromise(func, timeout = 2000, interval = 10) {
   const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 
   return new Promise((resolve, reject) => {
     const start = new Date().getTime();
     const end = start + timeout;
 
     let evalFn = () => {
       new Promise(func).then(resolve, rejected => {
@@ -114,17 +111,17 @@ wait.until = function(func, timeout = 20
 
   }).then(res => {
     timer.cancel();
     return res;
   }, err => {
     timer.cancel();
     throw err;
   });
-};
+}
 
 /**
  * The <code>TimedPromise</code> object represents the timed, eventual
  * completion (or failure) of an asynchronous operation, and its
  * resulting value.
  *
  * In contrast to a regular {@link Promise}, it times out after
  * <var>timeout</var>.
--- a/testing/marionette/test_sync.js
+++ b/testing/marionette/test_sync.js
@@ -1,76 +1,76 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const {utils: Cu} = Components;
 
-Cu.import("chrome://marionette/content/sync.js");
+const {PollPromise} = Cu.import("chrome://marionette/content/sync.js", {});
 
 const DEFAULT_TIMEOUT = 2000;
 
-add_task(async function test_until_types() {
+add_task(async function test_PollPromise_types() {
   for (let typ of [true, false, "foo", 42, [], {}]) {
-    strictEqual(typ, await wait.until(resolve => resolve(typ)));
+    strictEqual(typ, await new PollPromise(resolve => resolve(typ)));
   }
 });
 
-add_task(async function test_until_timeoutElapse() {
+add_task(async function test_PollPromise_timeoutElapse() {
   let nevals = 0;
   let start = new Date().getTime();
-  await wait.until((resolve, reject) => {
+  await new PollPromise((resolve, reject) => {
     ++nevals;
     reject();
   });
   let end = new Date().getTime();
   greaterOrEqual((end - start), DEFAULT_TIMEOUT);
   greaterOrEqual(nevals, 15);
 });
 
-add_task(async function test_until_rethrowError() {
+add_task(async function test_PollPromise_rethrowError() {
   let nevals = 0;
   let err;
   try {
-    await wait.until(() => {
+    await PollPromise(() => {
       ++nevals;
       throw new Error();
     });
   } catch (e) {
     err = e;
   }
   equal(1, nevals);
   ok(err instanceof Error);
 });
 
-add_task(async function test_until_noTimeout() {
+add_task(async function test_PollPromise_noTimeout() {
   // run at least once when timeout is 0
   let nevals = 0;
   let start = new Date().getTime();
-  await wait.until((resolve, reject) => {
+  await new PollPromise((resolve, reject) => {
     ++nevals;
     reject();
   }, 0);
   let end = new Date().getTime();
   equal(1, nevals);
   less((end - start), DEFAULT_TIMEOUT);
 });
 
-add_task(async function test_until_timeout() {
+add_task(async function test_PollPromise_timeout() {
   let nevals = 0;
   let start = new Date().getTime();
-  await wait.until((resolve, reject) => {
+  await new PollPromise((resolve, reject) => {
     ++nevals;
     reject();
   }, 100);
   let end = new Date().getTime();
   greater(nevals, 1);
   greaterOrEqual((end - start), 100);
 });
 
-add_task(async function test_until_interval() {
+add_task(async function test_PollPromise_interval() {
   let nevals = 0;
-  await wait.until((resolve, reject) => {
+  await new PollPromise((resolve, reject) => {
     ++nevals;
     reject();
   }, 100, 100);
   equal(2, nevals);
 });