def set_viewport_size(driver, required_size): """ Tries to set the viewport size. :param driver: The webdriver to use for getting the viewport size. :param required_size: The size that the viewport size should be set to. :return: None. :raise EyesError: If the viewport size or browser couldn't be set. """ _BROWSER_SIZE_CALCULATION_RETRIES = 2 _BROWSER_SET_SIZE_RETRIES = 3 _BROWSER_STABILIZATION_WAIT = 1 # Seconds logger.debug("set_viewport_size({0})".format(required_size)) if 'width' not in required_size or 'height' not in required_size: raise EyesError('Size must have width & height keys!') actual_viewport_size = get_viewport_size(driver) logger.debug("Current viewport size: {}".format(actual_viewport_size)) if actual_viewport_size == required_size: return # If the browser was initially maximized, we might need to repeat the process (border size for maximized browser is # sometimes different than non-maximized). for _ in range(_BROWSER_SIZE_CALCULATION_RETRIES): # We move the window to (0,0) to have the best chance to be able to set the viewport size as requested. driver.set_window_position(0, 0) browser_size = driver.get_window_size() logger.debug("Current browser size: {}".format(browser_size)) required_browser_size = { 'width': browser_size['width'] + (required_size['width'] - actual_viewport_size['width']), 'height': browser_size['height'] + (required_size['height'] - actual_viewport_size['height']) } logger.debug( "Trying to set browser size to: {}".format(required_browser_size)) for retry in range(_BROWSER_SET_SIZE_RETRIES): driver.set_window_size(required_browser_size['width'], required_browser_size['height']) time.sleep(_BROWSER_STABILIZATION_WAIT) browser_size = driver.get_window_size() if (browser_size['width'] == required_browser_size['width'] and browser_size['height'] == required_browser_size['height']): break logger.debug("Current browser size: {}".format(browser_size)) else: raise EyesError('Failed to set browser size!') actual_viewport_size = get_viewport_size(driver) logger.debug("Current viewport size: {}".format(actual_viewport_size)) if actual_viewport_size == required_size: return else: raise EyesError('Failed to set the viewport size.')
def get_current_position(self): """ Extracts the current scroll position from the browser. Returns: (Point) The scroll position """ try: x, y = self._execute_script(self._JS_GET_CURRENT_SCROLL_POSITION) if x is None or y is None: raise EyesError("Got None as scroll position! ({},{})".format( x, y)) except WebDriverException: raise EyesError("Failed to extract current scroll position!") return Point(x, y)
def reset_origin(self): self._origin_position_provider.push_state() self._origin_position_provider.set_position(Point(0, 0)) current_scroll_position = self._origin_position_provider.get_current_position( ) if current_scroll_position.x != 0 or current_scroll_position.y != 0: self._origin_position_provider.pop_state() raise EyesError( "Couldn't scroll to the top/left part of the screen!")
def get_channel(self, index): """ Get the values for a specific color/alpha of the image's pixels. :param int index: The index of the channel we would like to get. :return iterable: A copy of the values for the given pixel channel. """ if index > self.pixel_size - 1: raise EyesError("Invalid channel: {}, (pixel size {})".format( index, self.pixel_size)) return map(lambda x: list(x[0::self.pixel_size]), self.pixel_bytes)
def get_subimage(self, region): """ :return PngImage: """ if region.is_empty(): raise EyesError('region is empty!') result_pixels = [] x_start = region.left * self.pixel_size x_end = x_start + (region.width * self.pixel_size) y_start = region.top for y_offset in range(region.height): pixels_row = self.pixel_bytes[y_start + y_offset][x_start:x_end] result_pixels.append(pixels_row) meta_info = copy.copy(self.meta_info) meta_info['size'] = (region.width, region.height) return PngImage(region.width, region.height, result_pixels, meta_info)
def __init__(self, driver, screenshot=None, screenshot64=None, is_viewport_screenshot=None, frame_location_in_screenshot=None): """ Initializes a Screenshot instance. Either screenshot or screenshot64 must NOT be None. Should not be used directly. Use create_from_image/create_from_base64 instead. Args: driver: EyesWebDriver instance which handles the session from which the screenshot was retrieved. (Optional) screenshot: (PngImage) image instance. If screenshot64 is None, this variable must NOT be none. (Optional) screenshot64: (str) The base64 representation of a png image. If screenshot is None, this variable must NOT be none. (Optional) frame_location_in_screenshot: (Point) The location of the frame relative to the top,left of the screenshot. (Optional) is_viewport_screenshot: (boolean) Whether the screenshot object represents a viewport screenshot or a full screenshot. """ self._screenshot64 = screenshot64 if screenshot: self._screenshot = screenshot elif screenshot64: self._screenshot = _image_utils.png_image_from_bytes( base64.b64decode(screenshot64)) else: raise EyesError("both screenshot and screenshot64 are None!") self._driver = driver self._viewport_size = driver.get_default_content_viewport_size() self._frame_chain = driver.get_frame_chain() if self._frame_chain: chain_len = len(self._frame_chain) self._frame_size = self._frame_chain[chain_len - 1].size else: try: self._frame_size = driver.get_entire_page_size() except WebDriverException: # For Appium, we can't get the "entire page size", so we use the viewport size. self._frame_size = self._viewport_size # For native Appium Apps we can't get the scroll position, so we use (0,0) try: self._scroll_position = driver.get_current_position() except WebDriverException: self._scroll_position = Point(0, 0) if is_viewport_screenshot is None: is_viewport_screenshot = self._screenshot.width <= self._viewport_size['width'] \ and self._screenshot.height <= self._viewport_size['height'] self._is_viewport_screenshot = is_viewport_screenshot if frame_location_in_screenshot is None: if self._frame_chain: frame_location_in_screenshot = EyesScreenshot \ .calc_frame_location_in_screenshot(self._frame_chain, is_viewport_screenshot) else: # The frame is the default content frame_location_in_screenshot = Point(0, 0) if self._is_viewport_screenshot: frame_location_in_screenshot.offset( -self._scroll_position.x, -self._scroll_position.y) self._frame_location_in_screenshot = frame_location_in_screenshot self._frame_screenshot_intersect = Region( frame_location_in_screenshot.x, frame_location_in_screenshot.y, self._frame_size['width'], self._frame_size['height']) self._frame_screenshot_intersect.intersect( Region(width=self._screenshot.width, height=self._screenshot.height))
def __setstate__(self, state): raise EyesError('Cannot create Point instance from dict!')