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. 4import os 5 6from telemetry.page.actions import page_action 7 8 9class ScrollAction(page_action.PageAction): 10 # TODO(chrishenry): Ignore attributes, to be deleted when usage in 11 # other repo is cleaned up. 12 def __init__(self, selector=None, text=None, element_function=None, 13 left_start_ratio=0.5, top_start_ratio=0.5, direction='down', 14 distance=None, distance_expr=None, 15 speed_in_pixels_per_second=800, use_touch=False): 16 super(ScrollAction, self).__init__() 17 if direction not in ['down', 'up', 'left', 'right']: 18 raise page_action.PageActionNotSupported( 19 'Invalid scroll direction: %s' % self.direction) 20 self._selector = selector 21 self._text = text 22 self._element_function = element_function 23 self._left_start_ratio = left_start_ratio 24 self._top_start_ratio = top_start_ratio 25 self._direction = direction 26 self._speed = speed_in_pixels_per_second 27 self._use_touch = use_touch 28 29 self._distance_func = 'null' 30 if distance: 31 assert not distance_expr 32 distance_expr = str(distance) 33 if distance_expr: 34 self._distance_func = ('function() { return 0 + %s; }' % 35 distance_expr) 36 37 def WillRunAction(self, tab): 38 for js_file in ['gesture_common.js', 'scroll.js']: 39 with open(os.path.join(os.path.dirname(__file__), js_file)) as f: 40 js = f.read() 41 tab.ExecuteJavaScript(js) 42 43 # Fail if browser doesn't support synthetic scroll gestures. 44 if not tab.EvaluateJavaScript('window.__ScrollAction_SupportedByBrowser()'): 45 raise page_action.PageActionNotSupported( 46 'Synthetic scroll not supported for this browser') 47 48 # Fail if this action requires touch and we can't send touch events. 49 if self._use_touch: 50 if not page_action.IsGestureSourceTypeSupported(tab, 'touch'): 51 raise page_action.PageActionNotSupported( 52 'Touch scroll not supported for this browser') 53 54 if (page_action.GetGestureSourceTypeFromOptions(tab) == 55 'chrome.gpuBenchmarking.MOUSE_INPUT'): 56 raise page_action.PageActionNotSupported( 57 'Scroll requires touch on this page but mouse input was requested') 58 59 done_callback = 'function() { window.__scrollActionDone = true; }' 60 tab.ExecuteJavaScript(""" 61 window.__scrollActionDone = false; 62 window.__scrollAction = new __ScrollAction(%s, %s);""" 63 % (done_callback, self._distance_func)) 64 65 def RunAction(self, tab): 66 if (self._selector is None and self._text is None and 67 self._element_function is None): 68 self._element_function = 'document.body' 69 70 gesture_source_type = page_action.GetGestureSourceTypeFromOptions(tab) 71 if self._use_touch: 72 gesture_source_type = 'chrome.gpuBenchmarking.TOUCH_INPUT' 73 74 code = ''' 75 function(element, info) { 76 if (!element) { 77 throw Error('Cannot find element: ' + info); 78 } 79 window.__scrollAction.start({ 80 element: element, 81 left_start_ratio: %s, 82 top_start_ratio: %s, 83 direction: '%s', 84 speed: %s, 85 gesture_source_type: %s 86 }); 87 }''' % (self._left_start_ratio, 88 self._top_start_ratio, 89 self._direction, 90 self._speed, 91 gesture_source_type) 92 page_action.EvaluateCallbackWithElement( 93 tab, code, selector=self._selector, text=self._text, 94 element_function=self._element_function) 95 tab.WaitForJavaScriptExpression('window.__scrollActionDone', 60) 96