From 78e382c3a5e84fa838d1ede8c49bab515150a7dd Mon Sep 17 00:00:00 2001 From: nicolas Date: Mon, 28 Jan 2019 14:45:43 -0800 Subject: [PATCH] Selenium tests fail when response is slow. Increased implicit wait on message pop ups. Gives time for slow connections to wait for message. Find_elements retry. Gives an additional opportuninty for elements to be found. Additional attempts for _execute gives time for elements to move or dissapear when collision is a problem. Change-Id: I94670628c179f7291162f2c25947673f03106fc2 Closes-Bug: #1813670 --- horizon/test/webdriver.py | 35 ++++++++++--------- .../test/integration_tests/config.py | 3 ++ .../test/integration_tests/horizon.conf | 4 +++ .../integration_tests/regions/messages.py | 6 ++-- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/horizon/test/webdriver.py b/horizon/test/webdriver.py index d235249999..1049cbdd65 100644 --- a/horizon/test/webdriver.py +++ b/horizon/test/webdriver.py @@ -37,12 +37,26 @@ class WrapperFindOverride(object): """Mixin for overriding find_element methods.""" def find_element(self, by=by.By.ID, value=None): - web_el = super(WrapperFindOverride, self).find_element(by, value) + repeat = range(2) + for i in repeat: + try: + web_el = super(WrapperFindOverride, self).find_element( + by, value) + except exceptions.NoSuchElementException: + if i == repeat[-1]: + raise return WebElementWrapper(web_el.parent, web_el.id, (by, value), self) def find_elements(self, by=by.By.ID, value=None): - web_els = super(WrapperFindOverride, self).find_elements(by, value) + repeat = range(2) + for i in repeat: + try: + web_els = super(WrapperFindOverride, self).find_elements( + by, value) + except exceptions.NoSuchElementException: + if i == repeat[-1]: + raise result = [] for index, web_el in enumerate(web_els): result.append(WebElementWrapper(web_el.parent, web_el.id, @@ -70,18 +84,6 @@ class WebElementWrapper(WrapperFindOverride, webelement.WebElement): # we need his position in the returned list self.index = index - def reload_request(self, locator, index=None): - try: - # element was found out via find_elements - if index is not None: - web_els = self.src_element.find_elements(*locator) - web_el = web_els[index] - else: - web_el = self.src_element.find_element(*locator) - except (exceptions.NoSuchElementException, IndexError): - return False - return web_el - def _reload_element(self): """Method for starting reload process on current instance.""" web_el = self.src_element.reload_request(self.locator, self.index) @@ -97,11 +99,12 @@ class WebElementWrapper(WrapperFindOverride, webelement.WebElement): # exception, because driver.implicitly_wait delegates this to browser. # Just we need to catch StaleElement exception, reload chain of element # parents and then to execute command again. - repeat = range(2) + repeat = range(20) for i in repeat: try: return super(WebElementWrapper, self)._execute(command, params) - except exceptions.StaleElementReferenceException: + except (exceptions.StaleElementReferenceException, + exceptions.ElementClickInterceptedException): if i == repeat[-1]: raise if not self._reload_element(): diff --git a/openstack_dashboard/test/integration_tests/config.py b/openstack_dashboard/test/integration_tests/config.py index b2f402e4f6..52c68ecdd0 100644 --- a/openstack_dashboard/test/integration_tests/config.py +++ b/openstack_dashboard/test/integration_tests/config.py @@ -84,6 +84,9 @@ AvailableServiceGroup = [ ] SeleniumGroup = [ + cfg.FloatOpt('message_implicit_wait', + default=0.1, + help="Time to wait for confirmation modal in seconds"), cfg.IntOpt('implicit_wait', default=10, help="Implicit wait timeout in seconds"), diff --git a/openstack_dashboard/test/integration_tests/horizon.conf b/openstack_dashboard/test/integration_tests/horizon.conf index f4c9beb94b..5b938cbf56 100644 --- a/openstack_dashboard/test/integration_tests/horizon.conf +++ b/openstack_dashboard/test/integration_tests/horizon.conf @@ -10,6 +10,10 @@ dashboard_url=http://localhost/dashboard/ help_url=https://docs.openstack.org/ [selenium] +# Timeout in seconds to wait for message confirmation modal +# (float value) +message_implicit_wait=0.1 + # Timeout in seconds to wait for a page to become available # (integer value) page_timeout=60 diff --git a/openstack_dashboard/test/integration_tests/regions/messages.py b/openstack_dashboard/test/integration_tests/regions/messages.py index 2d46a1fdf4..aac86f4562 100644 --- a/openstack_dashboard/test/integration_tests/regions/messages.py +++ b/openstack_dashboard/test/integration_tests/regions/messages.py @@ -28,9 +28,9 @@ class MessageRegion(baseregion.BaseRegion): def __init__(self, driver, conf, level=SUCCESS): self._default_src_locator = self._msg_locator(level) - # NOTE(tsufiev): we cannot use self._turn_off_implicit_wait() at this - # point, because the instance is not initialized by ancestor's __init__ - driver.implicitly_wait(0.1) + # NOTE(nhelgeson): Running selenium on remote servers + # requires extra time to wait for message to pop up. + driver.implicitly_wait(conf.selenium.message_implicit_wait) try: super(MessageRegion, self).__init__(driver, conf) except NoSuchElementException: