Bug 1770461 - [bidi] Add support for awaitPromise to script.evaluate r=webdriver-reviewers,whimboo,jgraham
authorJulian Descottes <jdescottes@mozilla.com>
Sun, 03 Jul 2022 20:24:03 +0000
changeset 622864 da29b7f8b024401c25fc0a03e1da7631d2bab4ab
parent 622861 5f662264782ddbf021c5f15099c4fd8c9ce3b33b
child 622865 5ba34c75f73fc823b10265b03419747005eb37f9
push id39933
push userbszekely@mozilla.com
push dateMon, 04 Jul 2022 09:20:38 +0000
treeherdermozilla-central@f7c192231f50 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerswebdriver-reviewers, whimboo, jgraham
bugs1770461
milestone104.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 1770461 - [bidi] Add support for awaitPromise to script.evaluate r=webdriver-reviewers,whimboo,jgraham Differential Revision: https://phabricator.services.mozilla.com/D149412
remote/webdriver-bidi/modules/root/script.jsm
remote/webdriver-bidi/modules/windowglobal/script.jsm
testing/web-platform/meta/webdriver/tests/bidi/script/evaluate/evaluate.py.ini
--- a/remote/webdriver-bidi/modules/root/script.jsm
+++ b/remote/webdriver-bidi/modules/root/script.jsm
@@ -121,17 +121,17 @@ class ScriptModule extends Module {
    * @property {RemoteValue} result
    */
 
   /**
    * Evaluate a provided expression in the provided target, which is either a
    * realm or a browsing context.
    *
    * @param {Object=} options
-   * @param {boolean=} awaitPromise [unsupported]
+   * @param {boolean=} awaitPromise
    *     Determines if the command should wait for the return value of the
    *     expression to resolve, if this return value is a Promise. Defaults to
    *     true.
    * @param {string} expression
    *     The expression to evaluate.
    * @param {OwnershipModel=} resultOwnership [unsupported]
    *     The ownership model to use for the results of this evaluation.
    * @param {Object} target
@@ -212,16 +212,17 @@ class ScriptModule extends Module {
     const { result } = await this.messageHandler.forwardCommand({
       moduleName: "script",
       commandName: "evaluateExpression",
       destination: {
         type: lazy.WindowGlobalMessageHandler.type,
         id: realm.context.id,
       },
       params: {
+        awaitPromise,
         expression: source,
       },
     });
 
     return {
       result,
       realm: realm.realm,
     };
--- a/remote/webdriver-bidi/modules/windowglobal/script.jsm
+++ b/remote/webdriver-bidi/modules/windowglobal/script.jsm
@@ -59,30 +59,54 @@ class ScriptModule extends Module {
     // which can be used as is.
     return maybeDebuggerObject;
   }
 
   /**
    * Evaluate a provided expression in the current window global.
    *
    * @param {Object} options
+   * @param {boolean} awaitPromise
+   *     Determines if the command should wait for the return value of the
+   *     expression to resolve, if this return value is a Promise.
    * @param {string} expression
    *     The expression to evaluate.
    *
    * @return {Object}
    *     - result {RemoteValue} the result of the evaluation serialized as a
    *     RemoteValue.
    */
-  evaluateExpression(options) {
-    const { expression } = options;
+  async evaluateExpression(options) {
+    const { awaitPromise, expression } = options;
     const rv = this.#global.executeInGlobal(expression);
 
     if ("return" in rv) {
+      let result = rv.return;
+      if (
+        awaitPromise &&
+        // Only non-primitive return values are wrapped in Debugger.Object.
+        result instanceof Debugger.Object &&
+        result.isPromise
+      ) {
+        try {
+          // Force wrapping the promise resolution result in a Debugger.Object
+          // wrapper for consistency with the synchronous codepath.
+          result = this.#global.makeDebuggeeValue(
+            await result.unsafeDereference()
+          );
+        } catch (e) {
+          // Errors will be handled in Bug 1770477.
+          throw new lazy.error.UnsupportedOperationError(
+            `Unsupported promise rejection for expression evaluation`
+          );
+        }
+      }
+
       return {
-        result: lazy.serialize(this.#toRawObject(rv.return), 1),
+        result: lazy.serialize(this.#toRawObject(result), 1),
       };
     }
 
     throw new lazy.error.UnsupportedOperationError(
       `Unsupported completion value for expression evaluation`
     );
   }
 }
--- a/testing/web-platform/meta/webdriver/tests/bidi/script/evaluate/evaluate.py.ini
+++ b/testing/web-platform/meta/webdriver/tests/bidi/script/evaluate/evaluate.py.ini
@@ -3,22 +3,16 @@
     expected: FAIL
 
   [test_exception]
     expected: FAIL
 
   [test_resolved_promise_with_await_promise_false]
     expected: FAIL
 
-  [test_resolved_promise_with_await_promise_true]
-    expected: FAIL
-
-  [test_resolved_promise_with_await_promise_omitted]
-    expected: FAIL
-
   [test_rejected_promise_with_await_promise_false]
     expected: FAIL
 
   [test_rejected_promise_with_await_promise_true]
     expected: FAIL
 
   [test_rejected_promise_with_await_promise_omitted]
     expected: FAIL