Chromium Code Reviews| Index: tools/telemetry/telemetry/page/actions/page_action.py |
| diff --git a/tools/telemetry/telemetry/page/actions/page_action.py b/tools/telemetry/telemetry/page/actions/page_action.py |
| index 14f193ec4055d2c41cdcc19e00aecdf2f8bdbd54..ad3b38fe7e998f9fbeaaceb95b6855dd83c68f2c 100644 |
| --- a/tools/telemetry/telemetry/page/actions/page_action.py |
| +++ b/tools/telemetry/telemetry/page/actions/page_action.py |
| @@ -2,6 +2,8 @@ |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| +import re |
| + |
| class PageActionNotSupported(Exception): |
| pass |
| @@ -27,3 +29,88 @@ class PageAction(object): |
| def CleanUp(self, tab): |
| pass |
| + |
| + |
| +def EvaluateCallbackWithElement( |
| + tab, callback_js, selector=None, text=None, element_function=None, |
| + wait=False, timeout=60): |
| + """Evaluates the JavaScript callback with the given element. |
| + |
| + The element may be selected via selector, text, or element_function. |
| + Only one of these arguments must be specified. |
| + |
| + Returns: |
| + The callback's return value, if any. The return value must be |
| + convertible to JSON. |
| + |
| + Args: |
| + tab: A telemetry.core.Tab object. |
| + callback_js: The JavaScript callback to call (as string). |
| + The callback receive 2 parameters: the element, and information |
| + string about what method was used to retrieve the element. |
| + Example: ''' |
| + function(element, info) { |
| + if (!element) { |
| + throw Error('Can not find element: ' + info); |
| + } |
| + element.click() |
| + }''' |
| + selector: A CSS selector describing the element. |
| + text: The element must contains this exact text. |
| + element_function: A JavaScript function (as string) that is used |
| + to retrieve the element. For example: |
| + '(function() { return foo.element; })()'. |
|
nednguyen
2014/06/14 17:12:13
The naming element_function is misleading, I think
chrishenry
2014/06/14 17:30:51
I think you're right. It's not super confusing, bu
|
| + wait: Whether to wait for the return value to be true. |
| + timeout: The timeout for wait (if waiting). |
| + """ |
| + count = 0 |
| + info_msg = '' |
| + if element_function is not None: |
| + count = count + 1 |
| + info_msg = 'using element_function "%s"' % re.escape(element_function) |
| + if selector is not None: |
| + count = count + 1 |
| + info_msg = 'using selector "%s"' % _EscapeSelector(selector) |
| + element_function = 'document.querySelector("%s")' % _EscapeSelector( |
| + selector) |
| + if text is not None: |
| + count = count + 1 |
| + info_msg = 'using exact text match "%s"' % re.escape(text) |
| + element_function = ''' |
| + (function() { |
| + function _findElement(element, text) { |
| + if (element.innerHTML == text) { |
| + return element; |
| + } |
| + |
| + var childNodes = element.childNodes; |
| + for (var i = 0, len = childNodes.length; i < len; ++i) { |
| + var found = _findElement(childNodes[i], text); |
| + if (found) { |
| + return found; |
| + } |
| + } |
| + return null; |
| + } |
| + return _findElement(document, '%s'); |
| + })()''' % text |
| + |
| + if count != 1: |
| + raise PageActionFailed( |
| + 'Must specify 1 way to retrieve element, but %s was specified.' % count) |
| + |
| + code = ''' |
| + (function() { |
| + var element = %s; |
| + var callback = %s; |
| + return callback(element, '%s'); |
| + })()''' % (element_function, callback_js, info_msg) |
| + |
| + if wait: |
| + tab.WaitForJavaScriptExpression(code, timeout) |
| + return True |
| + else: |
| + return tab.EvaluateJavaScript(code) |
| + |
| +def _EscapeSelector(selector): |
| + return selector.replace('\'', '\\\'') |