Merge "Fix longtime tests" into stable/mitaka
This commit is contained in:
commit
26734a0d5f
|
@ -19,16 +19,9 @@
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class ElementNotReloadableException(Exception):
|
|
||||||
"""Raised when reload is not possible."""
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
from selenium.common import exceptions
|
from selenium.common import exceptions
|
||||||
from selenium.webdriver.common import by
|
from selenium.webdriver.common import by
|
||||||
from selenium.webdriver.common import desired_capabilities as dc
|
from selenium.webdriver.common import desired_capabilities as dc
|
||||||
|
@ -72,32 +65,15 @@ class WebElementWrapper(WrapperFindOverride, webelement.WebElement):
|
||||||
actualStaleElementReferenceException is raised.
|
actualStaleElementReferenceException is raised.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
STALE_ELEMENT_REFERENCE_WAIT = 0.5
|
|
||||||
STALE_ELEMENT_REFERENCE_MAX_TRY = 10
|
|
||||||
|
|
||||||
def __init__(self, parent, id_, locator, src_element, index=None):
|
def __init__(self, parent, id_, locator, src_element, index=None):
|
||||||
super(WebElementWrapper, self).__init__(parent, id_)
|
super(WebElementWrapper, self).__init__(parent, id_)
|
||||||
self.locator = locator
|
self.locator = locator
|
||||||
self.src_element = src_element
|
self.src_element = src_element
|
||||||
|
|
||||||
# StaleElementReferenceException occurrence counter
|
|
||||||
self.stale_reference_occurrence = 0
|
|
||||||
|
|
||||||
# storing if web element reload succeed or not
|
|
||||||
# in case of fail StaleElementReferenceException is raised
|
|
||||||
self.reload_failed = False
|
|
||||||
|
|
||||||
# in case element was looked up previously via find_elements
|
# in case element was looked up previously via find_elements
|
||||||
# we need his position in the returned list
|
# we need his position in the returned list
|
||||||
self.index = index
|
self.index = index
|
||||||
|
|
||||||
# if reloading of some other web element is in progress
|
|
||||||
# StaleElementReferenceException is not raised within current
|
|
||||||
# context
|
|
||||||
self.web_element_reload = False
|
|
||||||
|
|
||||||
def reload_request(self, locator, index=None):
|
def reload_request(self, locator, index=None):
|
||||||
self.web_element_reload = True
|
|
||||||
try:
|
try:
|
||||||
# element was found out via find_elements
|
# element was found out via find_elements
|
||||||
if index is not None:
|
if index is not None:
|
||||||
|
@ -107,64 +83,32 @@ class WebElementWrapper(WrapperFindOverride, webelement.WebElement):
|
||||||
web_el = self.src_element.find_element(*locator)
|
web_el = self.src_element.find_element(*locator)
|
||||||
except (exceptions.NoSuchElementException, IndexError):
|
except (exceptions.NoSuchElementException, IndexError):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.web_element_reload = False
|
|
||||||
return web_el
|
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)
|
||||||
if not web_el:
|
if not web_el:
|
||||||
return
|
return False
|
||||||
self._parent = web_el.parent
|
self._parent = web_el.parent
|
||||||
self._id = web_el.id
|
self._id = web_el.id
|
||||||
|
return True
|
||||||
|
|
||||||
def _execute(self, command, params=None):
|
def _execute(self, command, params=None):
|
||||||
"""Overriding in order to catch StaleElementReferenceException."""
|
"""Overriding in order to catch StaleElementReferenceException."""
|
||||||
result = None
|
# (schipiga): not need to use while True, trying to catch StaleElement
|
||||||
while True:
|
# 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)
|
||||||
|
for i in repeat:
|
||||||
try:
|
try:
|
||||||
result = super(WebElementWrapper, self)._execute(command,
|
return super(WebElementWrapper, self)._execute(command, params)
|
||||||
params)
|
|
||||||
break
|
|
||||||
except exceptions.StaleElementReferenceException:
|
except exceptions.StaleElementReferenceException:
|
||||||
|
if i == repeat[-1]:
|
||||||
# in case we reach the limit
|
raise
|
||||||
# STALE_ELEMENT_REFERENCE_MAX_TRY
|
if not self._reload_element():
|
||||||
# it is very probable that it is programmer fault
|
|
||||||
if self.reload_failed or self.stale_reference_occurrence \
|
|
||||||
> self.STALE_ELEMENT_REFERENCE_MAX_TRY:
|
|
||||||
raise
|
raise
|
||||||
|
|
||||||
# this is either programmer fault (bad logic in accessing
|
|
||||||
# elements) or web page content is been loaded via ajax,
|
|
||||||
# let's go with the second one and wait
|
|
||||||
# STALE_ELEMENT_REFERENCE_WAIT till the assumed page
|
|
||||||
# content is loaded and try to execute the whole process
|
|
||||||
# STALE_ELEMENT_REFERENCE_MAX_TRY times in case of failures
|
|
||||||
time.sleep(self.STALE_ELEMENT_REFERENCE_WAIT)
|
|
||||||
|
|
||||||
# try to reload the web element if result is false it
|
|
||||||
# means that request has gone to the driver and he did not
|
|
||||||
# find the element -> must be programmer fault, because it
|
|
||||||
# seems we are on entirely different page
|
|
||||||
try:
|
|
||||||
self._reload_element()
|
|
||||||
except ElementNotReloadableException:
|
|
||||||
|
|
||||||
# In case this element was responsible only for loading
|
|
||||||
# some other element raise the exception further
|
|
||||||
if self.web_element_reload:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
self.reload_failed = True
|
|
||||||
|
|
||||||
# increment occurrences
|
|
||||||
self.stale_reference_occurrence += 1
|
|
||||||
|
|
||||||
# reset counter
|
|
||||||
self.stale_reference_occurrence = 0
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
class WebDriverWrapper(WrapperFindOverride, WebDriver):
|
class WebDriverWrapper(WrapperFindOverride, WebDriver):
|
||||||
|
@ -180,4 +124,4 @@ class WebDriverWrapper(WrapperFindOverride, WebDriver):
|
||||||
web_el = self.find_element(*locator)
|
web_el = self.find_element(*locator)
|
||||||
return web_el
|
return web_el
|
||||||
except (exceptions.NoSuchElementException, IndexError):
|
except (exceptions.NoSuchElementException, IndexError):
|
||||||
raise ElementNotReloadableException()
|
return False
|
||||||
|
|
|
@ -81,7 +81,7 @@ class BaseWebObject(unittest.TestCase):
|
||||||
self.driver.implicitly_wait(0)
|
self.driver.implicitly_wait(0)
|
||||||
|
|
||||||
def _turn_on_implicit_wait(self):
|
def _turn_on_implicit_wait(self):
|
||||||
self.driver.implicitly_wait(self.conf.selenium.page_timeout)
|
self.driver.implicitly_wait(self.conf.selenium.implicit_wait)
|
||||||
|
|
||||||
def _wait_until(self, predicate, timeout=None, poll_frequency=0.5):
|
def _wait_until(self, predicate, timeout=None, poll_frequency=0.5):
|
||||||
"""Wait until the value returned by predicate is not False or
|
"""Wait until the value returned by predicate is not False or
|
||||||
|
|
Loading…
Reference in New Issue