diff --git a/testing/marionette/components/marionette.js b/testing/marionette/components/marionette.js index d0a7a184a1b7..a5bf353b2445 100644 --- a/testing/marionette/components/marionette.js +++ b/testing/marionette/components/marionette.js @@ -195,30 +195,27 @@ MarionetteComponent.prototype.observe = function(subject, topic, data) { this.logger.debug(`Received observer notification "${topic}"`); switch (topic) { + case "profile-after-change": + Services.obs.addObserver(this, "command-line-startup"); + Services.obs.addObserver(this, "sessionstore-windows-restored"); + + prefs.readFromEnvironment(ENV_PRESERVE_PREFS); + break; + + // In safe mode the command line handlers are getting parsed after the + // safe mode dialog has been closed. To allow Marionette to start + // earlier, use the CLI startup observer notification for + // special-cased handlers, which gets fired before the dialog appears. case "command-line-startup": Services.obs.removeObserver(this, topic); this.handle(subject); - case "profile-after-change": - // Using sessionstore-windows-restored as the xpcom category doesn't - // seem to work, so we wait for that by adding an observer here. - Services.obs.addObserver(this, "sessionstore-windows-restored"); - - // In safe mode the command line handlers are getting parsed after the - // safe mode dialog has been closed. To allow Marionette to start - // earlier, register the CLI startup observer notification for - // special-cased handlers, which gets fired before the dialog appears. - Services.obs.addObserver(this, "command-line-startup"); - - prefs.readFromEnvironment(ENV_PRESERVE_PREFS); - - if (this.enabled) { - // We want to suppress the modal dialog that's shown - // when starting up in safe-mode to enable testing. - if (Services.appinfo.inSafeMode) { - Services.obs.addObserver(this, "domwindowopened"); - } + // We want to suppress the modal dialog that's shown + // when starting up in safe-mode to enable testing. + if (this.enabled && Services.appinfo.inSafeMode) { + Services.obs.addObserver(this, "domwindowopened"); } + break; case "domwindowclosed": diff --git a/testing/marionette/harness/marionette_harness/tests/unit/test_quit_restart.py b/testing/marionette/harness/marionette_harness/tests/unit/test_quit_restart.py index f9bc072f3281..f6e5e8dff1fa 100644 --- a/testing/marionette/harness/marionette_harness/tests/unit/test_quit_restart.py +++ b/testing/marionette/harness/marionette_harness/tests/unit/test_quit_restart.py @@ -2,6 +2,8 @@ # 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/. +import unittest + from marionette_driver import errors from marionette_harness import MarionetteTestCase, skip @@ -88,6 +90,14 @@ class TestQuitRestart(MarionetteTestCase): MarionetteTestCase.tearDown(self) + @property + def is_safe_mode(self): + with self.marionette.using_context("chrome"): + return self.marionette.execute_script(""" + Cu.import("resource://gre/modules/Services.jsm"); + return Services.appinfo.inSafeMode; + """) + def shutdown(self, restart=False): self.marionette.set_context("chrome") self.marionette.execute_script(""" @@ -187,6 +197,32 @@ class TestQuitRestart(MarionetteTestCase): self.assertNotEqual(self.marionette.get_pref("startup.homepage_welcome_url"), "about:") + def test_in_app_restart_safe_mode(self): + if self.marionette.session_capabilities["moz:headless"]: + raise unittest.SkipTest("Bug 1390848 - Hang of Marionette client after the restart.") + + def restart_in_safe_mode(): + with self.marionette.using_context("chrome"): + self.marionette.execute_script(""" + Components.utils.import("resource://gre/modules/Services.jsm"); + + let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"] + .createInstance(Ci.nsISupportsPRBool); + Services.obs.notifyObservers(cancelQuit, + "quit-application-requested", null); + + if (!cancelQuit.data) { + Services.startup.restartInSafeMode(Ci.nsIAppStartup.eAttemptQuit); + } + """) + + try: + self.assertFalse(self.is_safe_mode, "Safe Mode is unexpectedly enabled") + self.marionette.restart(in_app=True, callback=restart_in_safe_mode) + self.assertTrue(self.is_safe_mode, "Safe Mode is not enabled") + finally: + self.marionette.quit(clean=True) + def test_in_app_restart_with_callback_no_shutdown(self): try: timeout_startup = self.marionette.DEFAULT_STARTUP_TIMEOUT