| # Copyright 2021 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| import time |
| |
| from telemetry.internal.actions import page_action |
| from telemetry.page import shared_page_state |
| |
| from page_sets.rendering import rendering_story |
| from page_sets.rendering import story_tags |
| |
| TOUGH_SCROLLBAR_UMA = [ |
| 'Graphics.Smoothness.Checkerboarding4.CompositorThread.ScrollbarScroll', |
| ] |
| |
| |
| class ToughFastScrollbarScrollingPage(rendering_story.RenderingStory): |
| ABSTRACT_STORY = True |
| SPEED_IN_PIXELS_PER_SECOND = None |
| SYNTHETIC_GESTURE_SOURCE = page_action.GESTURE_SOURCE_MOUSE |
| TAGS = [story_tags.GPU_RASTERIZATION, story_tags.TOUGH_SCROLLBAR_SCROLLING] |
| |
| def __init__(self, |
| page_set, |
| shared_page_state_class=shared_page_state.SharedPageState, |
| name_suffix='', |
| extra_browser_args=None): |
| super(ToughFastScrollbarScrollingPage, |
| self).__init__(page_set=page_set, |
| shared_page_state_class=shared_page_state_class, |
| name_suffix=name_suffix, |
| extra_browser_args=extra_browser_args) |
| |
| def RunPageInteractions(self, action_runner): |
| scrollbar_x, scrollbar_top, scrollbar_bottom, top_button, bottom_button = \ |
| self._ScrollBarRatios(action_runner) |
| start = time.time() |
| with action_runner.CreateGestureInteraction('DragAction'): |
| direction = 'down' |
| while time.time() - start < 15: |
| if direction == 'down': |
| action_runner.DragPage( |
| left_start_ratio=scrollbar_x, |
| top_start_ratio=scrollbar_top, |
| left_end_ratio=scrollbar_x, |
| top_end_ratio=bottom_button, |
| speed_in_pixels_per_second=self.SPEED_IN_PIXELS_PER_SECOND) |
| else: |
| action_runner.DragPage( |
| left_start_ratio=scrollbar_x, |
| top_start_ratio=scrollbar_bottom, |
| left_end_ratio=scrollbar_x, |
| top_end_ratio=top_button, |
| speed_in_pixels_per_second=self.SPEED_IN_PIXELS_PER_SECOND) |
| direction = 'up' if direction == 'down' else 'down' |
| |
| def _ScrollBarRatios(self, action_runner): |
| # Calculate scrollbar thickness by adding an element to the page. |
| # Record the client width of that element, and then add a long child |
| # element so that the first element includes a scrollbar. Record the |
| # client width again and then calculate the difference to get the |
| # scrollbar thickness. |
| scrollbar_thickness = float( |
| action_runner.EvaluateJavaScript(''' |
| (function() { |
| window.__scrollableElementForTelemetry = document.scrollingElement; |
| var container = document.createElement("div"); |
| container.style.width = "100px"; |
| container.style.height = "100px"; |
| container.style.position = "absolute"; |
| container.style.visibility = "hidden"; |
| container.style.overflow = "auto"; |
| |
| document.body.appendChild(container); |
| |
| var widthBefore = container.clientWidth; |
| var longContent = document.createElement("div"); |
| longContent.style.height = "1000px"; |
| container.appendChild(longContent); |
| |
| var widthAfter = container.clientWidth; |
| |
| container.remove(); |
| |
| window.__scrollbarThickness = widthBefore - widthAfter; |
| return window.__scrollbarThickness; |
| })();''')) |
| window_width = float(action_runner.EvaluateJavaScript('window.innerWidth')) |
| window_height = float( |
| action_runner.EvaluateJavaScript('window.innerHeight')) |
| # Works only when there is no horizontally overflowing content. |
| left_margin = float( |
| action_runner.EvaluateJavaScript( |
| 'document.body.getBoundingClientRect().x')) |
| body_width = float( |
| action_runner.EvaluateJavaScript( |
| 'document.body.getBoundingClientRect().width')) |
| top_margin = float( |
| action_runner.EvaluateJavaScript( |
| 'document.body.getBoundingClientRect().y')) |
| window_height = window_height - top_margin |
| |
| # For regular scrollbars the minimal thumb length is one and two times the |
| # track's width in W10 and W11 respectively. For Fluent scrollbars the |
| # minimal thumb length is 17px. The constant was chosen such that: |
| # (Button Length) <= (Track width * |track_to_arrow_button_ratio|) <= |
| # (Button Length + Minimum thumb length) for all scrollbars. |
| track_to_arrow_button_ratio = 1.8 |
| top = (scrollbar_thickness * track_to_arrow_button_ratio - |
| top_margin) / (window_height) |
| bottom = 1 - (scrollbar_thickness * |
| track_to_arrow_button_ratio) / window_height |
| scrollbar_mid_x = (window_width - left_margin - |
| (scrollbar_thickness / 2)) / body_width |
| # Ensure the thumb goes through the full range of motion. These |
| # variables make the the mouse drag until the middle of the scrollbar |
| # buttons. |
| top_button = ((scrollbar_thickness / 2) - top_margin) / window_height |
| bottom_button = 1 - (scrollbar_thickness / 2) / window_height |
| return scrollbar_mid_x, top, bottom, top_button, bottom_button |
| |
| def WillStartTracing(self, chrome_trace_config): |
| chrome_trace_config.EnableUMAHistograms(*TOUGH_SCROLLBAR_UMA) |
| |
| |
| class ScrollbarScrollingText100Page(ToughFastScrollbarScrollingPage): |
| BASE_NAME = 'text_scrollbar_100_pixels_per_second' |
| URL = 'file://../tough_scrolling_cases/text.html' |
| SPEED_IN_PIXELS_PER_SECOND = 100 |
| |
| |
| class ScrollbarScrollingText200Page(ToughFastScrollbarScrollingPage): |
| BASE_NAME = 'text_scrollbar_200_pixels_per_second' |
| URL = 'file://../tough_scrolling_cases/text.html' |
| SPEED_IN_PIXELS_PER_SECOND = 400 |
| |
| |
| class ScrollbarScrollingText300Page(ToughFastScrollbarScrollingPage): |
| BASE_NAME = 'text_scrollbar_700_pixels_per_second' |
| URL = 'file://../tough_scrolling_cases/text.html' |
| SPEED_IN_PIXELS_PER_SECOND = 700 |
| |
| |
| class ScrollbarScrollingText1200Page(ToughFastScrollbarScrollingPage): |
| BASE_NAME = 'text_scrollbar_1200_pixels_per_second' |
| URL = 'file://../tough_scrolling_cases/text.html' |
| SPEED_IN_PIXELS_PER_SECOND = 1200 |
| |
| |
| class ScrollbarScrollingText2300Page(ToughFastScrollbarScrollingPage): |
| BASE_NAME = 'text_scrollbar_2300_pixels_per_second' |
| URL = 'file://../tough_scrolling_cases/text.html' |
| SPEED_IN_PIXELS_PER_SECOND = 2300 |