1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
|
# Copyright 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from py_trace_event import trace_event
from telemetry import decorators
from telemetry.util import js_template
GESTURE_SOURCE_DEFAULT = 'DEFAULT'
GESTURE_SOURCE_MOUSE = 'MOUSE'
GESTURE_SOURCE_TOUCH = 'TOUCH'
SUPPORTED_GESTURE_SOURCES = (GESTURE_SOURCE_DEFAULT,
GESTURE_SOURCE_MOUSE,
GESTURE_SOURCE_TOUCH)
class PageActionNotSupported(Exception):
pass
class PageActionFailed(Exception):
pass
class PageAction(object):
"""Represents an action that a user might try to perform to a page."""
__metaclass__ = trace_event.TracedMetaClass
def WillRunAction(self, tab):
"""Override to do action-specific setup before
Test.WillRunAction is called."""
pass
def RunAction(self, tab):
raise NotImplementedError()
def CleanUp(self, tab):
pass
def EvaluateCallbackWithElement(
tab, callback_js, selector=None, text=None, element_function=None,
wait=False, timeout_in_seconds=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; })()'.
wait: Whether to wait for the return value to be true.
timeout_in_seconds: The timeout for wait (if waiting).
"""
count = 0
info_msg = ''
if element_function is not None:
count = count + 1
info_msg = js_template.Render(
'using element_function: {{ @code }}', code=element_function)
if selector is not None:
count = count + 1
info_msg = js_template.Render(
'using selector {{ selector }}', selector=selector)
element_function = js_template.Render(
'document.querySelector({{ selector }})', selector=selector)
if text is not None:
count = count + 1
info_msg = js_template.Render(
'using exact text match {{ text }}', text=text)
element_function = js_template.Render('''
(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, {{ text }});
})()''',
text=text)
if count != 1:
raise PageActionFailed(
'Must specify 1 way to retrieve element, but %s was specified.' % count)
code = js_template.Render('''
(function() {
var element = {{ @element_function }};
var callback = {{ @callback_js }};
return callback(element, {{ info_msg }});
})()''',
element_function=element_function,
callback_js=callback_js,
info_msg=info_msg)
if wait:
tab.WaitForJavaScriptExpression(code, timeout_in_seconds)
return True
else:
return tab.EvaluateJavaScript(code)
@decorators.Cache
def IsGestureSourceTypeSupported(tab, gesture_source_type):
# TODO(dominikg): remove once support for
# 'chrome.gpuBenchmarking.gestureSourceTypeSupported' has
# been rolled into reference build.
if tab.EvaluateJavaScript("""
typeof chrome.gpuBenchmarking.gestureSourceTypeSupported ===
'undefined'"""):
return (tab.browser.platform.GetOSName() != 'mac' or
gesture_source_type.lower() != 'touch')
# TODO(catapult:#3028): Render in JavaScript method when supported by API.
code = js_template.Render("""
chrome.gpuBenchmarking.gestureSourceTypeSupported(
chrome.gpuBenchmarking.{{ @gesture_source_type }}_INPUT)""",
gesture_source_type=gesture_source_type.upper())
return tab.EvaluateJavaScript(code)
|