diff --git a/.travis.yml b/.travis.yml index a6d96d2d3..7e1299ec1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,13 +35,13 @@ matrix: - BROWSER=chrome - SELENIUM=3.5.0 - ROBOTFRAMEWORK=3.0.2 - - ROBOT_OPTIONS= + - ROBOT_OPTIONS=--dotted - python: "2.7" env: - BROWSER=chrome - SELENIUM=2.53.6 - ROBOTFRAMEWORK=2.9.2 - - ROBOT_OPTIONS= + - ROBOT_OPTIONS=--dotted - python: "2.7" env: - BROWSER=chrome @@ -53,13 +53,13 @@ matrix: - BROWSER=chrome - SELENIUM=2.53.6 - ROBOTFRAMEWORK=3.0.2 - - ROBOT_OPTIONS= + - ROBOT_OPTIONS=--dotted - python: "3.3" env: - BROWSER=firefox - SELENIUM=3.5.0 - ROBOTFRAMEWORK=3.0.2 - - ROBOT_OPTIONS="--exclude Known_Issue_Firefox" + - ROBOT_OPTIONS="--exclude Known_Issue_Firefox --dotted" before_script: - "export DISPLAY=:99.0" - "sh -e /etc/init.d/xvfb start" diff --git a/src/SeleniumLibrary/__init__.py b/src/SeleniumLibrary/__init__.py index 25ed77023..1a7f13cb8 100644 --- a/src/SeleniumLibrary/__init__.py +++ b/src/SeleniumLibrary/__init__.py @@ -210,17 +210,17 @@ class SeleniumLibrary(DynamicCore): It also explains the `time format` that can be used when setting various timeouts, waits and delays. - == Timeouts == + == Timeout == - SeleniumLibrary contains various ``Wait ...`` keywords that can be used - to wait, for example, for a dynamically created elements to appear on - a page. All these keywords accept an optional ``timeout`` argument that - tells the maximum time to wait. + SeleniumLibrary contains various keywords that have an optional + ``timeout`` argument that specifies how long these keywords should + wait for certain events or actions. These keywords include, for example, + ``Wait ...`` keywords and keywords related to alerts. The default timeout these keywords use can be set globally either by using the `Set Selenium Timeout` keyword or with the ``timeout`` argument - when `importing` the library. The same timeout also applies to the - `Execute Async Javascript` keyword. + when `importing` the library. See `time format` below for supported + timeout syntax. == Implicit wait == @@ -230,6 +230,8 @@ class SeleniumLibrary(DynamicCore): the library. See [http://seleniumhq.org/docs/04_webdriver_advanced.html| Selenium documentation] for more information about this functionality. + See `time format` below for supported syntax. + == Selenium speed == Selenium execution speed can be slowed down globally by using `Set @@ -238,6 +240,8 @@ class SeleniumLibrary(DynamicCore): appear on a page is not a good idea, and the above explained timeouts and waits should be used instead. + See `time format` below for supported syntax. + == Time format == All timeouts and waits can be given as numbers considered seconds diff --git a/src/SeleniumLibrary/base/librarycomponent.py b/src/SeleniumLibrary/base/librarycomponent.py index b51ef3831..1273fe366 100644 --- a/src/SeleniumLibrary/base/librarycomponent.py +++ b/src/SeleniumLibrary/base/librarycomponent.py @@ -19,6 +19,8 @@ from robot.api import logger from robot.libraries.BuiltIn import BuiltIn, RobotNotRunningError +from SeleniumLibrary.utils import is_noney, timestr_to_secs + from .context import ContextAware from .robotlibcore import PY2 @@ -54,6 +56,11 @@ def assert_page_not_contains(self, locator, tag=None, message=None, self.element_finder.assert_page_not_contains(locator, tag, message, loglevel) + def get_timeout(self, timeout=None): + if is_noney(timeout): + return self.ctx.timeout + return timestr_to_secs(timeout) + @property def log_dir(self): try: diff --git a/src/SeleniumLibrary/keywords/alert.py b/src/SeleniumLibrary/keywords/alert.py index fe45a6247..f64ab5c35 100644 --- a/src/SeleniumLibrary/keywords/alert.py +++ b/src/SeleniumLibrary/keywords/alert.py @@ -14,152 +14,202 @@ # See the License for the specific language governing permissions and # limitations under the License. -import time - from selenium.common.exceptions import WebDriverException from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.ui import WebDriverWait -from SeleniumLibrary.base import keyword -from SeleniumLibrary.base import LibraryComponent -from SeleniumLibrary.utils import is_truthy +from SeleniumLibrary.base import keyword, LibraryComponent +from SeleniumLibrary.utils import is_truthy, secs_to_timestr, timestr_to_secs class AlertKeywords(LibraryComponent): + ACCEPT = 'ACCEPT' + DISMISS = 'DISMISS' + LEAVE = 'LEAVE' + _next_alert_action = ACCEPT - ACCEPT_ALERT = 'accept' - DISMISS_ALERT = 'dismiss' + @keyword + def input_text_into_prompt(self, text): + """Deprecated. Use `Input Text Into Alert` instead. - def __init__(self, ctx): - LibraryComponent.__init__(self, ctx) - self._next_alert_dismiss_type = self.ACCEPT_ALERT + Types the given ``text`` into an input field in an alert. + Leaves the alert open. + """ + self.input_text_into_alert(text, self.LEAVE) @keyword - def input_text_into_prompt(self, text): - """Types the given `text` into alert box. """ - try: - alert = self._wait_alert() - alert.send_keys(text) - except WebDriverException: - raise RuntimeError('There were no alerts') + def input_text_into_alert(self, text, action=ACCEPT, timeout=None): + """Types the given ``text`` into an input field in an alert. + + The alert is accepted by default, but that behavior can be controlled + by using the ``action`` argument same way as with `Handle Alert`. + + ``timeout`` specifies how long to wait for the alert to appear. + If it is not given, the global default `timeout` is used instead. + + New in SeleniumLibrary 3.0. + """ + alert = self._wait_alert(timeout) + alert.send_keys(text) + self._handle_alert(alert, action) + + @keyword + def alert_should_be_present(self, text='', action=ACCEPT, timeout=None): + """Verifies that an alert is present and, by default, accepts it. + + Fails if no alert is present. If ``text`` is a non-empty string, + then it is used to verify alert's message. The alert is accepted + by default, but that behavior can be controlled by using the + ``action`` argument same way as with `Handle Alert`. + + ``timeout`` specifies how long to wait for the alert to appear. + If it is not given, the global default `timeout` is used instead. + + ``action`` and ``timeout`` arguments are new in SeleniumLibrary 3.0. + In earlier versions the alert was always accepted and timeout was + hard coded to one second. + """ + message = self.handle_alert(action, timeout) + if text and text != message: + raise AssertionError("Alert message should have been '%s' but it " + "was '%s'." % (text, message)) @keyword - def alert_should_be_present(self, text=''): - """Verifies an alert is present and dismisses it. + def alert_should_not_be_present(self, action=ACCEPT, timeout=0): + """Verifies that no alert is present. - If `text` is a non-empty string, then it is also verified that the - message of the alert equals to `text`. + If the alert actually exists, the ``action`` argument determines + how it should be handled. By default the alert is accepted, but + it can be also dismissed or left open the same way as with the + `Handle Alert` keyword. - Will fail if no alert is present. Note that following keywords - will fail unless the alert is dismissed by this - keyword or another like `Get Alert Message`. + ``timeout`` specifies how long to wait for the alert to appear. + By default the alert is not waited at all, but a custom time can + be given if alert may be delayed. See the `time format` section + for information about the syntax. + + New in SeleniumLibrary 3.0. """ - 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)) + try: + alert = self._wait_alert(timeout) + except AssertionError: + return + text = self._handle_alert(alert, action) + raise AssertionError("Alert with message '%s' present." % text) @keyword def choose_cancel_on_next_confirmation(self): - """Cancel will be selected the next time `Confirm Action` is used.""" - self._next_alert_dismiss_type = self.DISMISS_ALERT + """Deprecated. Use `Handle Alert` directly instead. + + In versions prior to SeleniumLibrary 3.0, the alert handling + approach needed to be set separately before using the `Confirm + Action` keyword. New `Handle Alert` keyword accepts the action how + to handle the alert as a normal argument and should be used instead. + """ + self._next_alert_action = self.DISMISS @keyword def choose_ok_on_next_confirmation(self): - """Undo the effect of using keywords `Choose Cancel On Next Confirmation`. Note - that Selenium's overridden window.confirm() function will normally - automatically return true, as if the user had manually clicked OK, so - you shouldn't need to use this command unless for some reason you need - to change your mind prior to the next confirmation. After any - confirmation, Selenium will resume using the default behavior for - future confirmations, automatically returning true (OK) unless/until - you explicitly use `Choose Cancel On Next Confirmation` for each - confirmation. - - Note that every time a confirmation comes up, you must - consume it by using a keywords such as `Get Alert Message`, or else - the following selenium operations will fail. + """Deprecated. Use `Handle Alert` directly instead. + + In versions prior to SeleniumLibrary 3.0, the alert handling + approach needed to be set separately before using the `Confirm + Action` keyword. New `Handle Alert` keyword accepts the action how + to handle the alert as a normal argument and should be used instead. """ - self._next_alert_dismiss_type = self.ACCEPT_ALERT + self._next_alert_action = self.ACCEPT @keyword def confirm_action(self): - """Dismisses currently shown confirmation dialog and returns it's message. + """Deprecated. Use `Handle Alert` instead. - By default, this keyword chooses 'OK' option from the dialog. If - 'Cancel' needs to be chosen, keyword `Choose Cancel On Next - Confirmation` must be called before the action that causes the - confirmation dialog to be shown. - - Examples: - | Click Button | Send | # Shows a confirmation dialog | - | ${message}= | Confirm Action | # Chooses Ok | - | Should Be Equal | ${message} | Are your sure? | - | | | | - | Choose Cancel On Next Confirmation | | | - | Click Button | Send | # Shows a confirmation dialog | - | Confirm Action | | # Chooses Cancel | + By default accepts an alert, but this behavior can be altered + with `Choose Cancel On Next Confirmation` and `Choose Ok On Next + Confirmation` keywords. New `Handle Alert` keyword accepts the action + how to handle the alert as a normal argument and should be used + instead. """ - text = self._handle_alert(self._next_alert_dismiss_type) - self._next_alert_dismiss_type = self.DISMISS_ALERT + text = self.handle_alert(self._next_alert_action) + self._next_alert_action = self.ACCEPT return text @keyword def get_alert_message(self, dismiss=True): - """Returns the text of current JavaScript alert. + """Deprecated. Use `Handle Alert` instead. - By default the current JavaScript alert will be dismissed. - This keyword will fail if no alert is present. Note that - following keywords will fail unless the alert is - dismissed by this keyword or another like `Dismiss Alert`. + Returns the message the alert has. Dismisses the alert by default + (i.e. presses ``Cancel``) and setting ``dismiss`` to false leaves + the alert open. There is no support to accept the alert (i.e. to + press ``Ok``). + + `Handle Alert` has better support for controlling should the alert + be accepted, dismissed, or left open. """ - if is_truthy(dismiss): - return self._handle_alert(self.DISMISS_ALERT) - else: - return self._handle_alert() + action = self.DISMISS if is_truthy(dismiss) else self.LEAVE + return self.handle_alert(action) @keyword def dismiss_alert(self, accept=True): - """ Returns true if alert was confirmed, false if it was dismissed + """Deprecated. Use `Handle Alert` instead. + + Contrary to its name, this keyword accepts the alert by default + (i.e. presses ``Ok``). ``accept`` can be set to a false value + to dismiss the alert (i.e. to press ``Cancel``). - This keyword will fail if no alert is present. Note that - following keywords will fail unless the alert is - dismissed by this keyword or another like `Get Alert Message`. + `Handle Alert` has better support for controlling should the alert + be accepted, dismissed, or left open. """ if is_truthy(accept): - return self._handle_alert(self.ACCEPT_ALERT) - else: - return self._handle_alert() + self.handle_alert(self.ACCEPT) + return True + self.handle_alert(self.DISMISS) + return False - def _handle_alert(self, dismiss_type=None): - """Alert re-try for Chrome + @keyword + def handle_alert(self, action=ACCEPT, timeout=None): + """Handles the current alert and returns its message. + + By default the alert is accepted, but this can be controlled + with the ``action`` argument that supports the following + case-insensitive values: - Because Chrome has difficulties to handle alerts, like:: + - ``ACCEPT``: Accept the alert i.e. press ``Ok``. Default. + - ``DISMISS``: Dismiss the alert i.e. press ``Cancel``. + - ``LEAVE``: Leave the alert open. - alert.text - alert.dismiss + The ``timeout`` argument specifies how long to wait for the alert + to appear. If it is not given, the global default `timeout` is used + instead. - This function creates a re-try functionality to better support - alerts in Chrome. + Examples: + | Handle Alert | | | # Accept alert. | + | Handle Alert | action=DISMISS | | # Dismiss alert. | + | Handle Alert | timeout=10 s | | # Use custom timeout and accept alert. | + | Handle Alert | DISMISS | 1 min | # Use custom timeout and dismiss alert. | + | ${message} = | Handle Alert | | # Accept alert and get its message. | + | ${message} = | Handle Alert | LEAVE | # Leave alert open and get its message. | + + New in SeleniumLibrary 3.0. """ - 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() + alert = self._wait_alert(timeout) + return self._handle_alert(alert, action) + + def _handle_alert(self, alert, action): + action = action.upper() text = ' '.join(alert.text.splitlines()) - if dismiss_type == self.DISMISS_ALERT: - alert.dismiss() - elif dismiss_type == self.ACCEPT_ALERT: + if action == self.ACCEPT: alert.accept() + elif action == self.DISMISS: + alert.dismiss() + elif action != self.LEAVE: + raise ValueError("Invalid alert action '%s'." % action) return text - def _wait_alert(self): - return WebDriverWait(self.browser, 1).until(EC.alert_is_present()) + def _wait_alert(self, timeout=None): + timeout = self.get_timeout(timeout) + wait = WebDriverWait(self.browser, timeout) + try: + return wait.until(EC.alert_is_present()) + except WebDriverException: + raise AssertionError('Alert not found in %s.' + % secs_to_timestr(timeout)) diff --git a/src/SeleniumLibrary/keywords/browsermanagement.py b/src/SeleniumLibrary/keywords/browsermanagement.py index 95f7fb799..f76eb6ce7 100644 --- a/src/SeleniumLibrary/keywords/browsermanagement.py +++ b/src/SeleniumLibrary/keywords/browsermanagement.py @@ -522,7 +522,7 @@ def set_selenium_speed(self, seconds): Example: | Set Selenium Speed | .5 seconds | """ - old_speed = self.ctx.speed + old_speed = self.get_selenium_speed() self.ctx.speed = timestr_to_secs(seconds) for browser in self.browsers.browsers: self._monkey_patch_speed(browser) diff --git a/src/SeleniumLibrary/keywords/waiting.py b/src/SeleniumLibrary/keywords/waiting.py index 38d6a5a09..5afdfb31f 100644 --- a/src/SeleniumLibrary/keywords/waiting.py +++ b/src/SeleniumLibrary/keywords/waiting.py @@ -263,8 +263,7 @@ def wait_func(): self._wait_until_no_error(timeout, wait_func) def _wait_until_no_error(self, timeout, wait_func, *args): - timeout = timestr_to_secs(timeout) if is_truthy(timeout) else self.ctx.timeout - maxtime = time.time() + timeout + maxtime = time.time() + self.get_timeout(timeout) while True: timeout_error = wait_func(*args) if not timeout_error: @@ -274,5 +273,4 @@ def _wait_until_no_error(self, timeout, wait_func, *args): time.sleep(0.2) def _format_timeout(self, timeout): - timeout = timestr_to_secs(timeout) if is_truthy(timeout) else self.ctx.timeout - return secs_to_timestr(timeout) + return secs_to_timestr(self.get_timeout(timeout)) diff --git a/src/SeleniumLibrary/utils/__init__.py b/src/SeleniumLibrary/utils/__init__.py index f827f0b1d..377f9d42d 100644 --- a/src/SeleniumLibrary/utils/__init__.py +++ b/src/SeleniumLibrary/utils/__init__.py @@ -20,7 +20,7 @@ from .deprecated import Deprecated from .librarylistener import LibraryListener from .seleniumversion import SELENIUM_VERSION -from .types import is_string, is_truthy, is_falsy +from .types import is_falsy, is_noney, is_string, is_truthy def escape_xpath_value(value): diff --git a/src/SeleniumLibrary/utils/types.py b/src/SeleniumLibrary/utils/types.py index 86e1890fd..266c55a49 100644 --- a/src/SeleniumLibrary/utils/types.py +++ b/src/SeleniumLibrary/utils/types.py @@ -37,3 +37,7 @@ def is_truthy(item): def is_falsy(item): return not is_truthy(item) + + +def is_noney(item): + return item is None or is_string(item) and item.upper() == 'NONE' diff --git a/test/acceptance/keywords/alerts.robot b/test/acceptance/keywords/alerts.robot new file mode 100644 index 000000000..316618bcc --- /dev/null +++ b/test/acceptance/keywords/alerts.robot @@ -0,0 +1,232 @@ +*** Settings *** +Force Tags Known Issue Safari +Suite Setup Set Global Timeout 1 second +Test Setup Go To Page "javascript/alert.html" +Suite Teardown Restore Global Timeout +Resource ../resource.robot + +*** Test Cases *** +Handle Alert accepts by default + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + Handle Alert + Alert Should Not Be Present + Wait For Title Change Original Changed! + +Handle Alert can dismiss + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + Handle Alert action=DISMISS + Alert Should Not Be Present + Wait For Title Change Original + +Handle Alert can leave open + Click Link Click Me! + Handle Alert Leave + Alert Should Be Present + +Handle Alert with invalid action + Click Link Click Me! + Run Keyword And Expect Error + ... ValueError: Invalid alert action 'INVALID'. + ... Handle Alert INVALID + Alert Should Be Present + +Handle Alert returns message + Click Link Click Me! + ${message} = Handle Alert + Should Be Equal ${message} ALERT! + Click Link Click Me Too! + ${message} = Handle Alert action=LEAVE + Should Be Equal ${message} MULTILINE ALERT! + Alert Should Be Present + +Handle Alert with custom timeout + Click Button Slow alert + Handle Alert timeout=1s + Click Button Slow alert + Run Keyword And Expect Error + ... Alert not found in 1 millisecond. + ... Handle Alert ACCEPT 1 ms + Handle Alert timeout=3.14 seconds + +Alert Should Not Be Present + Alert Should Not Be Present + Click Link Click Me! + Run Keyword And Expect Error + ... Alert with message 'ALERT!' present. + ... Alert Should Not Be Present + +Alert Should Not Be Present with custom actions + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + Run Keyword And Expect Error + ... Alert with message 'Really change the title?' present. + ... Alert Should Not Be Present action=LEAVE + Run Keyword And Expect Error + ... Alert with message 'Really change the title?' present. + ... Alert Should Not Be Present action=DISmiss + Wait For Title Change Original + +Alert Should Not Be Present with custom timeout + Alert Should Not Be Present timeout=0.1s + Click Button Slow alert + Alert Should Not Be Present DISMISS ${0.001} + Run Keyword And Expect Error + ... Alert with message 'Alert after 500ms!' present. + ... Alert Should Not Be Present timeout=0.99999 + +Alert Should Be Present + Run Keyword And Expect Error + ... Alert not found in 1 second. + ... Alert Should Be Present + Click Link Click Me! + Alert Should Be Present + +Alert Should Be Present with message validation + Click Link Click Me! + Alert Should Be Present ALERT! + Click Link Click Me Too! + Alert Should Be Present MULTILINE ALERT! + Click Link Click Me! + Run Keyword And Expect Error + ... Alert message should have been 'foo bar' but it was 'ALERT!'. + ... Alert Should Be Present foo bar + +Alert Should Be Present accepts by default + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + Alert Should Be Present Really change the title? + Wait For Title Change Original Changed! + Alert Should Not Be Present + +Alert Should Be Present can dismiss + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + Alert Should Be Present Really change the title? action=DISMISS + Wait For Title Change Original + Alert Should Not Be Present + +Alert Should Be Present can leave alert open + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + Alert Should Be Present action=LEAVE + Alert Should Be Present + +Alert Should Be Present with custom timeout + Click Button Slow alert + Run Keyword And Expect Error + ... Alert not found in 1 millisecond. + ... Alert Should Be Present timeout=1ms + Alert Should Be Present Alert after 500ms! ACCEPT 3s + +Get Alert Message + [Documentation] DEPRECATED! + Click Link Click Me! + ${msg} = Get Alert Message + Should Be Equal ${msg} ALERT! + Click Link Click Me Too! + ${msg} = Get Alert Message + Should Be Equal ${msg} MULTILINE ALERT! + Run Keyword And Expect Error + ... Alert not found in 1 second. + ... Get Alert Message + +Get Alet Message dismisses by default + [Documentation] DEPRECATED! + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + ${msg} = Get Alert Message + Should Be Equal ${msg} Really change the title? + Wait For Title Change Original + +Get Alert Message can leave alert open + [Documentation] DEPRECATED! + Click Link Click Me! + ${msg} = Get Alert Message ${FALSE} + Should Be Equal ${msg} ALERT! + Alert Should Be Present + +Input Text Into Alert + [Setup] Go To Page "javascript/alert_prompt.html" + Click Button css=button + Input Text Into Alert Robot + Alert Should Not Be Present + Page Should Contain Hello Robot! How are you today? + +Input Text Into Alert can leave alert open + [Setup] Go To Page "javascript/alert_prompt.html" + Click Button css=button + Input Text Into Alert Robot action=LEAVE + Alert Should Be Present + Page Should Contain Hello Robot! How are you today? + +Input Text Into Alert can dismiss + [Setup] Go To Page "javascript/alert_prompt.html" + Click Button css=button + Input Text Into Alert Robot action=DISMISS + Alert Should Not Be Present + Page Should Not Contain Robot + +Input Text Into Alert with custom timeout + [Setup] Go To Page "javascript/alert_prompt.html" + Run Keyword And Expect Error + ... Alert not found in 7 milliseconds. + ... Input Text Into Alert This is not found timeout=007ms + +Input Text Into Prompt + [Documentation] DEPRECATED! Always leaves the alert open. + [Setup] Go To Page "javascript/alert_prompt.html" + Click Button css=button + Input Text Into Prompt Robot + Alert Should Be Present + Page Should Contain Hello Robot! How are you today? + +Confirm Action + [Documentation] DEPRECATED! + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + ${msg}= Confirm Action + Should Be Equal ${msg} Really change the title? + Wait For Title Change Original Changed! + +Confirm Action multiple times + [Documentation] DEPRECATED! + [Setup] Go To Page "javascript/alert_prompt.html" + Click Button css=button + Input Text Into Alert Robot action=LEAVE + Confirm Action + Page Should Contain Hello Robot! How are you today? + Click Button css=button + Input Text Into Alert Mr. Roboto action=LEAVE + Confirm Action + Page Should Contain Hello Mr. Roboto! How are you today? + +Cancel Action + [Documentation] DEPRECATED! + [Setup] Go To Page "javascript/alert_prompt.html" + Choose Cancel On Next Confirmation + Click Button css=button + Input Text Into Alert Robot action=LEAVE + Confirm Action + Page Should Not Contain Robot + +Dismiss Alert + [Documentation] DEPRECATED! + [Setup] Go To Page "javascript/dynamic_content.html" + Click Button Change the title + ${accepted} = Dismiss Alert # This actually accepts the alert + Should Be Equal ${accepted} ${TRUE} + Wait For Title Change Original Changed! + Click Button Change the title + ${accepted} = Dismiss Alert accept=${FALSE} + Wait For Title Change Original Changed! + Should Be Equal ${accepted} ${FALSE} + Click Button Change the title + Dismiss Alert true + Wait For Title Change Original Changed! Changed! + +*** Keywords *** +Wait For Title Change + [Arguments] ${expected} + Wait For Condition return document.title == '${expected}' diff --git a/test/acceptance/keywords/javascript.robot b/test/acceptance/keywords/javascript.robot index 59b49585b..d16de95c4 100644 --- a/test/acceptance/keywords/javascript.robot +++ b/test/acceptance/keywords/javascript.robot @@ -1,56 +1,14 @@ *** Settings *** -Documentation Tests javascript Test Setup Go To Page "javascript/dynamic_content.html" Resource ../resource.robot *** Test Cases *** Clicking Elements Should Activate Javascript - [Documentation] Clicking Elements Should Activate Javascript Title Should Be Original Click Element link=change title Title Should Be Changed -Alert Should Be Present - [Documentation] Alert Should Be Present - [Tags] Known Issue Safari - [Setup] Go To Page "javascript/alert.html" - Click Link Click Me! - Alert Should Be Present - Click Link Click Me Too! - Alert Should Be Present MULTILINE ALERT! - Click Link Click Me! - Run Keyword And Expect Error Alert text should have been 'foo bar' but was 'ALERT!' Alert Should Be Present foo bar - -Get Alert Message - [Documentation] Get Alert Message - [Tags] Known Issue Safari - [Setup] Go To Page "javascript/alert.html" - Click Link Click Me! - ${msg} = Get Alert Message - Should Be Equal ${msg} ALERT! - Run Keyword And Expect Error There were no alerts Get Alert Message - -Read Alert Message - [Documentation] Read Alert Message - [Tags] Known Issue Safari - [Setup] Go To Page "javascript/alert.html" - Click Link Click Me! - ${msg} = Get Alert Message ${FALSE} - Should Be Equal ${msg} ALERT! - Dismiss Alert - Run Keyword And Expect Error There were no alerts Get Alert Message - -Input Text Into Prompt - [Documentation] Input Text Into Prompt - [Tags] Known Issue Safari - [Setup] Go To Page "javascript/alert_prompt.html" - Click Element css=button - Input Text Into Prompt myname - Dismiss Alert - Page Should Contain myname - Mouse Down On Link - [Documentation] Mouse Down On Link [Tags] Known Issue Safari [Setup] Go To Page "javascript/mouse_events.html" Mouse Down On Image image_mousedown @@ -61,23 +19,6 @@ Mouse Down On Link Text Field Should Contain textfield onmousedown Mouse Up link_mousedown -Confirm Action - [Documentation] Confirm Action - [Tags] Known Issue Safari - Click Button Change the title - ${msg}= Confirm Action - Title Should Be Changed after confirmation - Should Be Equal ${msg} Really change the title? - -Cancel Action - [Documentation] Cancel Action - [Tags] Known Issue Safari - Choose Cancel On Next Confirmation - Click Button Change the title - ${msg}= Confirm Action - Title Should Be Original - Should Be Equal ${msg} Really change the title? - Execute Javascript [Documentation] LOG 2 Executing JavaScript: ... window.add_content('button_target', 'Inserted directly') @@ -92,13 +33,11 @@ Execute Javascript from File Page Should Contain Inserted via file Open Context Menu - [Documentation] Open Context Menu [Tags] Known Issue Safari Go To Page "javascript/context_menu.html" Open Context Menu myDiv Drag and Drop - [Documentation] Drag and Drop [Tags] Known Issue Internet Explorer Known Issue Safari [Setup] Go To Page "javascript/drag_and_drop.html" Element Text Should Be id=droppable Drop here @@ -106,7 +45,6 @@ Drag and Drop Element Text Should Be id=droppable Dropped! Drag and Drop by Offset - [Documentation] Drag and Drop by Offset [Tags] Known Issue Firefox Known Issue Internet Explorer Known Issue Safari [Setup] Go To Page "javascript/drag_and_drop.html" Element Text Should Be id=droppable Drop here @@ -117,7 +55,7 @@ Drag and Drop by Offset Verify Console Log Can be Caught [Tags] Known Issue Firefox - ${message} Set Variable Sample Console Error + ${message}= Set Variable Sample Console Error Execute Javascript console.error('${message}') ${logs}= Get Log browser ${err}= Convert To string ${logs} diff --git a/test/acceptance/keywords/set_selenium_speed.robot b/test/acceptance/keywords/set_selenium_speed.robot index a9cbf02fc..8d3da88fa 100644 --- a/test/acceptance/keywords/set_selenium_speed.robot +++ b/test/acceptance/keywords/set_selenium_speed.robot @@ -1,15 +1,15 @@ *** Settings *** Suite Setup Go To Page "forms/prefilled_email_form.html" -Suite Teardown Set Selenium Speed 0 +Test Teardown Set Selenium Speed 0 Resource ../resource.robot *** Test Cases *** Settimg selenium speed is possible multiple times Set Selenium Speed 10 - ${speed} = Set Selenium Speed 5 - Should Be Equal ${speed} ${10} - ${speed} = Set Selenium Speed 1 - Should Be Equal ${speed} ${5} + ${old} = Set Selenium Speed 1 + Should Be Equal ${old} 10 seconds + ${old} = Set Selenium Speed 100 + Should Be Equal ${old} 1 second Selenium speed should affect execution [Documentation] Click Element executes two selenium commands and diff --git a/test/acceptance/keywords/waiting.robot b/test/acceptance/keywords/waiting.robot index 69c4fa7fc..33c80f32f 100644 --- a/test/acceptance/keywords/waiting.robot +++ b/test/acceptance/keywords/waiting.robot @@ -1,12 +1,10 @@ *** Settings *** -Documentation Tests waiting Test Setup Go To Page "javascript/delayed_events.html" Resource ../resource.robot Force Tags Known Issue Internet Explorer *** Test Cases *** Wait For Condition - [Documentation] Wait For Condition Title Should Be Original Wait For Condition return window.document.title == "Changed" Run Keyword And Expect Error @@ -14,13 +12,11 @@ Wait For Condition ... Wait For Condition return window.document.title == "Invalid" ${0.1} Wait Until Page Contains - [Documentation] Wait Until Page Contains Wait Until Page Contains New Content 2 s Run Keyword And Expect Error Text 'invalid' did not appear in 100 milliseconds ... Wait Until Page Contains invalid 0.1 Wait Until Page Does Not Contain - [Documentation] Wait Until Page Does Not Contain Wait Until Page Does Not Contain This is content 2 s Run Keyword And Expect Error Text 'Initially hidden' did not disappear in 100 milliseconds ... Wait Until Page Does Not Contain Initially hidden 0.1 @@ -32,14 +28,12 @@ Wait Until Page Contains Element ... Wait Until Page Contains Element %cnon-existent 0.1 seconds Wait Until Page Does Not Contain Element - [Documentation] Tests also that format characters (e.g. %c) are handled correctly in error - ... messages + [Documentation] Tests also that format characters (e.g. %c) are handled correctly in error messages Wait Until Page Does Not Contain Element not_present 2 seconds Run Keyword And Expect Error Element 'content' did not disappear in 100 milliseconds ... Wait Until Page Does Not Contain Element content 0.1 seconds Wait Until Element Is Visible - [Documentation] Wait Until Element Is Visible Run Keyword And Expect Error Element 'hidden' was not visible in 100 milliseconds ... Wait Until Element Is Visible hidden 0.1 Wait Until Element Is Visible hidden 2 s @@ -57,7 +51,6 @@ Wait Until Element Is Visible with locator only Wait Until Element Is Visible hidden Wait Until Element Is Enabled - [Documentation] Wait Until Element Is Enabled Run Keyword And Expect Error Element 'id=disabled' was not enabled in 100 milliseconds ... Wait Until Element Is Enabled id=disabled 0.1 Wait Until Element Is Enabled id=disabled 2 s @@ -68,7 +61,6 @@ Wait Until Element Is Enabled ... id=invalid 0.1 User error message Wait Until Element Contains - [Documentation] Wait Until Element Contains Run Keyword And Expect Error ... Text 'New' did not appear in 100 milliseconds to element 'id=content'. Its text was 'This is content'. ... Wait Until Element Contains id=content New 0.1 @@ -82,7 +74,6 @@ Wait Until Element Contains ... Wait Until Element Contains id=invalid content 0.1 Wait Until Element Does Not Contain - [Documentation] Wait Until Element Does Not Contain Run Keyword And Expect Error ... Text 'This is' did not disappear in 100 milliseconds from element 'id=content'. ... Wait Until Element Does Not Contain id=content This is 0.1 @@ -90,3 +81,11 @@ Wait Until Element Does Not Contain Wait Until Element Does Not Contain id=content content 2 s Run Keyword And Expect Error User error message Wait Until Element Does Not Contain ... content New Content 0.1 User error message + +Timeout can be zero + Run Keyword And Expect Error + ... Text 'New Content' did not appear in 0 seconds to element 'content'. Its text was 'This is content'. + ... Wait Until Element Contains content New Content 0 + Run Keyword And Expect Error + ... Text 'New Content' did not appear in 0 seconds to element 'content'. Its text was 'This is content'. + ... Wait Until Element Contains content New Content ${0} diff --git a/test/acceptance/resource.robot b/test/acceptance/resource.robot index ce76d1ac2..fc17d44ff 100644 --- a/test/acceptance/resource.robot +++ b/test/acceptance/resource.robot @@ -1,5 +1,5 @@ *** Setting *** -Library SeleniumLibrary run_on_failure=Nothing implicit_wait=0 +Library SeleniumLibrary run_on_failure=Nothing implicit_wait=0.2 seconds Library Collections Library OperatingSystem @@ -17,7 +17,9 @@ Open Browser To Start Page [Documentation] This keyword also tests 'Set Selenium Speed' and 'Set Selenium Timeout' ... against all reason. ${default speed} ${default timeout}= Open Browser To Start Page Without Testing Default Options - Should Be Equal ${default speed} ${0.0} + # FIXME: We shouldn't test anything here. If this stuff isn't tested elsewhere, new *tests* needs to be added. + # FIXME: The second test below verifies a hard coded return value!!?! + Should Be Equal ${default speed} 0 seconds Should Be Equal ${default timeout} 5 seconds Open Browser To Start Page Without Testing Default Options @@ -70,3 +72,11 @@ Set ${level} Loglevel Verify Location Is "${relative url}" [Documentation] Verifies location Wait Until Keyword Succeeds 5 1 Location Should Be ${ROOT}/${relative url} + +Set Global Timeout + [Arguments] ${timeout} + ${previous} = Set Selenium timeout ${timeout} + Set Suite Variable ${PREVIOUS TIMEOUT} ${previous} + +Restore Global Timeout + Set Selenium timeout ${PREVIOUS TIMEOUT} diff --git a/test/resources/html/javascript/alert.html b/test/resources/html/javascript/alert.html index bc0f14f32..0913271ed 100644 --- a/test/resources/html/javascript/alert.html +++ b/test/resources/html/javascript/alert.html @@ -5,5 +5,6 @@
+ -