• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.internal.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               synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT):
17    super(ScrollAction, self).__init__()
18    if direction not in ('down', 'up', 'left', 'right',
19                         'downleft', 'downright',
20                         'upleft', 'upright'):
21      raise page_action.PageActionNotSupported(
22          'Invalid scroll direction: %s' % self.direction)
23    self._selector = selector
24    self._text = text
25    self._element_function = element_function
26    self._left_start_ratio = left_start_ratio
27    self._top_start_ratio = top_start_ratio
28    self._direction = direction
29    self._speed = speed_in_pixels_per_second
30    self._use_touch = use_touch
31    self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' %
32                                      synthetic_gesture_source)
33
34    self._distance_func = 'null'
35    if distance:
36      assert not distance_expr
37      distance_expr = str(distance)
38    if distance_expr:
39      self._distance_func = ('function() { return 0 + %s; }' %
40                             distance_expr)
41
42  def WillRunAction(self, tab):
43    if self._direction in ('downleft', 'downright', 'upleft', 'upright'):
44      # Diagonal scrolling support was added in Chrome branch number 2332.
45      branch_num = (
46          tab.browser._browser_backend.devtools_client.GetChromeBranchNumber())
47      if branch_num < 2332:
48        raise ValueError('Diagonal scrolling requires Chrome branch number'
49                         ' 2332 or later. Found branch number %d' %
50                         branch_num)
51    for js_file in ['gesture_common.js', 'scroll.js']:
52      with open(os.path.join(os.path.dirname(__file__), js_file)) as f:
53        js = f.read()
54        tab.ExecuteJavaScript(js)
55
56    # Fail if browser doesn't support synthetic scroll gestures.
57    if not tab.EvaluateJavaScript('window.__ScrollAction_SupportedByBrowser()'):
58      raise page_action.PageActionNotSupported(
59          'Synthetic scroll not supported for this browser')
60
61    # Fail if this action requires touch and we can't send touch events.
62    if self._use_touch:
63      if not page_action.IsGestureSourceTypeSupported(tab, 'touch'):
64        raise page_action.PageActionNotSupported(
65            'Touch scroll not supported for this browser')
66
67      if (self._synthetic_gesture_source ==
68          'chrome.gpuBenchmarking.MOUSE_INPUT'):
69        raise page_action.PageActionNotSupported(
70            'Scroll requires touch on this page but mouse input was requested')
71
72    done_callback = 'function() { window.__scrollActionDone = true; }'
73    tab.ExecuteJavaScript("""
74        window.__scrollActionDone = false;
75        window.__scrollAction = new __ScrollAction(%s, %s);"""
76        % (done_callback, self._distance_func))
77
78  def RunAction(self, tab):
79    if (self._selector is None and self._text is None and
80        self._element_function is None):
81      self._element_function = '(document.scrollingElement || document.body)'
82
83    gesture_source_type = self._synthetic_gesture_source
84    if self._use_touch:
85      gesture_source_type = 'chrome.gpuBenchmarking.TOUCH_INPUT'
86
87    code = '''
88        function(element, info) {
89          if (!element) {
90            throw Error('Cannot find element: ' + info);
91          }
92          window.__scrollAction.start({
93            element: element,
94            left_start_ratio: %s,
95            top_start_ratio: %s,
96            direction: '%s',
97            speed: %s,
98            gesture_source_type: %s
99          });
100        }''' % (self._left_start_ratio,
101                self._top_start_ratio,
102                self._direction,
103                self._speed,
104                gesture_source_type)
105    page_action.EvaluateCallbackWithElement(
106        tab, code, selector=self._selector, text=self._text,
107        element_function=self._element_function)
108    tab.WaitForJavaScriptExpression('window.__scrollActionDone', 60)
109