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.
4
5import os
6
7from telemetry.internal.actions import scroll
8from telemetry.testing import tab_test_case
9
10class ScrollActionTest(tab_test_case.TabTestCase):
11  def testScrollAction(self):
12    self.Navigate('blank.html')
13
14    # Make page bigger than window so it's scrollable.
15    self._tab.ExecuteJavaScript("""document.body.style.height =
16                              (2 * window.innerHeight + 1) + 'px';""")
17
18    self.assertEquals(
19        self._tab.EvaluateJavaScript("""document.documentElement.scrollTop
20                                   || document.body.scrollTop"""), 0)
21
22    i = scroll.ScrollAction()
23    i.WillRunAction(self._tab)
24
25    self._tab.ExecuteJavaScript("""
26        window.__scrollAction.beginMeasuringHook = function() {
27            window.__didBeginMeasuring = true;
28        };
29        window.__scrollAction.endMeasuringHook = function() {
30            window.__didEndMeasuring = true;
31        };""")
32    i.RunAction(self._tab)
33
34    self.assertTrue(self._tab.EvaluateJavaScript('window.__didBeginMeasuring'))
35    self.assertTrue(self._tab.EvaluateJavaScript('window.__didEndMeasuring'))
36
37    scroll_position = self._tab.EvaluateJavaScript(
38        '(document.documentElement.scrollTop || document.body.scrollTop)')
39    self.assertTrue(scroll_position != 0,
40                    msg='scroll_position=%d;' % (scroll_position))
41
42  def testDiagonalScrollAction(self):
43    # Diagonal scrolling was not supported in the ScrollAction until Chrome
44    # branch number 2332
45    branch_num = self._tab.browser._browser_backend.devtools_client \
46        .GetChromeBranchNumber()
47    if branch_num < 2332:
48      return
49
50    self.Navigate('blank.html')
51
52    # Make page bigger than window so it's scrollable.
53    self._tab.ExecuteJavaScript("""document.body.style.height =
54                              (2 * window.innerHeight + 1) + 'px';""")
55    self._tab.ExecuteJavaScript("""document.body.style.width =
56                              (2 * window.innerWidth + 1) + 'px';""")
57
58    self.assertEquals(
59        self._tab.EvaluateJavaScript("""document.documentElement.scrollTop
60                                   || document.body.scrollTop"""), 0)
61    self.assertEquals(
62        self._tab.EvaluateJavaScript("""document.documentElement.scrollLeft
63                                   || document.body.scrollLeft"""), 0)
64
65    i = scroll.ScrollAction(direction='downright')
66    i.WillRunAction(self._tab)
67
68    i.RunAction(self._tab)
69
70    viewport_top = self._tab.EvaluateJavaScript(
71        '(document.documentElement.scrollTop || document.body.scrollTop)')
72    self.assertTrue(viewport_top != 0, msg='viewport_top=%d;' % viewport_top)
73
74    viewport_left = self._tab.EvaluateJavaScript(
75        '(document.documentElement.scrollLeft || document.body.scrollLeft)')
76    self.assertTrue(viewport_left != 0, msg='viewport_left=%d;' % viewport_left)
77
78  def testBoundingClientRect(self):
79    self.Navigate('blank.html')
80
81    with open(os.path.join(os.path.dirname(__file__),
82                           'gesture_common.js')) as f:
83      js = f.read()
84      self._tab.ExecuteJavaScript(js)
85
86    # Verify that the rect returned by getBoundingVisibleRect() in scroll.js is
87    # completely contained within the viewport. Scroll events dispatched by the
88    # scrolling API use the center of this rect as their location, and this
89    # location needs to be within the viewport bounds to correctly decide
90    # between main-thread and impl-thread scroll. If the scrollable area were
91    # not clipped to the viewport bounds, then the instance used here (the
92    # scrollable area being more than twice as tall as the viewport) would
93    # result in a scroll location outside of the viewport bounds.
94    self._tab.ExecuteJavaScript("""document.body.style.height =
95                           (3 * window.innerHeight + 1) + 'px';""")
96    self._tab.ExecuteJavaScript("""document.body.style.width =
97                           (3 * window.innerWidth + 1) + 'px';""")
98    self._tab.ExecuteJavaScript(
99        "window.scrollTo(window.innerWidth, window.innerHeight);")
100
101    rect_top = int(self._tab.EvaluateJavaScript(
102        '__GestureCommon_GetBoundingVisibleRect(document.body).top'))
103    rect_height = int(self._tab.EvaluateJavaScript(
104        '__GestureCommon_GetBoundingVisibleRect(document.body).height'))
105    rect_bottom = rect_top + rect_height
106
107    rect_left = int(self._tab.EvaluateJavaScript(
108        '__GestureCommon_GetBoundingVisibleRect(document.body).left'))
109    rect_width = int(self._tab.EvaluateJavaScript(
110        '__GestureCommon_GetBoundingVisibleRect(document.body).width'))
111    rect_right = rect_left + rect_width
112
113    viewport_height = int(self._tab.EvaluateJavaScript('window.innerHeight'))
114    viewport_width = int(self._tab.EvaluateJavaScript('window.innerWidth'))
115
116    self.assertTrue(rect_top >= 0,
117        msg='%s >= %s' % (rect_top, 0))
118    self.assertTrue(rect_left >= 0,
119        msg='%s >= %s' % (rect_left, 0))
120    self.assertTrue(rect_bottom <= viewport_height,
121        msg='%s + %s <= %s' % (rect_top, rect_height, viewport_height))
122    self.assertTrue(rect_right <= viewport_width,
123        msg='%s + %s <= %s' % (rect_left, rect_width, viewport_width))
124