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
48 changes: 41 additions & 7 deletions src/Selenium2Library/keywords/_javascript.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import os
from selenium.common.exceptions import WebDriverException
from keywordgroup import KeywordGroup
from Selenium2Library.utils import isstr

from robot.api import logger


class _JavaScriptKeywords(KeywordGroup):

Expand Down Expand Up @@ -34,10 +38,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 @@ -65,7 +69,7 @@ def confirm_action(self):
self._cancel_on_next_confirmation = False
return text

def execute_javascript(self, *code):
def execute_javascript(self, args, *code):
"""Executes the given JavaScript code.

`code` may contain multiple lines of code and may be divided into
Expand All @@ -82,6 +86,16 @@ def execute_javascript(self, *code):
document object of the current frame or window, e.g.
_document.getElementById('foo')_.

`args` is an optional way of specifying arguments to be passed to the context
of the executing javascript code. `args` must either be a list or any other
non-string type. Multiple arguments and strings must be added to a list to be used
from `args`. Arguments are accessed in the javascript function using the _arguments_
variable.

Example:
| @{arg list} | Hello | World |
| Execute Javascript | ${arg list} | console.log(arguments[0], arguments[1]); |

This keyword returns None unless there is a return statement in the
JavaScript. Return values are converted to the appropriate type in
Python, including WebElements.
Expand All @@ -92,11 +106,21 @@ def execute_javascript(self, *code):
| ${sum}= | Execute JavaScript | return 1 + 1; |
| Should Be Equal | ${sum} | ${2} |
"""
if len(code) == 0:
code = args
args = []
elif isstr(args):
code = list(code)
code.insert(0, args)
args = []
elif not isinstance(args, list):
args = [args]

js = self._get_javascript_to_execute(''.join(code))
self._info("Executing JavaScript:\n%s" % js)
return self._current_browser().execute_script(js)
return self._current_browser().execute_script(js, *args)

def execute_async_javascript(self, *code):
def execute_async_javascript(self, args, *code):
"""Executes asynchronous JavaScript code.

Similar to `Execute Javascript` except that scripts executed with
Expand All @@ -116,9 +140,19 @@ def execute_async_javascript(self, *code):
| ... | window.setTimeout(answer, 2000); | |
| Should Be Equal | ${retval} | text |
"""
if len(code) == 0:
code = args
args = []
elif isstr(args):
code = list(code)
code.insert(0, args)
args = []
elif not isinstance(args, list):
args = [args]

js = self._get_javascript_to_execute(''.join(code))
self._info("Executing Asynchronous JavaScript:\n%s" % js)
return self._current_browser().execute_async_script(js)
return self._current_browser().execute_async_script(js, *args)

def get_alert_message(self):
"""Returns the text of current JavaScript alert.
Expand Down Expand Up @@ -152,4 +186,4 @@ def _get_javascript_to_execute(self, code):
try:
return codefile.read().strip()
finally:
codefile.close()
codefile.close()
21 changes: 16 additions & 5 deletions src/Selenium2Library/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import os
import os, sys
from fnmatch import fnmatch
from browsercache import BrowserCache

Expand All @@ -7,18 +7,29 @@
"get_module_names_under",
"import_modules_under",
"escape_xpath_value",
"BrowserCache"
"BrowserCache",
"isstr"
]

PY3 = sys.version_info[0] == 3

if PY3:
string_type = str
else:
string_type = basestring

# Public

def isstr(value):
return isinstance(value, string_type)

def get_child_packages_in(root_dir, include_root_package_name=True, exclusions=None):
packages = []
root_package_str = os.path.basename(root_dir) + '.' if include_root_package_name else ""
_discover_child_package_dirs(
root_dir,
_clean_exclusions(exclusions),
lambda abs_path, relative_path, name:
lambda abs_path, relative_path, name:
packages.append(root_package_str + relative_path.replace(os.sep, '.')))
return packages

Expand All @@ -29,7 +40,7 @@ def get_module_names_under(root_dir, include_root_package_name=True, exclusions=
root_dir,
_clean_exclusions(exclusions),
pattern if pattern is not None else "*.*",
lambda abs_path, relative_path, name:
lambda abs_path, relative_path, name:
module_names.append(root_package_str + os.path.splitext(relative_path)[0].replace(os.sep, '.')))
return module_names

Expand Down Expand Up @@ -65,7 +76,7 @@ def _discover_child_package_dirs(root_dir, exclusions, callback, relative_dir=No
item_abs_path = os.path.join(root_dir, item_relative_path)
if os.path.isdir(item_abs_path):
if os.path.exists(os.path.join(item_abs_path, "__init__.py")):
exclusion_matches = [ exclusion for exclusion in exclusions
exclusion_matches = [ exclusion for exclusion in exclusions
if os.sep + item_relative_path.lower() + os.sep == exclusion ]
if not exclusion_matches:
callback(item_abs_path, item_relative_path, item)
Expand Down
12 changes: 10 additions & 2 deletions test/acceptance/keywords/javascript.txt
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,16 @@ Execute Javascript
Execute Javascript window.add_content('button_target', 'Inserted directly')
Page Should Contain Inserted directly

Execute Javascript With List Arguments
@{args}= Create List Hello World
${result}= Execute Javascript ${args} return arguments[0] + ' ' + arguments[1];
Should Be Equal As Strings ${result} Hello World

Execute Javascript With Object Argument
${target}= Execute Javascript return window.document.getElementById('target');
${result}= Execute Javascript ${target} return arguments[0].id
Should Be Equal As Strings ${result} target

Execute Javascript from File
[Documentation] LOG 2:1 REGEXP: Reading JavaScript from file .* LOG 2:2 Executing JavaScript:\n window.add_content('button_target', 'Inserted via file')
Execute Javascript ${CURDIR}/executed_by_execute_javascript.js
Expand All @@ -76,5 +86,3 @@ Drag and Drop by Offset
Element Text Should Be id=droppable Drop here
Drag and Drop by Offset id=draggable ${100} ${20}
Element Text Should Be id=droppable Dropped!