1# Copyright 2015 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"""A Telemetry page_action that performs the "drag" action on pages. 6 7Action parameters are: 8- selector: If no selector is defined then the action attempts to drag the 9 document element on the page. 10- element_function: CSS selector used to evaluate callback when test completes 11- text: The element with exact text is selected. 12- left_start_ratio: ratio of start point's left coordinate to the element 13 width. 14- top_start_ratio: ratio of start point's top coordinate to the element height. 15- left_end_ratio: ratio of end point's left coordinate to the element width. 16- left_end_ratio: ratio of end point's top coordinate to the element height. 17- speed_in_pixels_per_second: speed of the drag gesture in pixels per second. 18- use_touch: boolean value to specify if gesture should use touch input or not. 19""" 20 21from telemetry.internal.actions import page_action 22from telemetry.internal.actions import utils 23from telemetry.util import js_template 24 25 26class DragAction(page_action.PageAction): 27 28 def __init__(self, selector=None, text=None, element_function=None, 29 left_start_ratio=None, top_start_ratio=None, left_end_ratio=None, 30 top_end_ratio=None, speed_in_pixels_per_second=800, 31 use_touch=False, 32 synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT): 33 super(DragAction, self).__init__() 34 self._selector = selector 35 self._text = text 36 self._element_function = element_function 37 self._left_start_ratio = left_start_ratio 38 self._top_start_ratio = top_start_ratio 39 self._left_end_ratio = left_end_ratio 40 self._top_end_ratio = top_end_ratio 41 self._speed = speed_in_pixels_per_second 42 self._use_touch = use_touch 43 self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' % 44 synthetic_gesture_source) 45 46 def WillRunAction(self, tab): 47 utils.InjectJavaScript(tab, 'gesture_common.js') 48 utils.InjectJavaScript(tab, 'drag.js') 49 50 # Fail if browser doesn't support synthetic drag gestures. 51 if not tab.EvaluateJavaScript('window.__DragAction_SupportedByBrowser()'): 52 raise page_action.PageActionNotSupported( 53 'Synthetic drag not supported for this browser') 54 55 # Fail if this action requires touch and we can't send touch events. 56 if self._use_touch: 57 if not page_action.IsGestureSourceTypeSupported(tab, 'touch'): 58 raise page_action.PageActionNotSupported( 59 'Touch drag not supported for this browser') 60 61 if (self._synthetic_gesture_source == 62 'chrome.gpuBenchmarking.MOUSE_INPUT'): 63 raise page_action.PageActionNotSupported( 64 'Drag requires touch on this page but mouse input was requested') 65 66 tab.ExecuteJavaScript(''' 67 window.__dragActionDone = false; 68 window.__dragAction = new __DragAction(function() { 69 window.__dragActionDone = true; 70 });''') 71 72 def RunAction(self, tab): 73 if (self._selector is None and self._text is None and 74 self._element_function is None): 75 self._element_function = 'document.body' 76 77 gesture_source_type = 'chrome.gpuBenchmarking.TOUCH_INPUT' 78 if (page_action.IsGestureSourceTypeSupported(tab, 'mouse') and 79 not self._use_touch): 80 gesture_source_type = 'chrome.gpuBenchmarking.MOUSE_INPUT' 81 82 code = js_template.Render(''' 83 function(element, info) { 84 if (!element) { 85 throw Error('Cannot find element: ' + info); 86 } 87 window.__dragAction.start({ 88 element: element, 89 left_start_ratio: {{ left_start_ratio }}, 90 top_start_ratio: {{ top_start_ratio }}, 91 left_end_ratio: {{ left_end_ratio }}, 92 top_end_ratio: {{ top_end_ratio }}, 93 speed: {{ speed }}, 94 gesture_source_type: {{ @gesture_source_type }} 95 }); 96 }''', 97 left_start_ratio=self._left_start_ratio, 98 top_start_ratio=self._top_start_ratio, 99 left_end_ratio=self._left_end_ratio, 100 top_end_ratio=self._top_end_ratio, 101 speed=self._speed, 102 gesture_source_type=gesture_source_type) 103 page_action.EvaluateCallbackWithElement( 104 tab, code, selector=self._selector, text=self._text, 105 element_function=self._element_function) 106 tab.WaitForJavaScriptCondition('window.__dragActionDone', timeout=60) 107