Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions src/Selenium2Library/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@

__version__ = VERSION


class Selenium2Library(
_LoggingKeywords,
_RunOnFailureKeywords,
_BrowserManagementKeywords,
_ElementKeywords,
_LoggingKeywords,
_RunOnFailureKeywords,
_BrowserManagementKeywords,
_ElementKeywords,
_TableElementKeywords,
_FormElementKeywords,
_SelectElementKeywords,
Expand All @@ -31,7 +32,7 @@ class Selenium2Library(
*Before running tests*

Prior to running test cases using Selenium2Library, Selenium2Library must be
imported into your Robot test suite (see `importing` section), and the
imported into your Robot test suite (see `importing` section), and the
`Open Browser` keyword must be used to open a browser to the desired location.

*Locating elements*
Expand Down
82 changes: 38 additions & 44 deletions src/Selenium2Library/keywords/_browsermanagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@
'googlechrome': "_make_chrome",
'gc': "_make_chrome",
'chrome': "_make_chrome",
'opera' : "_make_opera",
'htmlunit' : "_make_htmlunit",
'htmlunitwithjs' : "_make_htmlunitwithjs"
'opera': "_make_opera",
'htmlunit': "_make_htmlunit",
'htmlunitwithjs': "_make_htmlunitwithjs"
}


class _BrowserManagementKeywords(KeywordGroup):

def __init__(self):
Expand Down Expand Up @@ -51,8 +52,8 @@ def close_browser(self):
% self._cache.current.session_id)
self._cache.close()

def open_browser(self, url, browser='firefox', alias=None,remote_url=False,
desired_capabilities=None,ff_profile_dir=None):
def open_browser(self, url, browser='firefox', alias=None, remote_url=False,
desired_capabilities=None, ff_profile_dir=None):
"""Opens a new browser instance to given URL.

Returns the index of this browser instance which can be used later to
Expand All @@ -76,7 +77,7 @@ def open_browser(self, url, browser='firefox', alias=None,remote_url=False,
| opera | Opera |
| htmlunit | HTMLUnit |
| htmlunitwithjs | HTMLUnit with Javascipt support |


Note, that you will encounter strange behavior, if you open
multiple Internet Explorer browser instances. That is also why
Expand All @@ -101,7 +102,7 @@ def open_browser(self, url, browser='firefox', alias=None,remote_url=False,
else:
self._info("Opening browser '%s' to base url '%s'" % (browser, url))
browser_name = browser
browser = self._make_browser(browser_name,desired_capabilities,ff_profile_dir,remote_url)
browser = self._make_browser(browser_name, desired_capabilities, ff_profile_dir, remote_url)
browser.get(url)
self._debug('Opened browser with session id %s'
% browser.session_id)
Expand Down Expand Up @@ -185,7 +186,7 @@ def select_window(self, locator=None):

If the window is found, all subsequent commands use that window, until
this keyword is used again. If the window is not found, this keyword fails.

By default, when a locator value is provided,
it is matched against the title of the window and the
javascript name of the window. If multiple windows with
Expand Down Expand Up @@ -351,26 +352,25 @@ def set_selenium_implicit_wait(self, seconds):
"""Sets Selenium 2's default implicit wait in seconds and
sets the implicit wait for all open browsers.

From selenium 2 function 'Sets a sticky timeout to implicitly
From selenium 2 function 'Sets a sticky timeout to implicitly
wait for an element to be found, or a command to complete.
This method only needs to be called one time per session.'

Example:
| ${orig wait} = | Set Selenium Implicit Wait | 10 seconds |
| Perform AJAX call that is slow |
| Set Selenium Implicit Wait | ${orig wait} |
| Set Selenium Implicit Wait | ${orig wait} |
"""
old_wait = self.get_selenium_implicit_wait()
self._implicit_wait_in_secs = robot.utils.timestr_to_secs(seconds)
for browser in self._cache.get_open_browsers():
browser.implicitly_wait(self._implicit_wait_in_secs)
return old_wait


def set_browser_implicit_wait(self, seconds):
"""Sets current browser's implicit wait in seconds.

From selenium 2 function 'Sets a sticky timeout to implicitly
From selenium 2 function 'Sets a sticky timeout to implicitly
wait for an element to be found, or a command to complete.
This method only needs to be called one time per session.'

Expand All @@ -392,15 +392,14 @@ def _current_browser(self):
def _get_browser_token(self, browser_name):
return BROWSER_NAMES.get(browser_name.lower().replace(' ', ''), browser_name)


def _get_browser_creation_function(self,browser_name):
def _get_browser_creation_function(self, browser_name):
return BROWSER_NAMES.get(browser_name.lower().replace(' ', ''), browser_name)

def _make_browser(self , browser_name , desired_capabilities=None , profile_dir=None,
def _make_browser(self, browser_name, desired_capabilities=None, profile_dir=None,
remote=None):

creation_func = self._get_browser_creation_function(browser_name)
browser = getattr(self,creation_func)(remote , desired_capabilities , profile_dir)
browser = getattr(self, creation_func)(remote, desired_capabilities, profile_dir)

if browser is None:
raise ValueError(browser_name + " is not a supported browser.")
Expand All @@ -411,55 +410,51 @@ def _make_browser(self , browser_name , desired_capabilities=None , profile_dir=

return browser


def _make_ff(self , remote , desired_capabilites , profile_dir):

if not profile_dir: profile_dir = FIREFOX_PROFILE_DIR
def _make_ff(self, remote, desired_capabilites, profile_dir):
if not profile_dir:
profile_dir = FIREFOX_PROFILE_DIR
profile = webdriver.FirefoxProfile(profile_dir)
if remote:
browser = self._create_remote_web_driver(webdriver.DesiredCapabilities.FIREFOX ,
remote , desired_capabilites , profile)
browser = self._create_remote_web_driver(webdriver.DesiredCapabilities.FIREFOX,
remote, desired_capabilites, profile)
else:
browser = webdriver.Firefox(firefox_profile=profile)
return browser
def _make_ie(self , remote , desired_capabilities , profile_dir):
return self._generic_make_browser(webdriver.Ie,

def _make_ie(self, remote, desired_capabilities, profile_dir):
return self._generic_make_browser(webdriver.Ie,
webdriver.DesiredCapabilities.INTERNETEXPLORER, remote, desired_capabilities)

def _make_chrome(self , remote , desired_capabilities , profile_dir):
return self._generic_make_browser(webdriver.Chrome,
def _make_chrome(self, remote, desired_capabilities, profile_dir):
return self._generic_make_browser(webdriver.Chrome,
webdriver.DesiredCapabilities.CHROME, remote, desired_capabilities)

def _make_opera(self , remote , desired_capabilities , profile_dir):
return self._generic_make_browser(webdriver.Opera,
def _make_opera(self, remote, desired_capabilities, profile_dir):
return self._generic_make_browser(webdriver.Opera,
webdriver.DesiredCapabilities.OPERA, remote, desired_capabilities)

def _make_htmlunit(self , remote , desired_capabilities , profile_dir):
return self._generic_make_browser(webdriver.Remote,
def _make_htmlunit(self, remote, desired_capabilities, profile_dir):
return self._generic_make_browser(webdriver.Remote,
webdriver.DesiredCapabilities.HTMLUNIT, remote, desired_capabilities)

def _make_htmlunitwithjs(self , remote , desired_capabilities , profile_dir):
return self._generic_make_browser(webdriver.Remote,
def _make_htmlunitwithjs(self, remote, desired_capabilities, profile_dir):
return self._generic_make_browser(webdriver.Remote,
webdriver.DesiredCapabilities.HTMLUNITWITHJS, remote, desired_capabilities)


def _generic_make_browser(self, webdriver_type , desired_cap_type, remote_url, desired_caps):
'''most of the make browser functions just call this function which creates the
def _generic_make_browser(self, webdriver_type, desired_cap_type, remote_url, desired_caps):
'''most of the make browser functions just call this function which creates the
appropriate web-driver'''
if not remote_url:
if not remote_url:
browser = webdriver_type()
else:
browser = self._create_remote_web_driver(desired_cap_type,remote_url , desired_caps)
browser = self._create_remote_web_driver(desired_cap_type, remote_url, desired_caps)
return browser


def _create_remote_web_driver(self , capabilities_type , remote_url , desired_capabilities=None , profile=None):
def _create_remote_web_driver(self, capabilities_type, remote_url, desired_capabilities=None, profile=None):
'''parses the string based desired_capabilities which should be in the form
key1:val1,key2:val2 and creates the associated remote web driver'''
desired_cap = self._create_desired_capabilities(capabilities_type , desired_capabilities)
return webdriver.Remote(desired_capabilities=desired_cap , command_executor=str(remote_url) , browser_profile=profile)

desired_cap = self._create_desired_capabilities(capabilities_type, desired_capabilities)
return webdriver.Remote(desired_capabilities=desired_cap, command_executor=str(remote_url), browser_profile=profile)

def _create_desired_capabilities(self, capabilities_type, capabilities_string):
desired_capabilities = capabilities_type
Expand All @@ -468,4 +463,3 @@ def _create_desired_capabilities(self, capabilities_type, capabilities_string):
(key, value) = cap.split(":")
desired_capabilities[key.strip()] = value.strip()
return desired_capabilities

1 change: 1 addition & 0 deletions src/Selenium2Library/keywords/_cookie.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from keywordgroup import KeywordGroup


class _CookieKeywords(KeywordGroup):

def delete_all_cookies(self):
Expand Down
14 changes: 7 additions & 7 deletions src/Selenium2Library/keywords/_element.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from Selenium2Library.locators import ElementFinder
from keywordgroup import KeywordGroup


class _ElementKeywords(KeywordGroup):

def __init__(self):
Expand Down Expand Up @@ -287,11 +288,10 @@ def drag_and_drop(self, source, target):
Examples:
| Drag And Drop | elem1 | elem2 | # Move elem1 over elem2. |
"""
src_elem = self._element_find(source,True,True)
trg_elem = self._element_find(target,True,True)
src_elem = self._element_find(source, True, True)
trg_elem = self._element_find(target, True, True)
ActionChains(self._current_browser()).drag_and_drop(src_elem, trg_elem).perform()


def drag_and_drop_by_offset(self, source, xoffset, yoffset):
"""Drags element identified with `source` which is a locator.

Expand Down Expand Up @@ -524,7 +524,7 @@ def xpath_should_match_x_times(self, xpath, expected_xpath_count, message='', lo
if int(actual_xpath_count) != int(expected_xpath_count):
if not message:
message = "Xpath %s should have matched %s times but matched %s times"\
%(xpath, expected_xpath_count, actual_xpath_count)
% (xpath, expected_xpath_count, actual_xpath_count)
self.log_source(loglevel)
raise AssertionError(message)
self._info("Current page contains %s elements matching '%s'."
Expand All @@ -538,7 +538,8 @@ def _element_find(self, locator, first_only, required, tag=None):
if required and len(elements) == 0:
raise ValueError("Element locator '" + locator + "' did not match any elements.")
if first_only:
if len(elements) == 0: return None
if len(elements) == 0:
return None
return elements[0]
return elements

Expand Down Expand Up @@ -573,7 +574,7 @@ def _is_enabled(self, locator):
return True

def _is_text_present(self, text):
locator = "xpath=//*[contains(., %s)]" % utils.escape_xpath_value(text);
locator = "xpath=//*[contains(., %s)]" % utils.escape_xpath_value(text)
return self._is_element_present(locator)

def _is_visible(self, locator):
Expand Down Expand Up @@ -656,4 +657,3 @@ def _page_should_not_contain_element(self, locator, tag, message, loglevel):
raise AssertionError(message)
self._info("Current page does not contain %s '%s'."
% (element_name, locator))

8 changes: 5 additions & 3 deletions src/Selenium2Library/keywords/_formelement.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
from keywordgroup import KeywordGroup


class _FormElementKeywords(KeywordGroup):

# Public, form
Expand Down Expand Up @@ -168,7 +169,7 @@ def choose_file(self, locator, file_path):
"""Inputs the `file_path` into file input field found by `identifier`.

This keyword is most often used to input files into upload forms.
The file specified with `file_path` must be available on the same host
The file specified with `file_path` must be available on the same host
where the Selenium Server is running.

Example:
Expand Down Expand Up @@ -244,7 +245,8 @@ def textfield_value_should_be(self, locator, expected, message=''):
for details about locating elements.
"""
element = self._element_find(locator, True, False, 'text field')
if element is None: element = self._element_find(locator, True, False, 'file upload')
if element is None:
element = self._element_find(locator, True, False, 'file upload')
actual = element.get_attribute('value') if element is not None else None
if actual != expected:
if not message:
Expand Down Expand Up @@ -328,4 +330,4 @@ def _is_form_element(self, element):
if element is None:
return False
tag = element.tag_name.lower()
return tag == 'input' or tag == 'select' or tag == 'textarea' or tag == 'button'
return tag == 'input' or tag == 'select' or tag == 'textarea' or tag == 'button'
19 changes: 11 additions & 8 deletions src/Selenium2Library/keywords/_javascript.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from selenium.common.exceptions import WebDriverException
from keywordgroup import KeywordGroup


class _JavaScriptKeywords(KeywordGroup):

def __init__(self):
Expand Down Expand Up @@ -34,10 +35,10 @@ def choose_ok_on_next_confirmation(self):
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
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.
Expand Down Expand Up @@ -68,7 +69,7 @@ def confirm_action(self):
def execute_javascript(self, *code):
"""Executes the given JavaScript code.

`code` may contain multiple lines of code but must contain a
`code` may contain multiple lines of code but must contain a
return statement (with the value to be returned) at the end.

`code` may be divided into multiple cells in the test data. In that
Expand All @@ -94,7 +95,7 @@ def execute_javascript(self, *code):
def execute_async_javascript(self, *code):
"""Executes asynchronous JavaScript code.

`code` may contain multiple lines of code but must contain a
`code` may contain multiple lines of code but must contain a
return statement (with the value to be returned) at the end.

`code` may be divided into multiple cells in the test data. In that
Expand Down Expand Up @@ -132,9 +133,11 @@ def _close_alert(self, confirm=False):
alert = None
try:
alert = self._current_browser().switch_to_alert()
text = ' '.join(alert.text.splitlines()) # collapse new lines chars
if not confirm: alert.dismiss()
else: alert.accept()
text = ' '.join(alert.text.splitlines()) # collapse new lines chars
if not confirm:
alert.dismiss()
else:
alert.accept()
return text
except WebDriverException:
raise RuntimeError('There were no alerts')
Expand All @@ -149,4 +152,4 @@ def _get_javascript_to_execute(self, code):
try:
return codefile.read().strip()
finally:
codefile.close()
codefile.close()
Loading