Bug 1298800 - Add support for callbacks to restart() and quit() methods of Marionette; r?whimboo
MozReview-Commit-ID: CIiGOCkQs48
--- 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)