Skip to content

Commit

Permalink
Try to workaround specific WebDriverException (#154)
Browse files Browse the repository at this point in the history
If the WebDriverException is caused by "Expected to read
a START_MAP but instead have: END. Last 0 characters read"
lets ignore it and try again.

If the TimeoutException is caused by "Unable to execute
request for an existing session: java.util.concurrent.TimeoutException"
lets ignore it and try again.
  • Loading branch information
ljelinkova authored May 19, 2022
1 parent 922766b commit 1dcbf29
Showing 1 changed file with 59 additions and 7 deletions.
66 changes: 59 additions & 7 deletions ost_utils/selenium/navigation/driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from selenium.common.exceptions import (
NoSuchElementException,
StaleElementReferenceException,
TimeoutException,
WebDriverException,
)
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
Expand Down Expand Up @@ -123,7 +125,9 @@ def wait_long_while(self, message, condition_method, *args):
self._wait_while(message, assert_utils.LONG_TIMEOUT, condition_method, *args)

def _wait_while(self, message, timeout, condition_method, *args):
WebDriverWait(self.driver, timeout).until_not(ConditionClass(condition_method, *args), message)
WebDriverWait(self.driver, timeout, ignored_exceptions=[TimeoutException]).until_not(
ConditionClass(condition_method, *args), message
)

def retry_if_stale(self, method_to_retry, *args):
condition = StaleExceptionOccurredCondition(method_to_retry, *args)
Expand All @@ -139,9 +143,21 @@ class ConditionClass:
def __init__(self, condition_method, *args):
self.condition_method = condition_method
self.args = args
self.retry = 0

def __call__(self, driver):
return self.condition_method(*self.args)
self.retry += 1

try:
return self.condition_method(*self.args)
# Stating it here to avoid logging it
except NoSuchElementException as e:
raise e
except Exception as e:
LOGGER.exception(
'!!!ConditionClass failed with ' + e.__class__.__name__ + ' at retry number ' + str(self.retry)
)
raise e


class StaleExceptionOccurredCondition:
Expand All @@ -150,16 +166,52 @@ def __init__(self, method_to_execute, *args):
self.args = args
self.result = None
self.error = None
self.retry = 0

def __call__(self, driver):
shouldRunAgain = False
try:
self.retry += 1
self.result = self.method_to_execute(*self.args)
return False
# ignore StaleElementReferenceException and try again
except StaleElementReferenceException:
return True
# throw any other exception, even NoSuchElementException ignored
# by WebDriverWait by default
shouldRunAgain = True
# ignore TimeoutException if caused by timeout in java
except TimeoutException as e:
LOGGER.exception(
'!!!StaleExceptionOccurredCondition failed with '
+ e.__class__.__name__
+ ' at retry number '
+ str(self.retry)
)
if 'java.util.concurrent.TimeoutException' in str(e):
shouldRunAgain = True
else:
self.error = e
# stating it here just to avoid logging this expected condition or processing it as
# WebDriverException
except NoSuchElementException as e:
self.error = e
# ignore WebDriverException if caused by the following: Expected to read a START_MAP but instead have: END.
# Last 0 characters read:
except WebDriverException as e:
LOGGER.exception(
'!!!StaleExceptionOccurredCondition failed with '
+ e.__class__.__name__
+ ' at retry number '
+ str(self.retry)
)
if 'START_MAP' in str(e):
shouldRunAgain = True
else:
self.error = e
except Exception as e:
LOGGER.exception(
'!!!StaleExceptionOccurredCondition failed with '
+ e.__class__.__name__
+ ' at retry number '
+ str(self.retry)
)

self.error = e
return False
return shouldRunAgain

0 comments on commit 1dcbf29

Please sign in to comment.