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 21import os 22 23from telemetry.internal.actions import page_action 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 for js_file in ['gesture_common.js', 'drag.js']: 48 with open(os.path.join(os.path.dirname(__file__), js_file)) as f: 49 js = f.read() 50 tab.ExecuteJavaScript(js) 51 52 # Fail if browser doesn't support synthetic drag gestures. 53 if not tab.EvaluateJavaScript('window.__DragAction_SupportedByBrowser()'): 54 raise page_action.PageActionNotSupported( 55 'Synthetic drag not supported for this browser') 56 57 # Fail if this action requires touch and we can't send touch events. 58 if self._use_touch: 59 if not page_action.IsGestureSourceTypeSupported(tab, 'touch'): 60 raise page_action.PageActionNotSupported( 61 'Touch drag not supported for this browser') 62 63 if (self._synthetic_gesture_source == 64 'chrome.gpuBenchmarking.MOUSE_INPUT'): 65 raise page_action.PageActionNotSupported( 66 'Drag requires touch on this page but mouse input was requested') 67 68 done_callback = 'function() { window.__dragActionDone = true; }' 69 tab.ExecuteJavaScript(''' 70 window.__dragActionDone = false; 71 window.__dragAction = new __DragAction(%s);''' 72 % done_callback) 73 74 def RunAction(self, tab): 75 if (self._selector is None and self._text is None and 76 self._element_function is None): 77 self._element_function = 'document.body' 78 79 gesture_source_type = 'chrome.gpuBenchmarking.TOUCH_INPUT' 80 if (page_action.IsGestureSourceTypeSupported(tab, 'mouse') and 81 not self._use_touch): 82 gesture_source_type = 'chrome.gpuBenchmarking.MOUSE_INPUT' 83 84 code = ''' 85 function(element, info) { 86 if (!element) { 87 throw Error('Cannot find element: ' + info); 88 } 89 window.__dragAction.start({ 90 element: element, 91 left_start_ratio: %s, 92 top_start_ratio: %s, 93 left_end_ratio: %s, 94 top_end_ratio: %s, 95 speed: %s, 96 gesture_source_type: %s 97 }); 98 }''' % (self._left_start_ratio, 99 self._top_start_ratio, 100 self._left_end_ratio, 101 self._top_end_ratio, 102 self._speed, 103 gesture_source_type) 104 page_action.EvaluateCallbackWithElement( 105 tab, code, selector=self._selector, text=self._text, 106 element_function=self._element_function) 107 tab.WaitForJavaScriptExpression('window.__dragActionDone', 60) 108