Bug 1410652 - Let WebDriver:SwitchToFrame take a web element. r=whimboo draft
authorAndreas Tolfsen <ato@sny.no>
Sat, 21 Oct 2017 19:30:27 +0100
changeset 689636 e7a842bb69847b936fe449fc8985ceb60e533f17
parent 689635 6475a04bb7709072849547ffc27bd604ec678b07
child 738356 c8542e5c4882f191fe6c08550f30e0f6795fbc4f
push id87065
push userbmo:ato@sny.no
push dateTue, 31 Oct 2017 20:11:32 +0000
reviewerswhimboo
bugs1410652
milestone58.0a1
Bug 1410652 - Let WebDriver:SwitchToFrame take a web element. r=whimboo The "element" field on the WebDriver:SwitchToFrame command request's body takes a string web element reference UUID as input. This patch changes it so that it can also take a web element JSON Object. The old behaviour can be removed with Firefox 60. MozReview-Commit-ID: JcTD3MRxjOe
testing/marionette/driver.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -1725,17 +1725,26 @@ GeckoDriver.prototype.switchToParentFram
  *     Top-level browsing context has been discarded.
  * @throws {UnexpectedAlertOpenError}
  *     A modal dialog is open, blocking this operation.
  */
 GeckoDriver.prototype.switchToFrame = async function(cmd) {
   assert.window(this.getCurrentWindow());
   assert.noUserPrompt(this.dialog);
 
-  let {id, element, focus} = cmd.parameters;
+  let {id, focus} = cmd.parameters;
+
+  // TODO(ato): element can be either string (deprecated) or a web
+  // element JSON Object.  Can be removed with Firefox 60.
+  let byFrame;
+  if (typeof cmd.parameters.element == "string") {
+    byFrame = WebElement.fromUUID(cmd.parameters.element, Context.Chrome);
+  } else if (cmd.parameters.element) {
+    byFrame = WebElement.fromJSON(cmd.parameters.element);
+  }
 
   const otherErrorsExpr = /about:.+(error)|(blocked)\?/;
   const checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
 
   let curWindow = this.getCurrentWindow();
 
   let checkLoad = function() {
     let win = this.getCurrentWindow();
@@ -1753,30 +1762,29 @@ GeckoDriver.prototype.switchToFrame = as
     checkTimer.initWithCallback(
         checkLoad.bind(this), 100, Ci.nsITimer.TYPE_ONE_SHOT);
   };
 
   if (this.context == Context.Chrome) {
     let foundFrame = null;
 
     // just focus
-    if (typeof id == "undefined" && typeof element == "undefined") {
+    if (typeof id == "undefined" && !byFrame) {
       this.curFrame = null;
       if (focus) {
         this.mainFrame.focus();
       }
       checkTimer.initWithCallback(
           checkLoad.bind(this), 100, Ci.nsITimer.TYPE_ONE_SHOT);
       return;
     }
 
     // by element (HTMLIFrameElement)
-    if (typeof element != "undefined") {
-      let webEl = WebElement.fromUUID(element, Context.Chrome);
-      let wantedFrame = this.curBrowser.seenEls.get(webEl);
+    if (byFrame) {
+      let wantedFrame = this.curBrowser.seenEls.get(byFrame);
 
       // Deal with an embedded xul:browser case
       if (wantedFrame.tagName == "xul:browser" ||
           wantedFrame.tagName == "browser") {
         curWindow = wantedFrame.contentWindow;
         this.curFrame = curWindow;
         if (focus) {
           this.curFrame.focus();
@@ -1869,17 +1877,17 @@ GeckoDriver.prototype.switchToFrame = as
       }
       checkTimer.initWithCallback(
           checkLoad.bind(this), 100, Ci.nsITimer.TYPE_ONE_SHOT);
     } else {
       throw new NoSuchFrameError(`Unable to locate frame: ${id}`);
     }
 
   } else if (this.context == Context.Content) {
-    if (!id && !element &&
+    if (!id && !byFrame &&
         this.curBrowser.frameManager.currentRemoteFrame !== null) {
       // We're currently using a ChromeMessageSender for a remote frame,
       // so this request indicates we need to switch back to the top-level
       // (parent) frame.  We'll first switch to the parent's (global)
       // ChromeMessageBroadcaster, so we send the message to the right
       // listener.
       this.switchToGlobalMessageManager();
     }