Bug 1425947 - Run session finalizers also for new_session fixture. draft
authorHenrik Skupin <mail@hskupin.info>
Tue, 19 Dec 2017 13:02:39 +0100
changeset 713000 6f5d6b45406c1cf404fee5fa75da600ae484a2cf
parent 711413 22d2831cc1f41e1b3e1ebac9be5a7aff33684843
child 713001 6492e332186b2dcddb3443ba61b577015889553e
push id93523
push userbmo:hskupin@gmail.com
push dateTue, 19 Dec 2017 12:14:27 +0000
bugs1425947
milestone59.0a1
Bug 1425947 - Run session finalizers also for new_session fixture. Session finalizers should not only be run for the 'session' fixture, but also for any session as created with the 'new_session' fixture. MozReview-Commit-ID: 4jntS94mkR1
testing/web-platform/tests/webdriver/tests/support/fixtures.py
--- a/testing/web-platform/tests/webdriver/tests/support/fixtures.py
+++ b/testing/web-platform/tests/webdriver/tests/support/fixtures.py
@@ -12,83 +12,107 @@ from tests.support.wait import wait
 from tests.support import merge_dictionaries
 
 default_host = "http://127.0.0.1"
 default_port = "4444"
 
 logger = mozlog.get_default_logger()
 
 
+_current_session = None
+
+
 def ignore_exceptions(f):
     def inner(*args, **kwargs):
         try:
             return f(*args, **kwargs)
         except webdriver.error.WebDriverException as e:
             logger.warning("Ignored exception %s" % e)
     inner.__name__ = f.__name__
     return inner
 
 
 @ignore_exceptions
-def _ensure_valid_window(session):
-    """If current window is not open anymore, ensure to have a valid
-    one selected.
+def _ensure_valid_window():
+    """Ensure to have a valid window selected if current one has been closed."""
+    global _current_session
+    if not _current_session:
+        return
 
-    """
     try:
-        session.window_handle
+        _current_session.window_handle
     except webdriver.NoSuchWindowException:
-        session.window_handle = session.handles[0]
+        _current_session.window_handle = _current_session.handles[0]
 
 
 @ignore_exceptions
-def _dismiss_user_prompts(session):
-    """Dismisses any open user prompts in windows."""
-    current_window = session.window_handle
+def _dismiss_user_prompts():
+    """Dismiss any open user prompts in windows."""
+    global _current_session
+    if not _current_session:
+        return
 
-    for window in _windows(session):
-        session.window_handle = window
+    current_window = _current_session.window_handle
+
+    for window in _windows(_current_session):
+        _current_session.window_handle = window
         try:
-            session.alert.dismiss()
+            _current_session.alert.dismiss()
         except webdriver.NoSuchAlertException:
             pass
 
-    session.window_handle = current_window
+    _current_session.window_handle = current_window
 
 
 @ignore_exceptions
-def _restore_window_state(session):
-    """Reset window to an acceptable size, bringing it out of maximized,
-    minimized, or fullscreened state
+def _restore_window_state():
+    """Reset window to an acceptable size.
 
+    In case the window is maximized, minimized, or fullscreened,
+    it brings it out of this state.
     """
-    session.window.size = (800, 600)
+    global _current_session
+    if not _current_session:
+        return
+
+    _current_session.window.size = (800, 600)
 
 
 @ignore_exceptions
-def _restore_windows(session):
-    """Closes superfluous windows opened by the test without ending
-    the session implicitly by closing the last window.
+def _restore_windows():
+    """Closes superfluous windows opened by the test.
+
+    It will not end the session implicitly by closing the last window.
     """
-    current_window = session.window_handle
+    global _current_session
+    if not _current_session:
+        return
 
-    for window in _windows(session, exclude=[current_window]):
-        session.window_handle = window
-        if len(session.handles) > 1:
-            session.close()
+    current_window = _current_session.window_handle
 
-    session.window_handle = current_window
+    for window in _windows(_current_session, exclude=[current_window]):
+        _current_session.window_handle = window
+        if len(_current_session.handles) > 1:
+            _current_session.close()
+
+    _current_session.window_handle = current_window
 
 
-def _switch_to_top_level_browsing_context(session):
-    """If the current browsing context selected by WebDriver is a
-    `<frame>` or an `<iframe>`, switch it back to the top-level
-    browsing context.
+@ignore_exceptions
+def _switch_to_top_level_browsing_context():
+    """Ensure the top-level browsing context is selected.
+
+    This is necessary when the current browsing context as selected by
+    WebDriver is a `<frame>` or an `<iframe>`.
     """
-    session.switch_frame(None)
+    global _current_session
+    if not _current_session:
+        return
+
+    _current_session.switch_frame(None)
 
 
 def _windows(session, exclude=None):
     """Set of window handles, filtered by an `exclude` list if
     provided.
     """
     if exclude is None:
         exclude = []
@@ -136,19 +160,16 @@ def configuration():
 
     return {
         "host": host,
         "port": port,
         "capabilities": capabilities
     }
 
 
-_current_session = None
-
-
 def session(configuration, request):
     """Create and start a session for a test that does not itself test session creation.
 
     By default the session will stay open after each test, but we always try to start a
     new one and assume that if that fails there is already a valid session. This makes it
     possible to recover from some errors that might leave the session in a bad state, but
     does not demand that we start a new session per test."""
     global _current_session
@@ -157,23 +178,22 @@ def session(configuration, request):
                                              configuration["port"],
                                              capabilities={"alwaysMatch": configuration["capabilities"]})
     try:
         _current_session.start()
     except webdriver.error.SessionNotCreatedException:
         if not _current_session.session_id:
             raise
 
-    # finalisers are popped off a stack,
-    # making their ordering reverse
-    request.addfinalizer(lambda: _switch_to_top_level_browsing_context(_current_session))
-    request.addfinalizer(lambda: _restore_window_state(_current_session))
-    request.addfinalizer(lambda: _restore_windows(_current_session))
-    request.addfinalizer(lambda: _dismiss_user_prompts(_current_session))
-    request.addfinalizer(lambda: _ensure_valid_window(_current_session))
+    # finalisers are popped off a stack, making their ordering reverse
+    request.addfinalizer(_switch_to_top_level_browsing_context)
+    request.addfinalizer(_restore_window_state)
+    request.addfinalizer(_restore_windows)
+    request.addfinalizer(_dismiss_user_prompts)
+    request.addfinalizer(_ensure_valid_window)
 
     return _current_session
 
 
 def new_session(configuration, request):
     """Return a factory function that will attempt to start a session with a given body.
 
     This is intended for tests that are themselves testing new session creation, and the
@@ -192,17 +212,24 @@ def new_session(configuration, request):
         value = _session.send_command("POST", "session", body=body)
         # Don't set the global session until we are sure this succeeded
         _current_session = _session
         _session.session_id = value["sessionId"]
 
         return value, _current_session
 
     end()
+
+    # finalisers are popped off a stack, making their ordering reverse
     request.addfinalizer(end)
+    request.addfinalizer(_switch_to_top_level_browsing_context)
+    request.addfinalizer(_restore_window_state)
+    request.addfinalizer(_restore_windows)
+    request.addfinalizer(_dismiss_user_prompts)
+    request.addfinalizer(_ensure_valid_window)
 
     return create_session
 
 
 def add_browser_capabilites(configuration):
     def update_capabilities(capabilities):
         # Make sure there aren't keys in common.
         assert not set(configuration["capabilities"]).intersection(set(capabilities))
@@ -216,16 +243,17 @@ def url(server_config):
     def inner(path, protocol="http", query="", fragment=""):
         port = server_config["ports"][protocol][0]
         host = "%s:%s" % (server_config["host"], port)
         return urlparse.urlunsplit((protocol, host, path, query, fragment))
 
     inner.__name__ = "url"
     return inner
 
+
 def create_dialog(session):
     """Create a dialog (one of "alert", "prompt", or "confirm") and provide a
     function to validate that the dialog has been "handled" (either accepted or
     dismissed) by returning some value."""
 
     def create_dialog(dialog_type, text=None, result_var=None):
         assert dialog_type in ("alert", "confirm", "prompt"), (
                "Invalid dialog type: '%s'" % dialog_type)