Bug 1141335 - [marionette] Use in_app by default for quit() and restart(). r=webdriver-reviewers,jdescottes,perftest-reviewers,AlexandruIonescu

Hereby the "in_app" argument is required to be specified in case some
other argument eg. "clean" requires a termination of the application.

Differential Revision: https://phabricator.services.mozilla.com/D157219
This commit is contained in:
Henrik Skupin 2022-10-04 09:04:25 +00:00
Родитель 02611dde78
Коммит e75a84eaa1
27 изменённых файлов: 194 добавлений и 158 удалений

Просмотреть файл

@ -575,7 +575,7 @@ class TestFirefoxRefresh(MarionetteTestCase):
# Force yet another restart with a clean profile to disconnect from the # Force yet another restart with a clean profile to disconnect from the
# profile and environment changes we've made, to leave a more or less # profile and environment changes we've made, to leave a more or less
# blank slate for the next person. # blank slate for the next person.
self.marionette.restart(clean=True, in_app=False) self.marionette.restart(in_app=False, clean=True)
self.setUpScriptData() self.setUpScriptData()
# Super # Super

Просмотреть файл

@ -89,7 +89,7 @@ class SessionStoreTestCase(WindowManagerMixin, MarionetteTestCase):
def tearDown(self): def tearDown(self):
try: try:
# Create a fresh profile for subsequent tests. # Create a fresh profile for subsequent tests.
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
finally: finally:
super(SessionStoreTestCase, self).tearDown() super(SessionStoreTestCase, self).tearDown()
@ -213,7 +213,7 @@ class SessionStoreTestCase(WindowManagerMixin, MarionetteTestCase):
def close_all_tabs_and_restart(self): def close_all_tabs_and_restart(self):
self.close_all_tabs() self.close_all_tabs()
self.marionette.quit(in_app=True, callback=self._close_tab_shortcut) self.marionette.quit(callback=self._close_tab_shortcut)
self.marionette.start_session() self.marionette.start_session()
def simulate_os_shutdown(self): def simulate_os_shutdown(self):
@ -399,7 +399,7 @@ class SessionStoreTestCase(WindowManagerMixin, MarionetteTestCase):
), ),
) )
self.marionette.quit(in_app=True, callback=lambda: self.simulate_os_shutdown()) self.marionette.quit(callback=lambda: self.simulate_os_shutdown())
saved_args = self.marionette.instance.app_args saved_args = self.marionette.instance.app_args
try: try:

Просмотреть файл

@ -34,7 +34,7 @@ class TestSessionStoreEnabledAllWindows(SessionStoreTestCase):
self.all_windows, "Not all requested windows have been opened" self.all_windows, "Not all requested windows have been opened"
) )
self.marionette.quit(in_app=True) self.marionette.quit()
self.marionette.start_session() self.marionette.start_session()
self.wait_for_windows( self.wait_for_windows(

Просмотреть файл

@ -34,7 +34,7 @@ class TestSessionStoreEnabledAllWindows(SessionStoreTestCase):
self.all_windows, "Not all requested windows have been opened" self.all_windows, "Not all requested windows have been opened"
) )
self.marionette.quit(in_app=True) self.marionette.quit()
self.marionette.start_session() self.marionette.start_session()
self.marionette.set_context("chrome") self.marionette.set_context("chrome")
@ -56,7 +56,7 @@ class TestSessionStoreDisabled(SessionStoreTestCase):
self.all_windows, "Not all requested windows have been opened" self.all_windows, "Not all requested windows have been opened"
) )
self.marionette.quit(in_app=True) self.marionette.quit()
self.marionette.start_session() self.marionette.start_session()
self.marionette.set_context("chrome") self.marionette.set_context("chrome")

Просмотреть файл

@ -30,10 +30,10 @@ class CachesDeleteCleanupAtShutdownTestCase(MarionetteTestCase):
def setUp(self): def setUp(self):
super(CachesDeleteCleanupAtShutdownTestCase, self).setUp() super(CachesDeleteCleanupAtShutdownTestCase, self).setUp()
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
def tearDown(self): def tearDown(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(CachesDeleteCleanupAtShutdownTestCase, self).tearDown() super(CachesDeleteCleanupAtShutdownTestCase, self).tearDown()
def getUsage(self): def getUsage(self):

Просмотреть файл

@ -14,7 +14,7 @@ class ServiceWorkerAtStartupTestCase(MarionetteTestCase):
self.install_service_worker() self.install_service_worker()
def tearDown(self): def tearDown(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(ServiceWorkerAtStartupTestCase, self).tearDown() super(ServiceWorkerAtStartupTestCase, self).tearDown()
def install_service_worker(self): def install_service_worker(self):
@ -37,11 +37,11 @@ class ServiceWorkerAtStartupTestCase(MarionetteTestCase):
) )
# Quit and start a new session to simulate a full browser restart # Quit and start a new session to simulate a full browser restart
# (`self.marionette.restart(clean=False, in_app=True)` seems to not # (`self.marionette.restart()` seems to not
# be enough to simulate this scenario, because the service workers # be enough to simulate this scenario, because the service workers
# are staying registered and they are not actually re-registered # are staying registered and they are not actually re-registered
# from the list stored in the profile as this test needs). # from the list stored in the profile as this test needs).
self.marionette.quit(clean=False, in_app=True) self.marionette.quit()
self.marionette.start_session() self.marionette.start_session()
Wait(self.marionette).until( Wait(self.marionette).until(

Просмотреть файл

@ -12,7 +12,7 @@ from marionette_harness import MarionetteTestCase
class TestAutoConfig(MarionetteTestCase): class TestAutoConfig(MarionetteTestCase):
def tearDown(self): def tearDown(self):
self.marionette.quit(clean=True) self.marionette.quit(in_app=False, clean=True)
if hasattr(self, "pref_file"): if hasattr(self, "pref_file"):
os.remove(self.pref_file) os.remove(self.pref_file)

Просмотреть файл

@ -2754,7 +2754,8 @@ GeckoDriver.prototype.acceptConnections = function(cmd) {
* Dictionary containing information that explains the shutdown reason. * Dictionary containing information that explains the shutdown reason.
* The value for `cause` contains the shutdown kind like "shutdown" or * The value for `cause` contains the shutdown kind like "shutdown" or
* "restart", while `forced` will indicate if it was a normal or forced * "restart", while `forced` will indicate if it was a normal or forced
* shutdown of the application. * shutdown of the application. "in_app" is always set to indicate that
* it is a shutdown triggered from within the application.
* *
* @throws {InvalidArgumentError} * @throws {InvalidArgumentError}
* If <var>flags</var> contains unknown or incompatible flags, * If <var>flags</var> contains unknown or incompatible flags,
@ -2835,6 +2836,7 @@ GeckoDriver.prototype.quit = async function(cmd) {
return { return {
cause: (await quitApplication).data, cause: (await quitApplication).data,
forced: cancelQuit.data, forced: cancelQuit.data,
in_app: true,
}; };
}; };

Просмотреть файл

@ -112,7 +112,7 @@ class TestMemoryUsage(AwsyTestCase):
self._playback.start() self._playback.start()
# We need to reload after the mitmproxy cert is installed # We need to reload after the mitmproxy cert is installed
self.marionette.restart(clean=False) self.marionette.restart(in_app=False, clean=False)
# Setup WebDriver capabilities that we need # Setup WebDriver capabilities that we need
self.marionette.delete_session() self.marionette.delete_session()

Просмотреть файл

@ -109,7 +109,7 @@ class TestSafeBrowsingInitialDownload(MarionetteTestCase):
def tearDown(self): def tearDown(self):
try: try:
# Restart with a fresh profile # Restart with a fresh profile
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
finally: finally:
super(TestSafeBrowsingInitialDownload, self).tearDown() super(TestSafeBrowsingInitialDownload, self).tearDown()

Просмотреть файл

@ -976,19 +976,23 @@ class Marionette(object):
return self._send_message("Marionette:Quit", body) return self._send_message("Marionette:Quit", body)
@do_process_check @do_process_check
def quit(self, clean=False, in_app=False, callback=None): def quit(self, clean=False, in_app=True, callback=None):
"""Terminate the currently running instance. """
By default this method will trigger a normal shutdown of the currently running instance.
But it can also be used to force terminate the process.
This command will delete the active marionette session. It also allows This command will delete the active marionette session. It also allows
manipulation of eg. the profile data while the application is not running. manipulation of eg. the profile data while the application is not running.
To start the application again, :func:`start_session` has to be called. To start the application again, :func:`start_session` has to be called.
:param clean: If False the same profile will be used after the next start of :param clean: If True a new profile will be used after the next start of
the application. Note that the in app initiated restart always the application. Note that the in_app initiated quit always
maintains the same profile. maintains the same profile.
:param in_app: If True, marionette will cause a quit from within the :param in_app: If True, marionette will cause a quit from within the
browser. Otherwise the browser will be quit immediately application. Otherwise the application will be restarted
by killing the process. immediately by killing the process.
:param callback: If provided and `in_app` is True, the callback will :param callback: If provided and `in_app` is True, the callback will
be used to trigger the shutdown. be used to trigger the shutdown.
@ -1003,7 +1007,13 @@ class Marionette(object):
) )
quit_details = {"cause": "shutdown", "forced": False} quit_details = {"cause": "shutdown", "forced": False}
if in_app: if in_app:
if clean:
raise ValueError(
"An in_app restart cannot be triggered with the clean flag set"
)
if callback is not None and not callable(callback): if callback is not None and not callable(callback):
raise ValueError( raise ValueError(
"Specified callback '{}' is not callable".format(callback) "Specified callback '{}' is not callable".format(callback)
@ -1016,6 +1026,7 @@ class Marionette(object):
self.is_shutting_down = True self.is_shutting_down = True
if callback is not None: if callback is not None:
callback() callback()
quit_details["in_app"] = True
else: else:
quit_details = self._request_in_app_shutdown() quit_details = self._request_in_app_shutdown()
@ -1050,7 +1061,7 @@ class Marionette(object):
self.delete_session(send_request=False) self.delete_session(send_request=False)
self.instance.close(clean=clean) self.instance.close(clean=clean)
quit_details["forced"] = True quit_details.update({"in_app": False, "forced": True})
if quit_details.get("cause") not in (None, "shutdown"): if quit_details.get("cause") not in (None, "shutdown"):
raise errors.MarionetteException( raise errors.MarionetteException(
@ -1062,29 +1073,30 @@ class Marionette(object):
@do_process_check @do_process_check
def restart( def restart(
self, callback=None, clean=False, in_app=False, safe_mode=False, silent=False self, callback=None, clean=False, in_app=True, safe_mode=False, silent=False
): ):
""" """
This will terminate the currently running instance, and spawn a new instance By default this method will restart the currently running instance by using the same
with the same profile and then reuse the session id when creating a session again. profile. But it can also be forced to terminate the currently running instance, and
to spawn a new instance with the same or different profile.
:param callback: If provided and `in_app` is True, the callback will be :param callback: If provided and `in_app` is True, the callback will be
used to trigger the restart. used to trigger the restart.
:param clean: If False the same profile will be used after the restart. Note :param clean: If True a new profile will be used after the restart. Note
that the in app initiated restart always maintains the same that the in_app initiated restart always maintains the same
profile. profile.
:param in_app: If True, marionette will cause a restart from within the :param in_app: If True, marionette will cause a restart from within the
browser. Otherwise the browser will be restarted immediately application. Otherwise the application will be restarted
by killing the process. immediately by killing the process.
:param safe_mode: Optional flag to indicate that the application has to :param safe_mode: Optional flag to indicate that the application has to
be restarted in safe mode. be restarted in safe mode.
:param silent: Optional flag to indicate that the application should :param silent: Optional flag to indicate that the application should
not open any window after a restart. Note that this flag is only not open any window after a restart. Note that this flag is only
supported on MacOS. supported on MacOS and requires "in_app" to be True.
:returns: A dictionary containing details of the application restart. :returns: A dictionary containing details of the application restart.
The `cause` property reflects the reason, and `forced` indicates The `cause` property reflects the reason, and `forced` indicates
@ -1100,9 +1112,9 @@ class Marionette(object):
context = self._send_message("Marionette:GetContext", key="value") context = self._send_message("Marionette:GetContext", key="value")
restart_details = {"cause": "restart", "forced": False} restart_details = {"cause": "restart", "forced": False}
# Safe mode and the silent flag require in_app restarts. # Safe mode and the silent flag require an in_app restart.
if safe_mode or silent: if (safe_mode or silent) and not in_app:
in_app = True raise ValueError("An in_app restart is required for safe or silent mode")
if in_app: if in_app:
if clean: if clean:
@ -1122,6 +1134,7 @@ class Marionette(object):
self.is_shutting_down = True self.is_shutting_down = True
if callback is not None: if callback is not None:
callback() callback()
restart_details["in_app"] = True
else: else:
flags = ["eRestart"] flags = ["eRestart"]
if silent: if silent:
@ -1180,7 +1193,7 @@ class Marionette(object):
self.instance.restart(clean=clean) self.instance.restart(clean=clean)
self.raise_for_port(timeout=self.DEFAULT_STARTUP_TIMEOUT) self.raise_for_port(timeout=self.DEFAULT_STARTUP_TIMEOUT)
restart_details["forced"] = True restart_details.update({"in_app": False, "forced": True})
if restart_details.get("cause") not in (None, "restart"): if restart_details.get("cause") not in (None, "restart"):
raise errors.MarionetteException( raise errors.MarionetteException(

Просмотреть файл

@ -1264,7 +1264,7 @@ class BaseMarionetteTestRunner(object):
# it is still running. If that fails, kill the process. # it is still running. If that fails, kill the process.
# Therefore a new session needs to be started. # Therefore a new session needs to be started.
self.marionette.start_session() self.marionette.start_session()
self.marionette.quit(in_app=True) self.marionette.quit()
self.marionette.instance.close(clean=True) self.marionette.instance.close(clean=True)
self.marionette.instance = None self.marionette.instance = None

Просмотреть файл

@ -19,21 +19,10 @@ class TestCommandLineArguments(MarionetteTestCase):
def tearDown(self): def tearDown(self):
self.marionette.instance.app_args = self.orig_arguments self.marionette.instance.app_args = self.orig_arguments
self.marionette.quit(clean=True) self.marionette.quit(in_app=False, clean=True)
super(TestCommandLineArguments, self).tearDown() super(TestCommandLineArguments, self).tearDown()
def is_bidi_enabled(self):
with self.marionette.using_context("chrome"):
bidi_enabled = self.marionette.execute_script(
"""
const { RemoteAgent } = ChromeUtils.importESModule(
"chrome://remote/content/components/RemoteAgent.sys.mjs"
);
return !!RemoteAgent.webDriverBiDi;
"""
)
def test_debugger_address_cdp_status(self): def test_debugger_address_cdp_status(self):
# By default Remote Agent is not enabled # By default Remote Agent is not enabled
debugger_address = self.marionette.session_capabilities.get( debugger_address = self.marionette.session_capabilities.get(
@ -41,26 +30,23 @@ class TestCommandLineArguments(MarionetteTestCase):
) )
self.assertIsNone(debugger_address) self.assertIsNone(debugger_address)
# With BiDi only enabled the capability doesn't have to be returned # With BiDi only enabled the capability shouldn't be returned
self.marionette.enforce_gecko_prefs({"remote.active-protocols": 1}) self.marionette.set_pref("remote.active-protocols", 1)
try:
self.marionette.quit()
self.marionette.instance.app_args.append("-remote-debugging-port")
self.marionette.start_session()
debugger_address = self.marionette.session_capabilities.get(
"moz:debuggerAddress"
)
self.assertIsNone(debugger_address)
finally:
self.marionette.clear_pref("remote.active-protocols")
self.marionette.restart()
# With all protocols enabled the capability has to be returned
self.marionette.quit() self.marionette.quit()
self.marionette.instance.switch_profile()
self.marionette.instance.app_args.append("-remote-debugging-port")
self.marionette.start_session() self.marionette.start_session()
debugger_address = self.marionette.session_capabilities.get(
"moz:debuggerAddress"
)
self.assertIsNone(debugger_address)
# Clean the profile so that the preference is definetely reset.
self.marionette.quit(in_app=False, clean=True)
# With all protocols enabled again the capability has to be returned
self.marionette.start_session()
debugger_address = self.marionette.session_capabilities.get( debugger_address = self.marionette.session_capabilities.get(
"moz:debuggerAddress" "moz:debuggerAddress"
) )
@ -73,40 +59,36 @@ class TestCommandLineArguments(MarionetteTestCase):
# By default Remote Agent is not enabled # By default Remote Agent is not enabled
self.assertNotIn("webSocketUrl", self.marionette.session_capabilities) self.assertNotIn("webSocketUrl", self.marionette.session_capabilities)
# With BiDi not enabled the capability is still not returned # With CDP only enabled the capability is still not returned
self.marionette.enforce_gecko_prefs({"remote.active-protocols": 2}) self.marionette.set_pref("remote.active-protocols", 2)
try:
self.marionette.quit()
self.marionette.instance.app_args.append("-remote-debugging-port")
self.marionette.start_session({"webSocketUrl": True})
self.assertNotIn("webSocketUrl", self.marionette.session_capabilities) self.marionette.quit()
finally: self.marionette.instance.app_args.append("-remote-debugging-port")
self.marionette.clear_pref("remote.active-protocols") self.marionette.start_session({"webSocketUrl": True})
self.marionette.restart()
# With BiDi enabled the capability has to be returned self.assertNotIn("webSocketUrl", self.marionette.session_capabilities)
if self.is_bidi_enabled():
self.marionette.quit()
self.marionette.instance.switch_profile()
self.marionette.start_session({"webSocketUrl": True})
session_id = self.marionette.session_id # Clean the profile so that the preference is definetely reset.
websocket_url = self.marionette.session_capabilities.get("webSocketUrl") self.marionette.quit(in_app=False, clean=True)
self.assertEqual( # With all protocols enabled again the capability has to be returned
websocket_url, "ws://127.0.0.1:9222/session/{}".format(session_id) self.marionette.start_session({"webSocketUrl": True})
)
session_id = self.marionette.session_id
websocket_url = self.marionette.session_capabilities.get("webSocketUrl")
self.assertEqual(
websocket_url, "ws://127.0.0.1:9222/session/{}".format(session_id)
)
# An issue in the command line argument handling lead to open Firefox on # An issue in the command line argument handling lead to open Firefox on
# random URLs when remote-debugging-port is set to an explicit value, on macos. # random URLs when remote-debugging-port is set to an explicit value, on macos.
# See Bug 1724251. # See Bug 1724251.
def test_start_page_about_blank(self): def test_start_page_about_blank(self):
if self.is_bidi_enabled(): self.marionette.quit()
self.marionette.quit() self.marionette.instance.app_args.append("-remote-debugging-port=0")
self.marionette.instance.app_args.append("-remote-debugging-port=0") self.marionette.start_session({"webSocketUrl": True})
self.marionette.start_session({"webSocketUrl": True}) self.assertEqual(self.marionette.get_url(), "about:blank")
self.assertEqual(self.marionette.get_url(), "about:blank")
def test_startup_timeout(self): def test_startup_timeout(self):
try: try:

Просмотреть файл

@ -50,7 +50,7 @@ class TestMarionette(MarionetteTestCase):
"MarionetteActivePort file contains port", "MarionetteActivePort file contains port",
) )
self.marionette.quit(in_app=True) self.marionette.quit()
self.assertFalse( self.assertFalse(
os.path.exists(active_port_file), "MarionetteActivePort file removed" os.path.exists(active_port_file), "MarionetteActivePort file removed"
) )
@ -85,7 +85,7 @@ class TestMarionette(MarionetteTestCase):
self.assertRaises(socket.timeout, marionette.raise_for_port, timeout=1.0) self.assertRaises(socket.timeout, marionette.raise_for_port, timeout=1.0)
finally: finally:
self.marionette.quit() self.marionette.quit(in_app=False)
def test_client_socket_uses_expected_socket_timeout(self): def test_client_socket_uses_expected_socket_timeout(self):
current_socket_timeout = self.marionette.socket_timeout current_socket_timeout = self.marionette.socket_timeout

Просмотреть файл

@ -15,7 +15,7 @@ class TestEnforcePreferences(MarionetteTestCase):
self.marionette.set_context("chrome") self.marionette.set_context("chrome")
def tearDown(self): def tearDown(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(TestEnforcePreferences, self).tearDown() super(TestEnforcePreferences, self).tearDown()
@ -45,7 +45,7 @@ class TestEnforcePreferences(MarionetteTestCase):
self.enforce_prefs() self.enforce_prefs()
self.assertTrue(self.marionette.get_pref("marionette.test.bool")) self.assertTrue(self.marionette.get_pref("marionette.test.bool"))
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
self.assertEqual(self.marionette.get_pref("marionette.test.bool"), None) self.assertEqual(self.marionette.get_pref("marionette.test.bool"), None)
def test_restart_preserves_requested_capabilities(self): def test_restart_preserves_requested_capabilities(self):

Просмотреть файл

@ -13,7 +13,7 @@ import tempfile
import mozprofile import mozprofile
from marionette_driver import errors from marionette_driver import errors
from marionette_harness import MarionetteTestCase from marionette_harness import MarionetteTestCase, parameterized
class BaseProfileManagement(MarionetteTestCase): class BaseProfileManagement(MarionetteTestCase):
@ -26,7 +26,7 @@ class BaseProfileManagement(MarionetteTestCase):
shutil.rmtree(self.orig_profile_path, ignore_errors=True) shutil.rmtree(self.orig_profile_path, ignore_errors=True)
self.marionette.profile = None self.marionette.profile = None
self.marionette.quit(clean=True) self.marionette.quit(in_app=False, clean=True)
super(BaseProfileManagement, self).tearDown() super(BaseProfileManagement, self).tearDown()
@ -79,36 +79,42 @@ class ExternalProfileMixin(object):
class TestQuitRestartWithoutWorkspace(BaseProfileManagement): class TestQuitRestartWithoutWorkspace(BaseProfileManagement):
def test_quit_keeps_same_profile(self): @parameterized("safe", True)
self.marionette.quit() @parameterized("forced", False)
def test_quit_keeps_same_profile(self, in_app):
self.marionette.quit(in_app=in_app)
self.marionette.start_session() self.marionette.start_session()
self.assertEqual(self.profile_path, self.orig_profile_path) self.assertEqual(self.profile_path, self.orig_profile_path)
self.assertTrue(os.path.exists(self.orig_profile_path)) self.assertTrue(os.path.exists(self.orig_profile_path))
def test_quit_clean_creates_new_profile(self): def test_quit_clean_creates_new_profile(self):
self.marionette.quit(clean=True) self.marionette.quit(in_app=False, clean=True)
self.marionette.start_session() self.marionette.start_session()
self.assertNotEqual(self.profile_path, self.orig_profile_path) self.assertNotEqual(self.profile_path, self.orig_profile_path)
self.assertFalse(os.path.exists(self.orig_profile_path)) self.assertFalse(os.path.exists(self.orig_profile_path))
def test_restart_keeps_same_profile(self): @parameterized("safe", True)
self.marionette.restart() @parameterized("forced", False)
def test_restart_keeps_same_profile(self, in_app):
self.marionette.restart(in_app=in_app)
self.assertEqual(self.profile_path, self.orig_profile_path) self.assertEqual(self.profile_path, self.orig_profile_path)
self.assertTrue(os.path.exists(self.orig_profile_path)) self.assertTrue(os.path.exists(self.orig_profile_path))
def test_restart_clean_creates_new_profile(self): def test_restart_clean_creates_new_profile(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
self.assertNotEqual(self.profile_path, self.orig_profile_path) self.assertNotEqual(self.profile_path, self.orig_profile_path)
self.assertFalse(os.path.exists(self.orig_profile_path)) self.assertFalse(os.path.exists(self.orig_profile_path))
class TestQuitRestartWithWorkspace(WorkspaceProfileManagement): class TestQuitRestartWithWorkspace(WorkspaceProfileManagement):
def test_quit_keeps_same_profile(self): @parameterized("safe", True)
self.marionette.quit() @parameterized("forced", False)
def test_quit_keeps_same_profile(self, in_app):
self.marionette.quit(in_app=in_app)
self.marionette.start_session() self.marionette.start_session()
self.assertEqual(self.profile_path, self.orig_profile_path) self.assertEqual(self.profile_path, self.orig_profile_path)
@ -116,22 +122,24 @@ class TestQuitRestartWithWorkspace(WorkspaceProfileManagement):
self.assertTrue(os.path.exists(self.orig_profile_path)) self.assertTrue(os.path.exists(self.orig_profile_path))
def test_quit_clean_creates_new_profile(self): def test_quit_clean_creates_new_profile(self):
self.marionette.quit(clean=True) self.marionette.quit(in_app=False, clean=True)
self.marionette.start_session() self.marionette.start_session()
self.assertNotEqual(self.profile_path, self.orig_profile_path) self.assertNotEqual(self.profile_path, self.orig_profile_path)
self.assertIn(self.workspace, self.profile_path) self.assertIn(self.workspace, self.profile_path)
self.assertFalse(os.path.exists(self.orig_profile_path)) self.assertFalse(os.path.exists(self.orig_profile_path))
def test_restart_keeps_same_profile(self): @parameterized("safe", True)
self.marionette.restart() @parameterized("forced", False)
def test_restart_keeps_same_profile(self, in_app):
self.marionette.restart(in_app=in_app)
self.assertEqual(self.profile_path, self.orig_profile_path) self.assertEqual(self.profile_path, self.orig_profile_path)
self.assertNotIn(self.workspace, self.profile_path) self.assertNotIn(self.workspace, self.profile_path)
self.assertTrue(os.path.exists(self.orig_profile_path)) self.assertTrue(os.path.exists(self.orig_profile_path))
def test_restart_clean_creates_new_profile(self): def test_restart_clean_creates_new_profile(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
self.assertNotEqual(self.profile_path, self.orig_profile_path) self.assertNotEqual(self.profile_path, self.orig_profile_path)
self.assertIn(self.workspace, self.profile_path) self.assertIn(self.workspace, self.profile_path)

Просмотреть файл

@ -133,7 +133,7 @@ class TestQuitRestart(MarionetteTestCase):
) )
def test_force_restart(self): def test_force_restart(self):
self.marionette.restart() self.marionette.restart(in_app=False)
self.assertEqual(self.marionette.profile, self.profile) self.assertEqual(self.marionette.profile, self.profile)
self.assertNotEqual(self.marionette.session_id, self.session_id) self.assertNotEqual(self.marionette.session_id, self.session_id)
@ -144,7 +144,7 @@ class TestQuitRestart(MarionetteTestCase):
) )
def test_force_clean_restart(self): def test_force_clean_restart(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
self.assertNotEqual(self.marionette.profile, self.profile) self.assertNotEqual(self.marionette.profile, self.profile)
self.assertNotEqual(self.marionette.session_id, self.session_id) self.assertNotEqual(self.marionette.session_id, self.session_id)
# A forced restart will cause a new process id # A forced restart will cause a new process id
@ -154,7 +154,7 @@ class TestQuitRestart(MarionetteTestCase):
) )
def test_force_quit(self): def test_force_quit(self):
self.marionette.quit() self.marionette.quit(in_app=False)
self.assertEqual(self.marionette.session, None) self.assertEqual(self.marionette.session, None)
with self.assertRaisesRegexp( with self.assertRaisesRegexp(
@ -163,7 +163,7 @@ class TestQuitRestart(MarionetteTestCase):
self.marionette.get_url() self.marionette.get_url()
def test_force_clean_quit(self): def test_force_clean_quit(self):
self.marionette.quit(clean=True) self.marionette.quit(in_app=False, clean=True)
self.assertEqual(self.marionette.session, None) self.assertEqual(self.marionette.session, None)
with self.assertRaisesRegexp( with self.assertRaisesRegexp(
@ -178,7 +178,14 @@ class TestQuitRestart(MarionetteTestCase):
self.marionette.get_pref("startup.homepage_welcome_url"), "about:about" self.marionette.get_pref("startup.homepage_welcome_url"), "about:about"
) )
def test_no_in_app_clean_restart(self): def test_quit_no_in_app_and_clean(self):
# Test that in_app and clean cannot be used in combination
with self.assertRaisesRegexp(
ValueError, "cannot be triggered with the clean flag set"
):
self.marionette.quit(in_app=True, clean=True)
def test_restart_no_in_app_and_clean(self):
# Test that in_app and clean cannot be used in combination # Test that in_app and clean cannot be used in combination
with self.assertRaisesRegexp( with self.assertRaisesRegexp(
ValueError, "cannot be triggered with the clean flag set" ValueError, "cannot be triggered with the clean flag set"
@ -198,11 +205,20 @@ class TestQuitRestart(MarionetteTestCase):
self.marionette.restart(safe_mode=True) self.marionette.restart(safe_mode=True)
self.assertTrue(self.is_safe_mode, "Safe Mode is not enabled") self.assertTrue(self.is_safe_mode, "Safe Mode is not enabled")
finally: finally:
self.marionette.quit(clean=True) self.marionette.quit(in_app=False, clean=True)
def test_restart_safe_mode_requires_in_app(self):
self.assertFalse(self.is_safe_mode, "Safe Mode is unexpectedly enabled")
with self.assertRaisesRegexp(ValueError, "in_app restart is required"):
self.marionette.restart(in_app=False, safe_mode=True)
self.assertFalse(self.is_safe_mode, "Safe Mode is unexpectedly enabled")
self.marionette.quit(in_app=False, clean=True)
def test_in_app_restart(self): def test_in_app_restart(self):
details = self.marionette.restart(in_app=True) details = self.marionette.restart()
self.assertTrue(details["in_app"], "Expected in_app restart")
self.assertFalse(details["forced"], "Expected non-forced shutdown") self.assertFalse(details["forced"], "Expected non-forced shutdown")
self.assertEqual(self.marionette.profile, self.profile) self.assertEqual(self.marionette.profile, self.profile)
@ -225,8 +241,8 @@ class TestQuitRestart(MarionetteTestCase):
""" """
) )
details = self.marionette.restart(in_app=True) details = self.marionette.restart()
self.assertTrue(details["in_app"], "Expected in_app restart")
self.assertTrue(details["forced"], "Expected forced shutdown") self.assertTrue(details["forced"], "Expected forced shutdown")
self.assertEqual(self.marionette.profile, self.profile) self.assertEqual(self.marionette.profile, self.profile)
@ -239,9 +255,8 @@ class TestQuitRestart(MarionetteTestCase):
) )
def test_in_app_restart_with_callback(self): def test_in_app_restart_with_callback(self):
self.marionette.restart( details = self.marionette.restart(callback=lambda: self.shutdown(restart=True))
in_app=True, callback=lambda: self.shutdown(restart=True) self.assertTrue(details["in_app"], "Expected in_app restart")
)
self.assertEqual(self.marionette.profile, self.profile) self.assertEqual(self.marionette.profile, self.profile)
self.assertNotEqual(self.marionette.session_id, self.session_id) self.assertNotEqual(self.marionette.session_id, self.session_id)
@ -252,12 +267,15 @@ class TestQuitRestart(MarionetteTestCase):
self.marionette.get_pref("startup.homepage_welcome_url"), "about:about" self.marionette.get_pref("startup.homepage_welcome_url"), "about:about"
) )
def test_in_app_restart_with_callback_not_callable(self): def test_in_app_restart_with_non_callable_callback(self):
with self.assertRaisesRegexp(ValueError, "is not callable"): with self.assertRaisesRegexp(ValueError, "is not callable"):
self.marionette.restart(in_app=True, callback=4) self.marionette.restart(callback=4)
self.assertEqual(self.marionette.instance.runner.returncode, None)
self.assertEqual(self.marionette.is_shutting_down, False)
@unittest.skipIf(sys.platform.startswith("win"), "Bug 1493796") @unittest.skipIf(sys.platform.startswith("win"), "Bug 1493796")
def test_in_app_restart_with_callback_but_process_quit(self): def test_in_app_restart_with_callback_but_process_quits_instead(self):
try: try:
timeout_shutdown = self.marionette.shutdown_timeout timeout_shutdown = self.marionette.shutdown_timeout
timeout_startup = self.marionette.startup_timeout timeout_startup = self.marionette.startup_timeout
@ -267,9 +285,7 @@ class TestQuitRestart(MarionetteTestCase):
with self.assertRaisesRegexp( with self.assertRaisesRegexp(
IOError, "Process unexpectedly quit without restarting" IOError, "Process unexpectedly quit without restarting"
): ):
self.marionette.restart( self.marionette.restart(callback=lambda: self.shutdown(restart=False))
in_app=True, callback=lambda: self.shutdown(restart=False)
)
finally: finally:
self.marionette.shutdown_timeout = timeout_shutdown self.marionette.shutdown_timeout = timeout_shutdown
self.marionette.startup_timeout = timeout_startup self.marionette.startup_timeout = timeout_startup
@ -294,7 +310,8 @@ class TestQuitRestart(MarionetteTestCase):
self.marionette.delete_session() self.marionette.delete_session()
self.marionette.start_session(capabilities={"moz:fooBar": True}) self.marionette.start_session(capabilities={"moz:fooBar": True})
self.marionette.restart(in_app=True) details = self.marionette.restart()
self.assertTrue(details["in_app"], "Expected in_app restart")
self.assertEqual(self.marionette.session.get("moz:fooBar"), True) self.assertEqual(self.marionette.session.get("moz:fooBar"), True)
@unittest.skipUnless(sys.platform.startswith("darwin"), "Only supported on MacOS") @unittest.skipUnless(sys.platform.startswith("darwin"), "Only supported on MacOS")
@ -313,11 +330,21 @@ class TestQuitRestart(MarionetteTestCase):
self.marionette.restart(silent=True) self.marionette.restart(silent=True)
self.assertTrue(self.marionette.session_capabilities["moz:windowless"]) self.assertTrue(self.marionette.session_capabilities["moz:windowless"])
self.marionette.restart(in_app=True) self.marionette.restart()
self.assertTrue(self.marionette.session_capabilities["moz:windowless"]) self.assertTrue(self.marionette.session_capabilities["moz:windowless"])
self.marionette.delete_session() self.marionette.delete_session()
@unittest.skipUnless(sys.platform.startswith("darwin"), "Only supported on MacOS")
def test_in_app_silent_restart_requires_in_app(self):
self.marionette.delete_session()
self.marionette.start_session(capabilities={"moz:windowless": True})
with self.assertRaisesRegexp(ValueError, "in_app restart is required"):
self.marionette.restart(in_app=False, silent=True)
self.marionette.delete_session()
@unittest.skipIf( @unittest.skipIf(
sys.platform.startswith("darwin"), "Not supported on other platforms than MacOS" sys.platform.startswith("darwin"), "Not supported on other platforms than MacOS"
) )
@ -328,7 +355,8 @@ class TestQuitRestart(MarionetteTestCase):
self.marionette.start_session(capabilities={"moz:windowless": True}) self.marionette.start_session(capabilities={"moz:windowless": True})
def test_in_app_quit(self): def test_in_app_quit(self):
details = self.marionette.quit(in_app=True) details = self.marionette.quit()
self.assertTrue(details["in_app"], "Expected in_app shutdown")
self.assertFalse(details["forced"], "Expected non-forced shutdown") self.assertFalse(details["forced"], "Expected non-forced shutdown")
self.assertEqual(self.marionette.instance.runner.returncode, 0) self.assertEqual(self.marionette.instance.runner.returncode, 0)
@ -356,7 +384,8 @@ class TestQuitRestart(MarionetteTestCase):
""" """
) )
details = self.marionette.quit(in_app=True) details = self.marionette.quit()
self.assertTrue(details["in_app"], "Expected in_app shutdown")
self.assertTrue(details["forced"], "Expected forced shutdown") self.assertTrue(details["forced"], "Expected forced shutdown")
self.assertEqual(self.marionette.instance.runner.returncode, 0) self.assertEqual(self.marionette.instance.runner.returncode, 0)
@ -374,10 +403,12 @@ class TestQuitRestart(MarionetteTestCase):
) )
def test_in_app_quit_with_callback(self): def test_in_app_quit_with_callback(self):
details = self.marionette.quit(in_app=True, callback=self.shutdown) details = self.marionette.quit(callback=self.shutdown)
self.assertTrue(details["in_app"], "Expected in_app shutdown")
self.assertFalse(details["forced"], "Expected non-forced shutdown")
self.assertEqual(self.marionette.instance.runner.returncode, 0) self.assertEqual(self.marionette.instance.runner.returncode, 0)
self.assertEqual(self.marionette.is_shutting_down, False) self.assertEqual(self.marionette.is_shutting_down, False)
self.assertFalse(details["forced"], "Expected non-forced shutdown")
self.assertEqual(self.marionette.session, None) self.assertEqual(self.marionette.session, None)
with self.assertRaisesRegexp( with self.assertRaisesRegexp(
@ -392,9 +423,9 @@ class TestQuitRestart(MarionetteTestCase):
self.marionette.get_pref("startup.homepage_welcome_url"), "about:about" self.marionette.get_pref("startup.homepage_welcome_url"), "about:about"
) )
def tet_in_app_quit_with_callback_not_callable(self): def test_in_app_quit_with_non_callable_callback(self):
with self.assertRaisesRegexp(ValueError, "is not callable"): with self.assertRaisesRegexp(ValueError, "is not callable"):
self.marionette.quit(in_app=True, callback=4) self.marionette.quit(callback=4)
self.assertEqual(self.marionette.instance.runner.returncode, None) self.assertEqual(self.marionette.instance.runner.returncode, None)
self.assertEqual(self.marionette.is_shutting_down, False) self.assertEqual(self.marionette.is_shutting_down, False)
@ -441,7 +472,7 @@ class TestQuitRestart(MarionetteTestCase):
) )
self.marionette.find_element(By.TAG_NAME, "input").send_keys("foo") self.marionette.find_element(By.TAG_NAME, "input").send_keys("foo")
self.marionette.quit(in_app=True) self.marionette.quit()
self.assertNotEqual(self.marionette.instance.runner.returncode, None) self.assertNotEqual(self.marionette.instance.runner.returncode, None)
self.marionette.start_session() self.marionette.start_session()
@ -455,7 +486,7 @@ class TestQuitRestart(MarionetteTestCase):
) )
self.marionette.set_context("chrome") self.marionette.set_context("chrome")
self.marionette.quit(in_app=True) self.marionette.quit()
self.assertEqual(self.marionette.session, None) self.assertEqual(self.marionette.session, None)
self.marionette.start_session() self.marionette.start_session()
self.assertNotIn( self.assertNotIn(
@ -474,7 +505,7 @@ class TestQuitRestart(MarionetteTestCase):
) )
with self.marionette.using_context("chrome"): with self.marionette.using_context("chrome"):
self.marionette.quit(in_app=True) self.marionette.quit()
self.assertEqual(self.marionette.session, None) self.assertEqual(self.marionette.session, None)
self.marionette.start_session() self.marionette.start_session()
self.assertNotIn( self.assertNotIn(
@ -492,7 +523,7 @@ class TestQuitRestart(MarionetteTestCase):
# restart while we are in chrome context # restart while we are in chrome context
self.marionette.set_context("chrome") self.marionette.set_context("chrome")
self.marionette.restart(in_app=True) self.marionette.restart()
self.assertNotEqual(self.marionette.process_id, self.pid) self.assertNotEqual(self.marionette.process_id, self.pid)
@ -513,7 +544,7 @@ class TestQuitRestart(MarionetteTestCase):
# restart while we are in chrome context # restart while we are in chrome context
with self.marionette.using_context("chrome"): with self.marionette.using_context("chrome"):
self.marionette.restart(in_app=True) self.marionette.restart()
self.assertNotEqual(self.marionette.process_id, self.pid) self.assertNotEqual(self.marionette.process_id, self.pid)

Просмотреть файл

@ -13,7 +13,7 @@ class ServiceWorkerAtShutdownTestCase(MarionetteTestCase):
self.set_pref_to_delete_site_data_on_shutdown() self.set_pref_to_delete_site_data_on_shutdown()
def tearDown(self): def tearDown(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(ServiceWorkerAtShutdownTestCase, self).tearDown() super(ServiceWorkerAtShutdownTestCase, self).tearDown()
def install_service_worker(self): def install_service_worker(self):

Просмотреть файл

@ -31,7 +31,7 @@ class PurgeExtensionServiceWorkersOnPrefDisabled(MarionetteServiceWorkerTestCase
self.marionette.restart(in_app=True) self.marionette.restart(in_app=True)
def tearDown(self): def tearDown(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(PurgeExtensionServiceWorkersOnPrefDisabled, self).tearDown() super(PurgeExtensionServiceWorkersOnPrefDisabled, self).tearDown()
def test_unregistering_service_worker_when_clearing_data(self): def test_unregistering_service_worker_when_clearing_data(self):

Просмотреть файл

@ -31,7 +31,7 @@ class TemporarilyInstalledAddonServiceWorkerNotPersisted(
self.marionette.restart(in_app=True) self.marionette.restart(in_app=True)
def tearDown(self): def tearDown(self):
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(TemporarilyInstalledAddonServiceWorkerNotPersisted, self).tearDown() super(TemporarilyInstalledAddonServiceWorkerNotPersisted, self).tearDown()
def test_temporarily_installed_addon_serviceWorkers_not_persisted(self): def test_temporarily_installed_addon_serviceWorkers_not_persisted(self):

Просмотреть файл

@ -222,7 +222,7 @@ class Browser(object):
return new_tab return new_tab
def quit(self, in_app=False): def quit(self, in_app=True):
self.marionette.quit(in_app=in_app) self.marionette.quit(in_app=in_app)
def restart(self): def restart(self):

Просмотреть файл

@ -26,7 +26,7 @@ def test_deletion_request_ping(browser, helpers):
assert "environment" not in ping["payload"] assert "environment" not in ping["payload"]
# Close Firefox cleanly. # Close Firefox cleanly.
browser.quit(in_app=True) browser.quit()
# Start Firefox. # Start Firefox.
browser.start_session() browser.start_session()

Просмотреть файл

@ -150,7 +150,7 @@ class TelemetryTestCase(WindowManagerMixin, MarionetteTestCase):
def quit_browser(self): def quit_browser(self):
"""Quit the browser.""" """Quit the browser."""
return self.marionette.quit(in_app=True) return self.marionette.quit()
def install_addon(self): def install_addon(self):
"""Install a minimal addon.""" """Install a minimal addon."""
@ -231,4 +231,4 @@ class TelemetryTestCase(WindowManagerMixin, MarionetteTestCase):
"""Stop the ping server and tear down the testcase.""" """Stop the ping server and tear down the testcase."""
super(TelemetryTestCase, self).tearDown() super(TelemetryTestCase, self).tearDown()
self.ping_server.stop() self.ping_server.stop()
self.marionette.quit(clean=True) self.marionette.quit(in_app=False, clean=True)

Просмотреть файл

@ -13,7 +13,7 @@ class TestFissionAutostart(MarionetteTestCase):
sandbox="system", sandbox="system",
) )
self.marionette.quit(in_app=True, callback=call_quit) self.marionette.quit(callback=call_quit)
self.assertEqual(self.marionette.instance.runner.returncode, 0) self.assertEqual(self.marionette.instance.runner.returncode, 0)
def test_exit_code(self): def test_exit_code(self):
@ -27,5 +27,5 @@ class TestFissionAutostart(MarionetteTestCase):
sandbox="system", sandbox="system",
) )
self.marionette.quit(in_app=True, callback=call_quit) self.marionette.quit(callback=call_quit)
self.assertEqual(self.marionette.instance.runner.returncode, 5) self.assertEqual(self.marionette.instance.runner.returncode, 5)

Просмотреть файл

@ -142,7 +142,7 @@ class TestFissionAutostart(MarionetteTestCase):
def full_restart(self): def full_restart(self):
profile = self.marionette.instance.profile profile = self.marionette.instance.profile
try: try:
self.marionette.quit(in_app=True, clean=False) self.marionette.quit()
yield profile yield profile
finally: finally:
self.marionette.start_session() self.marionette.start_session()
@ -161,7 +161,7 @@ class TestFissionAutostart(MarionetteTestCase):
Prefs.FISSION_AUTOSTART Prefs.FISSION_AUTOSTART
] ]
del self.marionette.instance.required_prefs[Prefs.FISSION_AUTOSTART] del self.marionette.instance.required_prefs[Prefs.FISSION_AUTOSTART]
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
self.setUpSession() self.setUpSession()
@ -177,7 +177,7 @@ class TestFissionAutostart(MarionetteTestCase):
self.marionette.instance.required_prefs[ self.marionette.instance.required_prefs[
Prefs.FISSION_AUTOSTART Prefs.FISSION_AUTOSTART
] = self.fissionRequired ] = self.fissionRequired
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(TestFissionAutostart, self).tearDown() super(TestFissionAutostart, self).tearDown()

Просмотреть файл

@ -150,7 +150,7 @@ class TestWin32kAutostart(MarionetteTestCase):
def full_restart(self): def full_restart(self):
profile = self.marionette.instance.profile profile = self.marionette.instance.profile
try: try:
self.marionette.quit(in_app=True, clean=False) self.marionette.quit()
yield profile yield profile
finally: finally:
self.marionette.start_session() self.marionette.start_session()
@ -167,7 +167,7 @@ class TestWin32kAutostart(MarionetteTestCase):
if Prefs.WIN32K in self.marionette.instance.required_prefs: if Prefs.WIN32K in self.marionette.instance.required_prefs:
self.win32kRequired = self.marionette.instance.required_prefs[Prefs.WIN32K] self.win32kRequired = self.marionette.instance.required_prefs[Prefs.WIN32K]
del self.marionette.instance.required_prefs[Prefs.WIN32K] del self.marionette.instance.required_prefs[Prefs.WIN32K]
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
self.setUpSession() self.setUpSession()
@ -201,7 +201,7 @@ class TestWin32kAutostart(MarionetteTestCase):
def tearDown(self): def tearDown(self):
if self.win32kRequired is not None: if self.win32kRequired is not None:
self.marionette.instance.required_prefs[Prefs.WIN32K] = self.win32kRequired self.marionette.instance.required_prefs[Prefs.WIN32K] = self.win32kRequired
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(TestWin32kAutostart, self).tearDown() super(TestWin32kAutostart, self).tearDown()

Просмотреть файл

@ -150,7 +150,7 @@ class TestWin32kAutostart(MarionetteTestCase):
def full_restart(self): def full_restart(self):
profile = self.marionette.instance.profile profile = self.marionette.instance.profile
try: try:
self.marionette.quit(in_app=True, clean=False) self.marionette.quit()
yield profile yield profile
finally: finally:
self.marionette.start_session() self.marionette.start_session()
@ -167,7 +167,7 @@ class TestWin32kAutostart(MarionetteTestCase):
if Prefs.WIN32K in self.marionette.instance.required_prefs: if Prefs.WIN32K in self.marionette.instance.required_prefs:
self.win32kRequired = self.marionette.instance.required_prefs[Prefs.WIN32K] self.win32kRequired = self.marionette.instance.required_prefs[Prefs.WIN32K]
del self.marionette.instance.required_prefs[Prefs.WIN32K] del self.marionette.instance.required_prefs[Prefs.WIN32K]
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
self.setUpSession() self.setUpSession()
@ -201,6 +201,6 @@ class TestWin32kAutostart(MarionetteTestCase):
def tearDown(self): def tearDown(self):
if self.win32kRequired is not None: if self.win32kRequired is not None:
self.marionette.instance.required_prefs[Prefs.WIN32K] = self.win32kRequired self.marionette.instance.required_prefs[Prefs.WIN32K] = self.win32kRequired
self.marionette.restart(clean=True) self.marionette.restart(in_app=False, clean=True)
super(TestWin32kAutostart, self).tearDown() super(TestWin32kAutostart, self).tearDown()