--- 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)