def get_current_position(self): 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 get_entire_size(self): try: size = {'width': self._element.get_scroll_width(), 'height': self._element.get_scroll_height()} except WebDriverException: raise EyesError('Failed to extract entire size!') logger.info("ElementPositionProvider - Entire size: {}".format(size)) return size
def get_entire_size(self): """ :return: The entire size of the container which the position is relative to. """ try: width, height = self._driver.execute_script(self._JS_GET_CONTENT_ENTIRE_SIZE) except WebDriverException: raise EyesError('Failed to extract entire size!') return dict(width=width, height=height)
def get_current_frame_content_entire_size(driver): # type: (AnyWebDriver) -> ViewPort """ :return: The size of the entire content. """ try: width, height = driver.execute_script(_JS_GET_CONTENT_ENTIRE_SIZE) except WebDriverException: raise EyesError("Failed to extract entire size!") return dict(width=width, height=height)
def _get_position_from_transform(self, transform): data = re.match(r"^translate\(\s*(\-?)([\d, \.]+)px,\s*(\-?)([\d, \.]+)px\s*\)", transform) if not data: raise EyesError("Can't parse CSS transition") x = float(data.group(2)) y = float(data.group(4)) minus_x, minus_y = data.group(1), data.group(3) if minus_x: x *= -1 if minus_y: y *= -1 return Point(float(x), float(y))
def _check_image(self, name, ignore_mismatch, target): # type: (Text, bool, Target) -> bool # Set the title to be linked to the screenshot. self._raw_title = name if name else "" if not self.is_open: self.abort_if_not_closed() raise EyesError("you must call open() before checking") image = target.values.image # type: Image.Image timeout = 0 # run match_window once self._screenshot = EyesImagesScreenshot(image) if not self._viewport_size: self.set_viewport_size(dict(width=image.width, height=image.height)) match_result = self._check_window_base(name, timeout, target, ignore_mismatch) self._screenshot = None self._raw_title = None return match_result["as_expected"]
def __init__(self, driver, screenshot=None, screenshot64=None, is_viewport_screenshot=None, frame_location_in_screenshot=None): # type: (EyesWebDriver, Image.Image, None, tp.Optional[bool], tp.Optional[Point]) -> 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. :param driver: EyesWebDriver instance which handles the session from which the screenshot was retrieved. :param screenshot: image instance. If screenshot64 is None, this variable must NOT be none. :param screenshot64: The base64 representation of a png image. If screenshot is None, this variable must NOT be none. :param is_viewport_screenshot: Whether the screenshot object represents a viewport screenshot or a full screenshot. :param frame_location_in_screenshot: The location of the frame relative to the top,left of the screenshot. :raise EyesError: If the screenshots are None. """ if screenshot is None and screenshot64 is None: raise EyesError("both screenshot and screenshot64 are None!") if screenshot64: screenshot = image_utils.image_from_bytes( base64.b64decode(screenshot64)) # initializing of screenshot super(EyesWebDriverScreenshot, self).__init__(image=screenshot) self._driver = driver self._viewport_size = driver.get_default_content_viewport_size( force_query=False) # type: ViewPort self._frame_chain = driver.frame_chain.clone() if self._frame_chain: chain_len = len(self._frame_chain) self._frame_size = self._frame_chain[chain_len - 1].outer_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, EyesError): 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 = EyesWebDriverScreenshot \ .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 default_content_scroll_position(self): # type: () -> tp.Union[Point, EyesError] if len(self) == 0: raise EyesError("No frames in frame chain") result = self[0].parent_scroll_position return Point(result.x, result.y)
def set_viewport_size(driver, required_size): # type: (AnyWebDriver, ViewPort) -> None logger.info("set_viewport_size({})".format(str(required_size))) actual_viewport_size = get_viewport_size(driver) if actual_viewport_size == required_size: logger.info("Required size already set.") return None try: # 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) except WebDriverException: logger.info("Warning: Failed to move the browser window to (0,0)") set_browser_size_by_viewport_size(driver, actual_viewport_size, required_size) actual_viewport_size = get_viewport_size(driver) if actual_viewport_size == required_size: return None # Additional attempt. This Solves the "maximized browser" bug # (border size for maximized browser sometimes different than # non-maximized, so the original browser size calculation is # wrong). logger.info("Trying workaround for maximization...") set_browser_size_by_viewport_size(driver, actual_viewport_size, required_size) actual_viewport_size = get_viewport_size(driver) logger.debug("Current viewport size: {}".format(actual_viewport_size)) if actual_viewport_size == required_size: return None width_diff = abs(actual_viewport_size["width"] - required_size["width"]) width_step = -1 if width_diff > 0 else 1 # -1 for smaller size, 1 for larger height_diff = abs(actual_viewport_size["height"] - required_size["height"]) height_step = -1 if height_diff > 0 else 1 browser_size = get_window_size(driver) curr_width_change = 0 curr_height_change = 0 if width_diff <= _MAX_DIFF and height_diff <= _MAX_DIFF: logger.info("Trying workaround for zoom...") last_required_browser_size = None while (abs(curr_width_change) <= width_diff and abs(curr_height_change) <= height_diff): if abs(curr_width_change) <= width_diff: curr_width_change += width_step if abs(curr_height_change) <= height_diff: curr_height_change += height_step required_browser_size = dict( width=browser_size["width"] + curr_width_change, height=browser_size["height"] + curr_height_change, ) if required_browser_size == last_required_browser_size: logger.info( "Browser size is as required but viewport size does not match!" ) logger.info("Browser size: {}, Viewport size: {}".format( required_browser_size, actual_viewport_size)) logger.info("Stopping viewport size attempts.") break set_browser_size(driver, required_browser_size) last_required_browser_size = required_browser_size actual_viewport_size = get_viewport_size(driver) logger.info( "Current viewport size: {}".format(actual_viewport_size)) if actual_viewport_size == required_size: return None else: logger.info("Zoom workaround failed.") raise EyesError("Failed to set the viewport size.")