Bug 1374762 - Allow Marionette to handle the safe mode dialog. draft
authorHenrik Skupin <mail@hskupin.info>
Thu, 29 Jun 2017 22:12:03 -0700
changeset 602934 9905ca4801263f730311b26d17dbcbb6bfdc5189
parent 602839 57b57379c60c6b938881f80cd58a62479358465a
child 635780 0cc71de4979a87006c446bce039d159baa51fbde
push id66621
push userbmo:hskupin@gmail.com
push dateFri, 30 Jun 2017 22:48:32 +0000
bugs1374762
milestone56.0a1
Bug 1374762 - Allow Marionette to handle the safe mode dialog. In safe mode the command line hander arguments are getting parsed after the safe mode dialog has been closed. As such Marionette is not getting enabled before, and cannot close the dialog. To workaround the problem the "command-line-startup" observer notification can be used, which allows to parse the given arguments before the dialog. MozReview-Commit-ID: LWzUKCnM0YK
testing/marionette/components/marionette.js
testing/marionette/harness/marionette_harness/tests/unit/test_cli_arguments.py
testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini
--- a/testing/marionette/components/marionette.js
+++ b/testing/marionette/components/marionette.js
@@ -150,21 +150,31 @@ MarionetteComponent.prototype = {
 MarionetteComponent.prototype.handle = function(cmdLine) {
   if (cmdLine.handleFlag("marionette", false)) {
     this.enabled = true;
   }
 };
 
 MarionetteComponent.prototype.observe = function(subject, topic, data) {
   switch (topic) {
+    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");
         }
@@ -224,16 +234,17 @@ MarionetteComponent.prototype.setupLogge
   logger.addAppender(new Log.DumpAppender());
   return logger;
 };
 
 MarionetteComponent.prototype.suppressSafeModeDialog = function(win) {
   win.addEventListener("load", () => {
     if (win.document.getElementById("safeModeDialog")) {
       // accept the dialog to start in safe-mode
+      this.logger.debug("Safe Mode detected. Going to suspress the dialog now.");
       win.setTimeout(() => {
         win.document.documentElement.getButton("accept").click();
       });
     }
   }, {once: true});
 };
 
 MarionetteComponent.prototype.init = function() {
new file mode 100644
--- /dev/null
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_cli_arguments.py
@@ -0,0 +1,36 @@
+# 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/.
+
+import copy
+
+from marionette_harness import MarionetteTestCase
+
+
+class TestCommandLineArguments(MarionetteTestCase):
+
+    def setUp(self):
+        super(TestCommandLineArguments, self).setUp()
+
+        self.orig_arguments = copy.copy(self.marionette.instance.app_args)
+
+    def tearDown(self):
+        self.marionette.instance.app_args = self.orig_arguments
+        self.marionette.quit(clean=True)
+
+        super(TestCommandLineArguments, self).tearDown()
+
+    def test_start_in_safe_mode(self):
+        self.marionette.instance.app_args.append("-safe-mode")
+
+        self.marionette.quit()
+        self.marionette.start_session()
+
+        with self.marionette.using_context("chrome"):
+            safe_mode = self.marionette.execute_script("""
+              Cu.import("resource://gre/modules/Services.jsm");
+
+              return Services.appinfo.inSafeMode;
+            """)
+
+            self.assertTrue(safe_mode, "Safe Mode has not been enabled")
--- a/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini
+++ b/testing/marionette/harness/marionette_harness/tests/unit/unit-tests.ini
@@ -1,9 +1,11 @@
 [test_marionette.py]
+[test_cli_arguments.py]
+skip-if = manage_instance == false || appname == 'fennec' # Bug 1298921 and bug 1322993
 [test_geckoinstance.py]
 [test_data_driven.py]
 [test_session.py]
 [test_capabilities.py]
 [test_accessibility.py]
 [test_expectedfail.py]
 expected = fail
 [test_click.py]