1 # Copyright 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
7 from telemetry import decorators
10 class PageActionNotSupported(Exception):
13 class PageActionFailed(Exception):
17 class PageAction(object):
18 """Represents an action that a user might try to perform to a page."""
20 def WillRunAction(self, tab):
21 """Override to do action-specific setup before
22 Test.WillRunAction is called."""
25 def RunAction(self, tab):
26 raise NotImplementedError()
28 def CleanUp(self, tab):
31 def EvaluateCallbackWithElement(
32 tab, callback_js, selector=None, text=None, element_function=None,
33 wait=False, timeout_in_seconds=60):
34 """Evaluates the JavaScript callback with the given element.
36 The element may be selected via selector, text, or element_function.
37 Only one of these arguments must be specified.
40 The callback's return value, if any. The return value must be
44 tab: A telemetry.core.Tab object.
45 callback_js: The JavaScript callback to call (as string).
46 The callback receive 2 parameters: the element, and information
47 string about what method was used to retrieve the element.
49 function(element, info) {
51 throw Error('Can not find element: ' + info);
55 selector: A CSS selector describing the element.
56 text: The element must contains this exact text.
57 element_function: A JavaScript function (as string) that is used
58 to retrieve the element. For example:
59 '(function() { return foo.element; })()'.
60 wait: Whether to wait for the return value to be true.
61 timeout_in_seconds: The timeout for wait (if waiting).
65 if element_function is not None:
67 info_msg = 'using element_function "%s"' % re.escape(element_function)
68 if selector is not None:
70 info_msg = 'using selector "%s"' % _EscapeSelector(selector)
71 element_function = 'document.querySelector(\'%s\')' % _EscapeSelector(
75 info_msg = 'using exact text match "%s"' % re.escape(text)
76 element_function = '''
78 function _findElement(element, text) {
79 if (element.innerHTML == text) {
83 var childNodes = element.childNodes;
84 for (var i = 0, len = childNodes.length; i < len; ++i) {
85 var found = _findElement(childNodes[i], text);
92 return _findElement(document, '%s');
96 raise PageActionFailed(
97 'Must specify 1 way to retrieve element, but %s was specified.' % count)
103 return callback(element, '%s');
104 })()''' % (element_function, callback_js, info_msg)
107 tab.WaitForJavaScriptExpression(code, timeout_in_seconds)
110 return tab.EvaluateJavaScript(code)
112 def _EscapeSelector(selector):
113 return selector.replace('\'', '\\\'')
115 def GetGestureSourceTypeFromOptions(tab):
116 gesture_source_type = tab.browser.synthetic_gesture_source_type
117 return 'chrome.gpuBenchmarking.' + gesture_source_type.upper() + '_INPUT'
120 def IsGestureSourceTypeSupported(tab, gesture_source_type):
121 # TODO(dominikg): remove once support for
122 # 'chrome.gpuBenchmarking.gestureSourceTypeSupported' has
123 # been rolled into reference build.
124 if tab.EvaluateJavaScript("""
125 typeof chrome.gpuBenchmarking.gestureSourceTypeSupported ===
127 return (tab.browser.platform.GetOSName() != 'mac' or
128 gesture_source_type.lower() != 'touch')
130 return tab.EvaluateJavaScript("""
131 chrome.gpuBenchmarking.gestureSourceTypeSupported(
132 chrome.gpuBenchmarking.%s_INPUT)"""
133 % (gesture_source_type.upper()))