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
--- 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;
}