blob: 3e17c84b6ae744a544f265c094875e9abd8526cf [file] [log] [blame]
# 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)