def ScrollElement(self, selector=None, text=None, element_function=None, left_start_ratio=0.5, top_start_ratio=0.5, direction='down', distance=None, distance_expr=None, speed_in_pixels_per_second=800, use_touch=False, synthetic_gesture_source=GESTURE_SOURCE_DEFAULT): """Perform scroll gesture on the element. The element may be selected via selector, text, or element_function. Only one of these arguments must be specified. You may specify distance or distance_expr, but not both. If neither is specified, the default scroll distance is variable depending on direction (see scroll.js for full implementation). Args: selector: A CSS selector describing the element. text: The element must contains this exact text. element_function: A JavaScript function (as string) that is used to retrieve the element. For example: 'function() { return foo.element; }'. left_start_ratio: The horizontal starting coordinate of the gesture, as a ratio of the visible bounding rectangle for the element. top_start_ratio: The vertical starting coordinate of the gesture, as a ratio of the visible bounding rectangle for the element. direction: The direction of scroll, either 'left', 'right', 'up', 'down', 'upleft', 'upright', 'downleft', or 'downright' distance: The distance to scroll (in pixel). distance_expr: A JavaScript expression (as string) that can be evaluated to compute scroll distance. Example: 'window.scrollTop' or '(function() { return crazyMath(); })()'. speed_in_pixels_per_second: The speed of the gesture (in pixels/s). use_touch: Whether scrolling should be done with touch input. synthetic_gesture_source: the source input device type for the synthetic gesture: 'DEFAULT', 'TOUCH' or 'MOUSE'. """ assert synthetic_gesture_source in SUPPORTED_GESTURE_SOURCES self._RunAction( ScrollAction(selector=selector, text=text, element_function=element_function, left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio, direction=direction, distance=distance, distance_expr=distance_expr, speed_in_pixels_per_second=speed_in_pixels_per_second, use_touch=use_touch, synthetic_gesture_source=synthetic_gesture_source))
def WillRunAction(self, tab): if self._selector: element = js_template.Render( 'document.querySelector({{ selector }})', selector=self._selector) else: element = self._element_function # TODO(catapult:#3028): Render in JavaScript method when supported by API. get_distance_js = js_template.Render(''' (function(elem){ var rect = elem.getBoundingClientRect(); if (rect.bottom < 0) { // The bottom of the element is above the viewport. // Scroll up until the top of the element is on screen. return rect.top - (window.innerHeight / 2); } if (rect.top - window.innerHeight >= 0) { // rect.top provides the pixel offset of the element from the // top of the page. Because that exceeds the viewport's height, // we know that the element is below the viewport. return rect.top - (window.innerHeight / 2); } return 0; })({{ @element }}); ''', element=element) self._distance = tab.EvaluateJavaScript(get_distance_js) self._direction = 'down' if self._distance > 0 else 'up' self._distance = abs(self._distance) self._scroller = ScrollAction( direction=self._direction, selector=self._container_selector, element_function=self._container_element_function, distance=self._distance, speed_in_pixels_per_second=self._speed)
def ScrollPage(self, left_start_ratio=0.5, top_start_ratio=0.5, direction='down', distance=None, distance_expr=None, speed_in_pixels_per_second=800, use_touch=False, synthetic_gesture_source=GESTURE_SOURCE_DEFAULT): """Perform scroll gesture on the page. You may specify distance or distance_expr, but not both. If neither is specified, the default scroll distance is variable depending on direction (see scroll.js for full implementation). Args: left_start_ratio: The horizontal starting coordinate of the gesture, as a ratio of the visible bounding rectangle for document.body. top_start_ratio: The vertical starting coordinate of the gesture, as a ratio of the visible bounding rectangle for document.body. direction: The direction of scroll, either 'left', 'right', 'up', 'down', 'upleft', 'upright', 'downleft', or 'downright' distance: The distance to scroll (in pixel). distance_expr: A JavaScript expression (as string) that can be evaluated to compute scroll distance. Example: 'window.scrollTop' or '(function() { return crazyMath(); })()'. speed_in_pixels_per_second: The speed of the gesture (in pixels/s). use_touch: Whether scrolling should be done with touch input. synthetic_gesture_source: the source input device type for the synthetic gesture: 'DEFAULT', 'TOUCH' or 'MOUSE'. """ assert synthetic_gesture_source in SUPPORTED_GESTURE_SOURCES self._RunAction( ScrollAction(left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio, direction=direction, distance=distance, distance_expr=distance_expr, speed_in_pixels_per_second=speed_in_pixels_per_second, use_touch=use_touch, synthetic_gesture_source=synthetic_gesture_source))
class ScrollToElementAction(page_action.PageAction): def __init__(self, selector=None, element_function=None, container_selector=None, container_element_function=None, speed_in_pixels_per_second=800): """Perform scroll gesture on container until an element is in view. Both the element and the container can be specified by a CSS selector xor a JavaScript function, provided as a string, which returns an element. The element is required so exactly one of selector and element_function must be provided. The container is optional so at most one of container_selector and container_element_function can be provided. The container defaults to document.scrollingElement or document.body if scrollingElement is not set. Args: selector: A CSS selector describing the element. element_function: A JavaScript function (as string) that is used to retrieve the element. For example: 'function() { return foo.element; }'. container_selector: A CSS selector describing the container element. container_element_function: A JavaScript function (as a string) that is used to retrieve the container element. speed_in_pixels_per_second: Speed to scroll. """ super(ScrollToElementAction, self).__init__() self._selector = selector self._element_function = element_function self._container_selector = container_selector self._container_element_function = container_element_function self._speed = speed_in_pixels_per_second self._distance = None self._direction = None self._scroller = None assert (self._selector or self._element_function), ( 'Must have either selector or element function') def WillRunAction(self, tab): if self._selector: element = js_template.Render( 'document.querySelector({{ selector }})', selector=self._selector) else: element = self._element_function self._distance = tab.EvaluateJavaScript(''' (function(elem){ var rect = elem.getBoundingClientRect(); if (rect.bottom < 0) { // The bottom of the element is above the viewport. // Scroll up until the top of the element is on screen. return rect.top - (window.innerHeight / 2); } if (rect.top - window.innerHeight >= 0) { // rect.top provides the pixel offset of the element from the // top of the page. Because that exceeds the viewport's height, // we know that the element is below the viewport. return rect.top - (window.innerHeight / 2); } return 0; })({{ @element }}); ''', element=element) self._direction = 'down' if self._distance > 0 else 'up' self._distance = abs(self._distance) self._scroller = ScrollAction( direction=self._direction, selector=self._container_selector, element_function=self._container_element_function, distance=self._distance, speed_in_pixels_per_second=self._speed) def RunAction(self, tab): if self._distance == 0: # Element is already in view. return self._scroller.WillRunAction(tab) self._scroller.RunAction(tab)