Bug 1298800 - Add support for callbacks to restart() and quit() methods of Marionette; r?whimboo draft
authorCuriousLearner <sanyam.khurana01@gmail.com>
Wed, 21 Sep 2016 21:53:12 +0530
changeset 416158 ece99863b1efda8a8304624b3403246b46c056cc
parent 412489 cfdb7af3af2e92e95f71ca2f1672bf5433beeb89
child 531768 6f79d3cf4e06f6a913fcacb9d69815e61a6e1c7d
push id30047
push userbmo:sanyam.khurana01@gmail.com
push dateWed, 21 Sep 2016 16:24:08 +0000
reviewerswhimboo
bugs1298800
milestone51.0a1
Bug 1298800 - Add support for callbacks to restart() and quit() methods of Marionette; r?whimboo MozReview-Commit-ID: CIiGOCkQs48
testing/marionette/client/marionette_driver/marionette.py
testing/marionette/harness/marionette/tests/unit/test_quit_restart.py
--- a/testing/marionette/client/marionette_driver/marionette.py
+++ b/testing/marionette/client/marionette_driver/marionette.py
@@ -1040,65 +1040,75 @@ class Marionette(object):
         flags = set(["eForceQuit"])
         if shutdown_flags:
             flags.add(shutdown_flags)
         self._send_message("quitApplication", {"flags": list(flags)})
 
         self.delete_session(in_app=True)
 
     @do_process_check
-    def quit(self, in_app=False):
+    def quit(self, in_app=False, callback=None):
         """Terminate the currently running instance.
 
         This command will delete the active marionette session. It also allows
         manipulation of eg. the profile data while the application is not running.
         To start the application again, start_session() has to be called.
 
         :param in_app: If True, marionette will cause a quit from within the
                        browser. Otherwise the browser will be quit immediately
                        by killing the process.
+        :param callback: If provided and `in_app` is True, the callback will
+                         be used to trigger the shutdown.
         """
         if not self.instance:
             raise errors.MarionetteException("quit() can only be called "
                                              "on Gecko instances launched by Marionette")
 
         self.reset_timeouts()
 
         if in_app:
-            self._request_in_app_shutdown()
+            if callable(callback):
+                callback()
+            else:
+                self._request_in_app_shutdown()
 
             # Give the application some time to shutdown
             self.instance.runner.wait(timeout=self.DEFAULT_SHUTDOWN_TIMEOUT)
         else:
             self.delete_session()
             self.instance.close()
 
     @do_process_check
-    def restart(self, clean=False, in_app=False):
+    def restart(self, clean=False, in_app=False, callback=None):
         """
         This will terminate the currently running instance, and spawn a new instance
         with the same profile and then reuse the session id when creating a session again.
 
         :param clean: If False the same profile will be used after the restart. Note
                       that the in app initiated restart always maintains the same
                       profile.
         :param in_app: If True, marionette will cause a restart from within the
                        browser. Otherwise the browser will be restarted immediately
                        by killing the process.
+        :param callback: If provided and `in_app` is True, the callback will be
+                         used to trigger the restart.
         """
         if not self.instance:
             raise errors.MarionetteException("restart() can only be called "
                                              "on Gecko instances launched by Marionette")
         session_id = self.session_id
 
         if in_app:
             if clean:
                 raise ValueError("An in_app restart cannot be triggered with the clean flag set")
 
-            self._request_in_app_shutdown("eRestart")
+            if callable(callback):
+                callback()
+            else:
+                self._request_in_app_shutdown("eRestart")
 
             try:
                 self.raise_for_port(self.wait_for_port())
             except socket.timeout:
                 if self.instance.runner.returncode is not None:
                     exc, val, tb = sys.exc_info()
                     self.cleanup()
                     raise exc, "Requested restart of the application was aborted", tb
--- a/testing/marionette/harness/marionette/tests/unit/test_quit_restart.py
+++ b/testing/marionette/harness/marionette/tests/unit/test_quit_restart.py
@@ -31,46 +31,73 @@ class TestQuitRestart(MarionetteTestCase
         self.assertEqual(self.marionette.session_id, self.session_id)
 
         # A forced restart will cause a new process id
         self.assertNotEqual(self.marionette.session["processId"], self.pid)
 
         # If a preference value is not forced, a restart will cause a reset
         self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
 
+    def test_force_quit(self):
+        self.marionette.quit()
+
+        self.assertEqual(self.marionette.session, None)
+        with self.assertRaisesRegexp(MarionetteException, "Please start a session"):
+            self.marionette.get_url()
+
+        self.marionette.start_session()
+        self.assertNotEqual(self.marionette.session_id, self.session_id)
+        self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
+
+    def test_in_app_clean_restart(self):
+        with self.assertRaises(ValueError):
+            self.marionette.restart(in_app=True, clean=True)
+
     def test_in_app_restart(self):
         self.marionette.restart(in_app=True)
         self.assertEqual(self.marionette.session_id, self.session_id)
 
         # An in-app restart will keep the same process id only on Linux
         if self.marionette.session_capabilities['platformName'] == 'linux':
             self.assertEqual(self.marionette.session["processId"], self.pid)
         else:
             self.assertNotEqual(self.marionette.session["processId"], self.pid)
 
         # If a preference value is not forced, a restart will cause a reset
         self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
 
-    def test_in_app_clean_restart(self):
-        with self.assertRaises(ValueError):
-            self.marionette.restart(in_app=True, clean=True)
+    def test_in_app_restart_with_callback(self):
+        def callback():
+            self.marionette._request_in_app_shutdown(shutdown_flags='eRestart')
+        self.marionette.restart(in_app=True, callback=callback)
 
-    def test_force_quit(self):
-        self.marionette.quit()
+        self.assertEqual(self.marionette.session_id, self.session_id)
 
-        self.assertEqual(self.marionette.session, None)
-        with self.assertRaisesRegexp(MarionetteException, "Please start a session"):
-            self.marionette.get_url()
+        # An in-app restart will keep the same process id only on Linux
+        if self.marionette.session_capabilities['platformName'] == 'linux':
+            self.assertEqual(self.marionette.session["processId"], self.pid)
+        else:
+            self.assertNotEqual(self.marionette.session["processId"], self.pid)
 
-        self.marionette.start_session()
-        self.assertNotEqual(self.marionette.session_id, self.session_id)
+        # If a preference value is not forced, a restart will cause a reset
         self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
 
     def test_in_app_quit(self):
         self.marionette.quit(in_app=True)
 
         self.assertEqual(self.marionette.session, None)
         with self.assertRaisesRegexp(MarionetteException, "Please start a session"):
             self.marionette.get_url()
 
         self.marionette.start_session()
         self.assertNotEqual(self.marionette.session_id, self.session_id)
         self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)
+
+    def test_in_app_quit_with_callback(self):
+        self.marionette.quit(in_app=True,
+                             callback=self.marionette._request_in_app_shutdown)
+        self.assertEqual(self.marionette.session, None)
+        with self.assertRaisesRegexp(MarionetteException, "Please start a session"):
+            self.marionette.get_url()
+
+        self.marionette.start_session()
+        self.assertNotEqual(self.marionette.session_id, self.session_id)
+        self.assertNotEqual(self.marionette.get_pref("browser.startup.page"), 3)