From 3ffdfc67e75a608c05b35086233d40d7c09440cd Mon Sep 17 00:00:00 2001 From: John Chilton Date: Fri, 22 Sep 2017 07:58:18 -0400 Subject: [PATCH] Selenium - catch popups fading out as transitions to retry various actions on. Previously we only detected transitions for retrying actions based on stale element exceptions, this expands that to include popups that may be fading out for instance. I think this is what is happening with the transiently failing test here https://jenkins.galaxyproject.org/job/selenium/528/artifact/528-test-errors/test_save_as2017092203291506065342/stacktrace.txt. The exception indicates that a click was not clickable because a modal element that was fading out - though it had been previously clickable. I think this should fix that. --- test/galaxy_selenium/has_driver.py | 12 ++++++++++ test/galaxy_selenium/navigates_galaxy.py | 28 +++++++++++++++++++++--- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/test/galaxy_selenium/has_driver.py b/test/galaxy_selenium/has_driver.py index 021de2eac0a..4dca4fbe5d3 100644 --- a/test/galaxy_selenium/has_driver.py +++ b/test/galaxy_selenium/has_driver.py @@ -140,5 +140,17 @@ class HasDriver: ) +def execption_indicates_not_clickable(exception): + return "not clickable" in str(exception) + + def exception_indicates_stale_element(exception): return "stale" in str(exception) + + +__all__ = ( + "execption_indicates_not_clickable", + "exception_indicates_stale_element", + "HasDriver", + "TimeoutException", +) diff --git a/test/galaxy_selenium/navigates_galaxy.py b/test/galaxy_selenium/navigates_galaxy.py index 5a87c5732c8..ed3773cb87c 100644 --- a/test/galaxy_selenium/navigates_galaxy.py +++ b/test/galaxy_selenium/navigates_galaxy.py @@ -15,7 +15,12 @@ import requests import yaml from .data import NAVIGATION_DATA -from .has_driver import exception_indicates_stale_element, HasDriver, TimeoutException +from .has_driver import ( + execption_indicates_not_clickable, + exception_indicates_stale_element, + HasDriver, + TimeoutException, +) from . import sizzle # Test case data @@ -28,7 +33,24 @@ class NullTourCallback(object): pass -def retry_call_during_transitions(f, attempts=5, sleep=.1, exception_check=exception_indicates_stale_element): +def excepion_seems_to_indicate_transition(e): + """True if exception seems to indicate the page state is transitioning. + + Galaxy features many different transition effects that change the page state over time. + These transitions make it slightly more difficult to test Galaxy because atomic input + actions take an indeterminate amount of time to be reflected on the screen. This method + takes a Selenium assertion and tries to infer if such a transition could be the root + cause of the exception. The methods that follow use it to allow retrying actions during + transitions. + + Currently the two kinds of exceptions that we say may indicate a transition are + StaleElement exceptions (a DOM element grabbed at one step is no longer available) + and "not clickable" exceptions (so perhaps a popup modal is blocking a click). + """ + return exception_indicates_stale_element(e) or execption_indicates_not_clickable(e) + + +def retry_call_during_transitions(f, attempts=5, sleep=.1, exception_check=excepion_seems_to_indicate_transition): previous_attempts = 0 while True: try: @@ -44,7 +66,7 @@ def retry_call_during_transitions(f, attempts=5, sleep=.1, exception_check=excep previous_attempts += 1 -def retry_during_transitions(f, attempts=5, sleep=.1, exception_check=exception_indicates_stale_element): +def retry_during_transitions(f, attempts=5, sleep=.1, exception_check=excepion_seems_to_indicate_transition): @wraps(f) def _retry(*args, **kwds):