Skip to content

Commit

Permalink
Fix alerts on chrome (robotframework#661)
Browse files Browse the repository at this point in the history
* Improves alert hadling for Chrome (robotframework#652)

In Chrome is often a random WebDriverException which caused
by unknow reson. This commit creates a retry functionality
that improves alert handling for Crome.

Fixes robotframework#652

* Refactored the code to simplify the logic

* Changed class attribute to better describe what it does

* Updates alert handling based on the comment review

* Changed class atributes names to describe better what they do

* Fixed based on the comments
  • Loading branch information
aaltat authored and Gaurang033 committed Oct 14, 2016
1 parent 3f578e7 commit 3b7c14f
Showing 1 changed file with 41 additions and 37 deletions.
78 changes: 41 additions & 37 deletions src/Selenium2Library/keywords/_alert.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import time
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
Expand All @@ -6,14 +7,16 @@

class _AlertKeywords(KeywordGroup):

__ACCEPT_ALERT = 'accept'
__DISMISS_ALERT = 'dismiss'

def __init__(self):
self._cancel_on_next_confirmation = False
self._next_alert_dismiss_type = self.__ACCEPT_ALERT

# Public

def input_text_into_prompt(self, text):
"""Types the given `text` into alert box. """
alert = None
try:
alert = self._wait_alert()
alert.send_keys(text)
Expand All @@ -30,15 +33,15 @@ def alert_should_be_present(self, text=''):
will fail unless the alert is dismissed by this
keyword or another like `Get Alert Message`.
"""
alert_text = self.get_alert_message()
alert_text = self._handle_alert(self.__ACCEPT_ALERT)
if text and alert_text != text:
raise AssertionError("Alert text should have been "
"'%s' but was '%s'"
% (text, alert_text))

def choose_cancel_on_next_confirmation(self):
"""Cancel will be selected the next time `Confirm Action` is used."""
self._cancel_on_next_confirmation = True
self._next_alert_dismiss_type = self.__DISMISS_ALERT

def choose_ok_on_next_confirmation(self):
"""Undo the effect of using keywords `Choose Cancel On Next Confirmation`. Note
Expand All @@ -55,7 +58,7 @@ def choose_ok_on_next_confirmation(self):
consume it by using a keywords such as `Get Alert Message`, or else
the following selenium operations will fail.
"""
self._cancel_on_next_confirmation = False
self._next_alert_dismiss_type = self.__ACCEPT_ALERT

def confirm_action(self):
"""Dismisses currently shown confirmation dialog and returns it's message.
Expand All @@ -74,8 +77,8 @@ def confirm_action(self):
| Click Button | Send | # Shows a confirmation dialog |
| Confirm Action | | # Chooses Cancel |
"""
text = self._close_alert(not self._cancel_on_next_confirmation)
self._cancel_on_next_confirmation = False
text = self._handle_alert(self._next_alert_dismiss_type)
self._next_alert_dismiss_type = self.__DISMISS_ALERT
return text

def get_alert_message(self, dismiss=True):
Expand All @@ -87,9 +90,9 @@ def get_alert_message(self, dismiss=True):
dismissed by this keyword or another like `Get Alert Message`.
"""
if dismiss:
return self._close_alert()
return self._handle_alert(self.__DISMISS_ALERT)
else:
return self._read_alert()
return self._handle_alert()

def dismiss_alert(self, accept=True):
""" Returns true if alert was confirmed, false if it was dismissed
Expand All @@ -98,38 +101,39 @@ def dismiss_alert(self, accept=True):
following keywords will fail unless the alert is
dismissed by this keyword or another like `Get Alert Message`.
"""
return self._handle_alert(accept)
if accept:
return self._handle_alert(self.__ACCEPT_ALERT)
else:
return self._handle_alert()

# Private
def _handle_alert(self, dismiss_type=None):
"""Alert re-try for Chrome
def _close_alert(self, confirm=True):
try:
text = self._read_alert()
self._handle_alert(confirm)
return text
except WebDriverException:
raise RuntimeError('There were no alerts')
Because Chrome has difficulties to handle alerts, like::
def _read_alert(self):
alert = None
try:
alert = self._wait_alert()
# collapse new lines chars
return ' '.join(alert.text.splitlines())
except WebDriverException:
raise RuntimeError('There were no alerts')
alert.text
alert.dismiss
def _handle_alert(self, confirm=True):
try:
alert = self._wait_alert()
if not confirm:
alert.dismiss()
return False
else:
alert.accept()
return True
except WebDriverException:
raise RuntimeError('There were no alerts')
This function creates a re-try funtionality to better support
alerts in Chrome.
"""
retry = 0
while retry < 4:
try:
return self._alert_worker(dismiss_type)
except WebDriverException:
time.sleep(0.2)
retry += 1
raise RuntimeError('There were no alerts')

def _alert_worker(self, dismiss_type=None):
alert = self._wait_alert()
text = ' '.join(alert.text.splitlines())
if dismiss_type == self.__DISMISS_ALERT:
alert.dismiss()
elif dismiss_type == self.__ACCEPT_ALERT:
alert.accept()
return text

def _wait_alert(self):
return WebDriverWait(self._current_browser(), 1).until(
Expand Down

0 comments on commit 3b7c14f

Please sign in to comment.