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
This commit is contained in:
parent
712bbe1fa5
commit
78e382c3a5
@ -37,12 +37,26 @@ class WrapperFindOverride(object):
|
|||||||
"""Mixin for overriding find_element methods."""
|
"""Mixin for overriding find_element methods."""
|
||||||
|
|
||||||
def find_element(self, by=by.By.ID, value=None):
|
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),
|
return WebElementWrapper(web_el.parent, web_el.id, (by, value),
|
||||||
self)
|
self)
|
||||||
|
|
||||||
def find_elements(self, by=by.By.ID, value=None):
|
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 = []
|
result = []
|
||||||
for index, web_el in enumerate(web_els):
|
for index, web_el in enumerate(web_els):
|
||||||
result.append(WebElementWrapper(web_el.parent, web_el.id,
|
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
|
# we need his position in the returned list
|
||||||
self.index = index
|
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):
|
def _reload_element(self):
|
||||||
"""Method for starting reload process on current instance."""
|
"""Method for starting reload process on current instance."""
|
||||||
web_el = self.src_element.reload_request(self.locator, self.index)
|
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.
|
# exception, because driver.implicitly_wait delegates this to browser.
|
||||||
# Just we need to catch StaleElement exception, reload chain of element
|
# Just we need to catch StaleElement exception, reload chain of element
|
||||||
# parents and then to execute command again.
|
# parents and then to execute command again.
|
||||||
repeat = range(2)
|
repeat = range(20)
|
||||||
for i in repeat:
|
for i in repeat:
|
||||||
try:
|
try:
|
||||||
return super(WebElementWrapper, self)._execute(command, params)
|
return super(WebElementWrapper, self)._execute(command, params)
|
||||||
except exceptions.StaleElementReferenceException:
|
except (exceptions.StaleElementReferenceException,
|
||||||
|
exceptions.ElementClickInterceptedException):
|
||||||
if i == repeat[-1]:
|
if i == repeat[-1]:
|
||||||
raise
|
raise
|
||||||
if not self._reload_element():
|
if not self._reload_element():
|
||||||
|
@ -84,6 +84,9 @@ AvailableServiceGroup = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
SeleniumGroup = [
|
SeleniumGroup = [
|
||||||
|
cfg.FloatOpt('message_implicit_wait',
|
||||||
|
default=0.1,
|
||||||
|
help="Time to wait for confirmation modal in seconds"),
|
||||||
cfg.IntOpt('implicit_wait',
|
cfg.IntOpt('implicit_wait',
|
||||||
default=10,
|
default=10,
|
||||||
help="Implicit wait timeout in seconds"),
|
help="Implicit wait timeout in seconds"),
|
||||||
|
@ -10,6 +10,10 @@ dashboard_url=http://localhost/dashboard/
|
|||||||
help_url=https://docs.openstack.org/
|
help_url=https://docs.openstack.org/
|
||||||
|
|
||||||
[selenium]
|
[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
|
# Timeout in seconds to wait for a page to become available
|
||||||
# (integer value)
|
# (integer value)
|
||||||
page_timeout=60
|
page_timeout=60
|
||||||
|
@ -28,9 +28,9 @@ class MessageRegion(baseregion.BaseRegion):
|
|||||||
|
|
||||||
def __init__(self, driver, conf, level=SUCCESS):
|
def __init__(self, driver, conf, level=SUCCESS):
|
||||||
self._default_src_locator = self._msg_locator(level)
|
self._default_src_locator = self._msg_locator(level)
|
||||||
# NOTE(tsufiev): we cannot use self._turn_off_implicit_wait() at this
|
# NOTE(nhelgeson): Running selenium on remote servers
|
||||||
# point, because the instance is not initialized by ancestor's __init__
|
# requires extra time to wait for message to pop up.
|
||||||
driver.implicitly_wait(0.1)
|
driver.implicitly_wait(conf.selenium.message_implicit_wait)
|
||||||
try:
|
try:
|
||||||
super(MessageRegion, self).__init__(driver, conf)
|
super(MessageRegion, self).__init__(driver, conf)
|
||||||
except NoSuchElementException:
|
except NoSuchElementException:
|
||||||
|
Loading…
Reference in New Issue
Block a user