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. 4 5import re 6 7from telemetry import decorators 8 9 10class PageActionNotSupported(Exception): 11 pass 12 13class PageActionFailed(Exception): 14 pass 15 16 17class PageAction(object): 18 """Represents an action that a user might try to perform to a page.""" 19 20 def WillRunAction(self, tab): 21 """Override to do action-specific setup before 22 Test.WillRunAction is called.""" 23 pass 24 25 def RunAction(self, tab): 26 raise NotImplementedError() 27 28 def CleanUp(self, tab): 29 pass 30 31def 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. 35 36 The element may be selected via selector, text, or element_function. 37 Only one of these arguments must be specified. 38 39 Returns: 40 The callback's return value, if any. The return value must be 41 convertible to JSON. 42 43 Args: 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. 48 Example: ''' 49 function(element, info) { 50 if (!element) { 51 throw Error('Can not find element: ' + info); 52 } 53 element.click() 54 }''' 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). 62 """ 63 count = 0 64 info_msg = '' 65 if element_function is not None: 66 count = count + 1 67 info_msg = 'using element_function "%s"' % re.escape(element_function) 68 if selector is not None: 69 count = count + 1 70 info_msg = 'using selector "%s"' % _EscapeSelector(selector) 71 element_function = 'document.querySelector(\'%s\')' % _EscapeSelector( 72 selector) 73 if text is not None: 74 count = count + 1 75 info_msg = 'using exact text match "%s"' % re.escape(text) 76 element_function = ''' 77 (function() { 78 function _findElement(element, text) { 79 if (element.innerHTML == text) { 80 return element; 81 } 82 83 var childNodes = element.childNodes; 84 for (var i = 0, len = childNodes.length; i < len; ++i) { 85 var found = _findElement(childNodes[i], text); 86 if (found) { 87 return found; 88 } 89 } 90 return null; 91 } 92 return _findElement(document, '%s'); 93 })()''' % text 94 95 if count != 1: 96 raise PageActionFailed( 97 'Must specify 1 way to retrieve element, but %s was specified.' % count) 98 99 code = ''' 100 (function() { 101 var element = %s; 102 var callback = %s; 103 return callback(element, '%s'); 104 })()''' % (element_function, callback_js, info_msg) 105 106 if wait: 107 tab.WaitForJavaScriptExpression(code, timeout_in_seconds) 108 return True 109 else: 110 return tab.EvaluateJavaScript(code) 111 112def _EscapeSelector(selector): 113 return selector.replace('\'', '\\\'') 114 115def GetGestureSourceTypeFromOptions(tab): 116 gesture_source_type = tab.browser.synthetic_gesture_source_type 117 return 'chrome.gpuBenchmarking.' + gesture_source_type.upper() + '_INPUT' 118 119@decorators.Cache 120def 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 === 126 'undefined'"""): 127 return (tab.browser.platform.GetOSName() != 'mac' or 128 gesture_source_type.lower() != 'touch') 129 130 return tab.EvaluateJavaScript(""" 131 chrome.gpuBenchmarking.gestureSourceTypeSupported( 132 chrome.gpuBenchmarking.%s_INPUT)""" 133 % (gesture_source_type.upper())) 134