Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / page / actions / page_action.py
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
5 import re
6
7 from telemetry import decorators
8
9
10 class PageActionNotSupported(Exception):
11   pass
12
13 class PageActionFailed(Exception):
14   pass
15
16
17 class 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
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.
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
112 def _EscapeSelector(selector):
113   return selector.replace('\'', '\\\'')
114
115 def 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
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 ===
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()))