Bug 1398111 - [marionette] Simulate that the browser is always the top-most application. draft
authorHenrik Skupin <mail@hskupin.info>
Thu, 07 Jun 2018 08:59:42 +0200
changeset 805118 03d3e88e82e33437e2d60b48360e4911883755bd
parent 805117 d8bb6c1c43661f278e5c9c0e97ec65434827ba56
push id112566
push userbmo:hskupin@gmail.com
push dateThu, 07 Jun 2018 08:09:37 +0000
bugs1398111
milestone62.0a1
Bug 1398111 - [marionette] Simulate that the browser is always the top-most application. To allow the focusmanager testmode to raise focus events even with the Firefox window in the background, the current chrome window has to be virtually brought into foreground. This can be achieved by using `window.focus()` before executing a received WebDriver command. This has to be done for each and every command, given that the application focus can change at any time. MozReview-Commit-ID: KeKATPYjIVG
testing/marionette/driver.js
testing/marionette/server.js
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -125,17 +125,17 @@ this.GeckoDriver = function(appId, serve
   this.appId = appId;
   this._server = server;
 
   this.sessionID = null;
   this.wins = new browser.Windows();
   this.browsers = {};
   // points to current browser
   this.curBrowser = null;
-  // topmost chrome frame
+  // top-most chrome window
   this.mainFrame = null;
   // chrome iframe that currently has focus
   this.curFrame = null;
   this.currentFrameElement = null;
   this.observing = null;
   this._browserIds = new WeakMap();
 
   // Use content context by default
@@ -2829,25 +2829,19 @@ GeckoDriver.prototype.deleteSession = fu
         win.messageManager.removeDelayedFrameScript(FRAME_SCRIPT);
       } else {
         logger.error(
             `Could not remove listener from page ${win.location.href}`);
       }
     }
   }
 
-  // reset frame to the top-most frame
+  // reset frame to the top-most frame, and clear reference to chrome window
   this.curFrame = null;
-  if (this.mainFrame) {
-    try {
-      this.mainFrame.focus();
-    } catch (e) {
-      this.mainFrame = null;
-    }
-  }
+  this.mainFrame = null;
 
   if (this.observing !== null) {
     for (let topic in this.observing) {
       Services.obs.removeObserver(this.observing[topic], topic);
     }
     this.observing = null;
   }
 
--- a/testing/marionette/server.js
+++ b/testing/marionette/server.js
@@ -288,16 +288,25 @@ class TCPConnection {
     if (typeof fn == "undefined") {
       throw new UnknownCommandError(cmd.name);
     }
 
     if (!["newSession", "WebDriver:NewSession"].includes(cmd.name)) {
       assert.session(this.driver);
     }
 
+    // With the focusmanager testmode enabled the currently selected
+    // chrome window of Firefox has to virtually be brought into foreground
+    // so that focus events will be fired when interacting with UI elements.
+    // This has to be done for each and every command, given that the
+    // application focus can change at any time.
+    if (this.driver.mainFrame !== null) {
+      this.driver.mainFrame.focus();
+    }
+
     let rv = await fn.bind(this.driver)(cmd);
 
     if (rv != null) {
       if (rv instanceof WebElement || typeof rv != "object") {
         resp.body = {value: rv};
       } else {
         resp.body = rv;
       }