From 7dd9213fd874a4bf12d0eee86f03c48dd467a6f2 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Thu, 31 Jan 2019 13:12:08 -0500 Subject: [PATCH 1/5] Add longer pauses for some selenium tests, mark as slow renders for easier tracking down and fixing. --- test/galaxy_selenium/navigates_galaxy.py | 2 ++ test/selenium_tests/test_custom_builds.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/test/galaxy_selenium/navigates_galaxy.py b/test/galaxy_selenium/navigates_galaxy.py index 3856880a246..04ef23be115 100644 --- a/test/galaxy_selenium/navigates_galaxy.py +++ b/test/galaxy_selenium/navigates_galaxy.py @@ -40,6 +40,8 @@ WaitType = collections.namedtuple("WaitType", ["name", "default_length"]) WAIT_TYPES = Bunch( # Rendering a form and registering callbacks, etc... UX_RENDER=WaitType("ux_render", 1), + # TODO: Track down and fix all of these. + UX_SLOW_RENDER=WaitType("ux_slow_render", 3), # Fade in, fade out, etc... UX_TRANSITION=WaitType("ux_transition", 5), # Toastr popup and dismissal, etc... diff --git a/test/selenium_tests/test_custom_builds.py b/test/selenium_tests/test_custom_builds.py index c678540381a..7e17fe691e9 100644 --- a/test/selenium_tests/test_custom_builds.py +++ b/test/selenium_tests/test_custom_builds.py @@ -79,7 +79,7 @@ class CustomBuildsTestcase(SharedStateSeleniumTestCase): delete_button.click() def get_custom_builds(self): - self.sleep_for(self.wait_types.UX_RENDER) + self.sleep_for(self.wait_types.UX_TRANSITION) builds = [] grid = self.wait_for_selector('table.grid > tbody') for row in grid.find_elements_by_tag_name('tr'): From d59352224c8f41ba8a1a9219b2bafa24e1a1f142 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Thu, 31 Jan 2019 15:34:56 -0500 Subject: [PATCH 2/5] Set chrome to run headlessly -- todo configure via env var or switch --- test/galaxy_selenium/driver_factory.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/galaxy_selenium/driver_factory.py b/test/galaxy_selenium/driver_factory.py index 1e9b729225c..cb9a1833ae7 100644 --- a/test/galaxy_selenium/driver_factory.py +++ b/test/galaxy_selenium/driver_factory.py @@ -6,6 +6,7 @@ except ImportError: Display = None from selenium import webdriver +from selenium.webdriver.chrome.options import Options as ChromeOptions from selenium.webdriver.common.desired_capabilities import DesiredCapabilities @@ -32,7 +33,12 @@ def get_local_driver(browser=DEFAULT_BROWSER): "PHANTOMJS": webdriver.PhantomJS, } driver_class = driver_to_class[browser] - return driver_class(desired_capabilities={"loggingPrefs": LOGGING_PREFS}) + if browser == 'CHROME': + options = ChromeOptions() + options.add_argument('--headless') + return driver_class(desired_capabilities={"loggingPrefs": LOGGING_PREFS}, chrome_options=options) + else: + return driver_class(desired_capabilities={"loggingPrefs": LOGGING_PREFS}) def get_remote_driver( From 78c66f260c4bad5b2d632919fe14307602c8fb4e Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Fri, 1 Feb 2019 13:49:07 -0500 Subject: [PATCH 3/5] Wait for logout redirect. --- test/galaxy_selenium/navigates_galaxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/galaxy_selenium/navigates_galaxy.py b/test/galaxy_selenium/navigates_galaxy.py index 04ef23be115..ee9e3f11b14 100644 --- a/test/galaxy_selenium/navigates_galaxy.py +++ b/test/galaxy_selenium/navigates_galaxy.py @@ -1259,7 +1259,7 @@ class NavigatesGalaxy(HasDriver): self.home() self.click_masthead_user() self.wait_for_and_click(self.navigation.masthead.labels.logout) - self.click_label('go to the home page') + self.sleep_for(WAIT_TYPES.UX_TRANSITION) assert not self.is_logged_in() def run_tour(self, path, skip_steps=None, sleep_on_steps=None, tour_callback=None): From 9e879b731f27d7b17161c83a60ef559aa529ec63 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Fri, 1 Feb 2019 13:50:23 -0500 Subject: [PATCH 4/5] Drop now unused slowrender --- test/galaxy_selenium/navigates_galaxy.py | 2 -- test/selenium_tests/test_custom_builds.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/test/galaxy_selenium/navigates_galaxy.py b/test/galaxy_selenium/navigates_galaxy.py index ee9e3f11b14..f3bc993bf91 100644 --- a/test/galaxy_selenium/navigates_galaxy.py +++ b/test/galaxy_selenium/navigates_galaxy.py @@ -40,8 +40,6 @@ WaitType = collections.namedtuple("WaitType", ["name", "default_length"]) WAIT_TYPES = Bunch( # Rendering a form and registering callbacks, etc... UX_RENDER=WaitType("ux_render", 1), - # TODO: Track down and fix all of these. - UX_SLOW_RENDER=WaitType("ux_slow_render", 3), # Fade in, fade out, etc... UX_TRANSITION=WaitType("ux_transition", 5), # Toastr popup and dismissal, etc... diff --git a/test/selenium_tests/test_custom_builds.py b/test/selenium_tests/test_custom_builds.py index 7e17fe691e9..c678540381a 100644 --- a/test/selenium_tests/test_custom_builds.py +++ b/test/selenium_tests/test_custom_builds.py @@ -79,7 +79,7 @@ class CustomBuildsTestcase(SharedStateSeleniumTestCase): delete_button.click() def get_custom_builds(self): - self.sleep_for(self.wait_types.UX_TRANSITION) + self.sleep_for(self.wait_types.UX_RENDER) builds = [] grid = self.wait_for_selector('table.grid > tbody') for row in grid.find_elements_by_tag_name('tr'): From 817a8469b69e37c48e72a081a75d5c734e636624 Mon Sep 17 00:00:00 2001 From: Dannon Baker Date: Mon, 4 Feb 2019 09:39:51 -0500 Subject: [PATCH 5/5] Tie chrome native headless mode into existing HEADLESS logic, functioning with or without pyvirtualdisplay. --- test/galaxy_selenium/cli.py | 2 +- test/galaxy_selenium/driver_factory.py | 11 +++++++---- test/selenium_tests/framework.py | 22 +++++++++++++++++++--- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/test/galaxy_selenium/cli.py b/test/galaxy_selenium/cli.py index 93048dc26dc..e46a6f3a32a 100644 --- a/test/galaxy_selenium/cli.py +++ b/test/galaxy_selenium/cli.py @@ -3,7 +3,7 @@ BROWSER_DESCRIPTION = "Use specific browser for selenium (e.g. firefox or chrome REMOTE_HOST_DESCRIPTION = "Selenium hub remote host to use (if remote driver in use)." REMOTE_PORT_DESCRIPTION = "Selenium hub remote port to use (if remote driver in use)." GALAXY_URL_DESCRIPTION = "URL of Galaxy instance to target." -HEADLESS_DESCRIPTION = "Use local selenium headlessly (requires pyvirtualdisplay)." +HEADLESS_DESCRIPTION = "Use local selenium headlessly (native in chrome, otherwise this requires pyvirtualdisplay)." from six.moves.urllib.parse import urljoin diff --git a/test/galaxy_selenium/driver_factory.py b/test/galaxy_selenium/driver_factory.py index cb9a1833ae7..8ddb0cd4953 100644 --- a/test/galaxy_selenium/driver_factory.py +++ b/test/galaxy_selenium/driver_factory.py @@ -16,15 +16,18 @@ LOGGING_PREFS = { } -def get_local_driver(browser=DEFAULT_BROWSER): +def get_local_browser(browser): if browser == "auto": if _which("chromedriver"): - browser = "CHROME" + return "CHROME" elif _which("geckodriver"): - browser = "FIREFOX" + return "FIREFOX" else: raise Exception("Selenium browser is 'auto' but neither geckodriver or chromedriver are found on PATH.") + +def get_local_driver(browser=DEFAULT_BROWSER, headless=False): + browser = get_local_browser(browser) assert browser in ["CHROME", "FIREFOX", "OPERA", "PHANTOMJS"] driver_to_class = { "CHROME": webdriver.Chrome, @@ -33,7 +36,7 @@ def get_local_driver(browser=DEFAULT_BROWSER): "PHANTOMJS": webdriver.PhantomJS, } driver_class = driver_to_class[browser] - if browser == 'CHROME': + if browser == 'CHROME' and headless: options = ChromeOptions() options.add_argument('--headless') return driver_class(desired_capabilities={"loggingPrefs": LOGGING_PREFS}, chrome_options=options) diff --git a/test/selenium_tests/framework.py b/test/selenium_tests/framework.py index d0166dcd846..480b9e801d8 100644 --- a/test/selenium_tests/framework.py +++ b/test/selenium_tests/framework.py @@ -287,7 +287,7 @@ class SeleniumTestCase(FunctionalTestCase, NavigatesGalaxy, UsesApiTestCaseMixin self._try_setup_with_driver() def setup_driver_and_session(self): - self.display = driver_factory.virtual_display_if_enabled(headless_selenium()) + self.display = driver_factory.virtual_display_if_enabled(use_virtual_display()) self.driver = get_driver() # New workflow index page does not degrade well to smaller sizes, needed # to increase this. @@ -488,7 +488,20 @@ def headless_selenium(): return False if GALAXY_TEST_SELENIUM_HEADLESS == "auto": - if driver_factory.is_virtual_display_available(): + if driver_factory.is_virtual_display_available() or driver_factory.get_local_browser(GALAXY_TEST_SELENIUM_BROWSER) == "CHROME": + return True + else: + return False + else: + return asbool(GALAXY_TEST_SELENIUM_HEADLESS) + + +def use_virtual_display(): + if asbool(GALAXY_TEST_SELENIUM_REMOTE): + return False + + if GALAXY_TEST_SELENIUM_HEADLESS == "auto": + if driver_factory.is_virtual_display_available() and not driver_factory.get_local_browser(GALAXY_TEST_SELENIUM_BROWSER) == "CHROME": return True else: return False @@ -497,7 +510,10 @@ def headless_selenium(): def get_local_driver(): - return driver_factory.get_local_driver(GALAXY_TEST_SELENIUM_BROWSER) + return driver_factory.get_local_driver( + GALAXY_TEST_SELENIUM_BROWSER, + headless_selenium() + ) def get_remote_driver():