Bug 1378121 - Add Minimize Window command to marionette; r=ato
MozReview-Commit-ID: F5Z38LxhOJm
--- a/testing/marionette/client/marionette_driver/marionette.py
+++ b/testing/marionette/client/marionette_driver/marionette.py
@@ -2037,16 +2037,22 @@ class Marionette(object):
:param height: The height to resize the window to.
"""
warnings.warn("set_window_size() has been deprecated, please use set_window_rect()",
DeprecationWarning)
body = {"width": width, "height": height}
return self._send_message("setWindowSize", body)
+ def minimize_window(self):
+ """ Resize the browser window currently receiving commands. The action
+ should be equivalent to the user pressing the minimize button
+ """
+ return self._send_message("WebDriver:MinimizeWindow")
+
def maximize_window(self):
""" Resize the browser window currently receiving commands. The action
should be equivalent to the user pressing the maximize button
"""
return self._send_message("maximizeWindow")
def fullscreen(self):
""" Synchronously sets the user agent window to full screen as if the user
--- a/testing/marionette/driver.js
+++ b/testing/marionette/driver.js
@@ -2863,16 +2863,59 @@ GeckoDriver.prototype.setScreenOrientati
}
if (!win.screen.mozLockOrientation(mozOr)) {
throw new WebDriverError(`Unable to set screen orientation: ${or}`);
}
};
/**
+ * Synchronously minimizes the user agent window as if the user pressed
+ * the minimize button, or restores it if it is already minimized.
+ *
+ * Not supported on Fennec.
+ *
+ * @return {Map.<string, number>}
+ * Window rect & windowState.
+ *
+ * @throws {UnsupportedOperationError}
+ * Not available for current application.
+ * @throws {NoSuchWindowError}
+ * Top-level browsing context has been discarded.
+ * @throws {UnexpectedAlertOpenError}
+ * A modal dialog is open, blocking this operation.
+ */
+GeckoDriver.prototype.minimizeWindow = function* (cmd, resp) {
+ assert.firefox();
+ const win = assert.window(this.getCurrentWindow());
+ assert.noUserPrompt(this.dialog);
+
+ let state;
+ yield new Promise(resolve => {
+ win.addEventListener("sizemodechange", resolve, {once: true});
+
+ if (win.windowState == win.STATE_MINIMIZED) {
+ win.restore();
+ state = "normal";
+ } else {
+ win.minimize();
+ state = "minimized";
+ }
+ });
+
+ resp.body = {
+ x: win.screenX,
+ y: win.screenY,
+ width: win.outerWidth,
+ height: win.outerHeight,
+ state,
+ };
+};
+
+/**
* Synchronously maximizes the user agent window as if the user pressed
* the maximize button, or restores it if it is already maximized.
*
* Not supported on Fennec.
*
* @return {Map.<string, number>}
* Window rect.
*
@@ -3398,16 +3441,17 @@ GeckoDriver.prototype.commands = {
"WebDriver:GetTitle": GeckoDriver.prototype.getTitle,
"WebDriver:GetWindowHandle": GeckoDriver.prototype.getWindowHandle,
"WebDriver:GetWindowHandles": GeckoDriver.prototype.getWindowHandles,
"WebDriver:GetWindowRect": GeckoDriver.prototype.getWindowRect,
"WebDriver:GetWindowType": GeckoDriver.prototype.getWindowType,
"WebDriver:IsElementDisplayed": GeckoDriver.prototype.isElementDisplayed,
"WebDriver:IsElementEnabled": GeckoDriver.prototype.isElementEnabled,
"WebDriver:IsElementSelected": GeckoDriver.prototype.isElementSelected,
+ "WebDriver:MinimizeWindow": GeckoDriver.prototype.minimizeWindow,
"WebDriver:MaximizeWindow": GeckoDriver.prototype.maximizeWindow,
"WebDriver:Navigate": GeckoDriver.prototype.get,
"WebDriver:NewSession": GeckoDriver.prototype.newSession,
"WebDriver:PerformActions": GeckoDriver.prototype.performActions,
"WebDriver:Refresh": GeckoDriver.prototype.refresh,
"WebDriver:ReleaseActions": GeckoDriver.prototype.releaseActions,
"WebDriver:SendAlertText": GeckoDriver.prototype.sendKeysToDialog,
"WebDriver:SetScreenOrientation": GeckoDriver.prototype.setScreenOrientation,
new file mode 100644
--- /dev/null
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_window_minimize.py
@@ -0,0 +1,40 @@
+# 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/.
+
+from marionette_driver.errors import InvalidArgumentException
+
+from marionette_harness import MarionetteTestCase
+
+class TestWindowMinimize(MarionetteTestCase):
+
+ def setUp(self):
+ MarionetteTestCase.setUp(self)
+
+ self.original_size = self.marionette.window_size
+
+ def assert_window_minimized(self, resp):
+ self.assertEqual("minimized", resp["state"])
+
+ def assert_window_restored(self, actual):
+ self.assertEqual("normal", actual["state"])
+ self.assertEqual(self.original_size["width"], actual["width"])
+ self.assertEqual(self.original_size["height"], actual["height"])
+
+ def test_minimize_twice_restores(self):
+ resp = self.marionette.minimize_window()
+ self.assert_window_minimized(resp)
+
+ # restore the window
+ resp = self.marionette.minimize_window()
+ self.assert_window_restored(resp)
+
+ def test_minimize_stress(self):
+ for i in range(1, 25):
+ expect_minimized = bool(i % 2)
+
+ resp = self.marionette.minimize_window()
+ if expect_minimized:
+ self.assert_window_minimized(resp)
+ else:
+ self.assert_window_restored(resp)
--- a/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini
+++ b/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini
@@ -65,16 +65,18 @@ skip-if = appname == 'fennec'
[test_window_handles_content.py]
[test_window_close_chrome.py]
skip-if = appname == 'fennec'
[test_window_close_content.py]
[test_window_rect.py]
skip-if = appname == 'fennec'
[test_window_maximize.py]
skip-if = appname == 'fennec'
+[test_window_minimize.py]
+skip-if = appname == 'fennec'
[test_window_status_content.py]
[test_window_status_chrome.py]
[test_screenshot.py]
skip-if = headless # Relies on native styling which headless doesn't support.
[test_cookies.py]
[test_title.py]
[test_title_chrome.py]