def __attrs_post_init__(self):
        # type: () -> None
        self._frame_chain = self._driver.frame_chain.clone()
        self._screenshot_type = update_screenshot_type(
            self._screenshot_type, self._image, self._driver
        )
        cur_frame_position_provider = self._driver.eyes.current_frame_position_provider
        if cur_frame_position_provider:
            position_provider = cur_frame_position_provider
        else:
            position_provider = self._driver.eyes.position_provider

        if self._current_frame_scroll_position is None:
            self._current_frame_scroll_position = get_updated_scroll_position(
                position_provider
            )
        self._frame_location_in_screenshot = self.get_updated_frame_location_in_screenshot(
            self._frame_location_in_screenshot
        )
        logger.debug("Calculating frame window...")

        if self.frame_window is None:
            frame_size = self.get_frame_size(position_provider)
            self.frame_window = Region.from_location_size(
                self._frame_location_in_screenshot, frame_size
            )
            self.frame_window.intersect(
                Region(0, 0, width=self.image.width, height=self.image.height)
            )
 def create_entire_frame(cls, driver, image, entire_frame_size):
     # type: (EyesWebDriver, Image.Image, RectangleSize) -> EyesWebDriverScreenshot
     return cls(
         driver,
         image,
         ScreenshotType.ENTIRE_FRAME,
         frame_location_in_screenshot=Point(0, 0),
         current_frame_scroll_position=Point(0, 0),
         frame_window=Region.from_location_size(Point(0, 0), entire_frame_size),
     )
示例#3
0
def _region_from_element(element, screenshot):
    location = element.location
    size = element.size
    if screenshot:
        # Element's coordinates are context relative, so we need to convert them first.
        adjusted_location = screenshot.location_in_screenshot(
            Point(location["x"], location["y"]),
            CoordinatesType.CONTEXT_RELATIVE)
    else:
        adjusted_location = Point(location["x"], location["y"])
    region = Region.from_location_size(adjusted_location, size)
    return region
 def from_screenshot(cls, driver, image, screenshot_region):
     # type: (EyesWebDriver, Image.Image, Region) -> EyesWebDriverScreenshot
     return cls(
         driver,
         image,
         ScreenshotType.ENTIRE_FRAME,
         Point.zero(),
         frame_window=Region.from_location_size(
             Point.zero(), screenshot_region.size
         ),
         region_window=Region.from_(screenshot_region),
     )
 def _get_viewport_scroll_bounds(self):
     switch_to = self.driver.switch_to
     with switch_to.frames_and_back(self.original_frame_chain):
         try:
             location = ScrollPositionProvider.get_current_position_static(
                 self.driver, self.scroll_root_element)
         except WebDriverException as e:
             logger.warning(str(e))
             logger.info("Assuming position is 0,0")
             location = Point(0, 0)
     viewport_bounds = Region.from_location_size(location,
                                                 self._get_viewport_size())
     return viewport_bounds
    def get_image(self):
        image = TakesScreenshotImageProvider(self._eyes).get_image()
        self._eyes.debug_screenshot_provider.save(image, "SAFARI")

        if self._eyes.is_cut_provider_explicitly_set:
            return image

        scale_ratio = self._eyes.device_pixel_ratio
        original_viewport_size = self._eyes._get_viewport_size()
        viewport_size = original_viewport_size.scale(scale_ratio)

        logger.info("logical viewport size: {}".format(original_viewport_size))

        if self._useragent.os == OSNames.IOS:
            if self._devices_regions is None:
                self.init_device_regions_table()

            logger.info("physical device pixel size: {} x {}".format(
                image.width, image.height))

            device_delta = DeviceData(
                image.width,
                image.height,
                original_viewport_size.width,
                original_viewport_size.height,
                self._useragent.browser_major_version,
            )
            if device_delta in self._devices_regions:
                logger.debug("device model found in hash table")
                crop = self._devices_regions.get(device_delta)
                image = image_utils.crop_image(image, crop)
            else:
                logger.debug(
                    "device not found in list. returning original image.")
        elif not self._eyes.configuration.force_full_page_screenshot:
            current_frame_chain = self._eyes.driver.frame_chain  # type: FrameChain

            if len(current_frame_chain) == 0:
                position_provider = ScrollPositionProvider(
                    self._eyes.driver,
                    self._eyes.driver.find_element_by_tag_name("html"),
                )
                loc = position_provider.get_current_position()
            else:
                loc = current_frame_chain.default_content_scroll_position

            loc = loc.scale(scale_ratio)
            image = image_utils.crop_image(
                image, Region.from_location_size(loc, viewport_size))
        return image
    def _ensure_frame_visible(self):
        logger.debug("scroll_root_element_: []".format(
            self._scroll_root_element))
        original_fc = self.driver.frame_chain.clone()
        fc = self.driver.frame_chain.clone()
        self.driver.execute_script("window.scrollTo(0,0);")
        origin_driver = eyes_selenium_utils.get_underlying_driver(self.driver)

        while len(fc) > 0:
            logger.debug("fc count: {}".format(fc.size))
            self.driver.switch_to.parent_frame_static(origin_driver.switch_to,
                                                      fc)
            self.driver.execute_script("window.scrollTo(0,0);")
            prev_frame = fc.pop()
            frame = fc.peek
            scroll_root_element = None
            if fc.size == original_fc.size:
                logger.debug("PositionProvider: {}".format(
                    self.position_provider))
                self.position_provider.push_state()
                scroll_root_element = self._scroll_root_element
            else:
                if frame:
                    scroll_root_element = frame.scroll_root_element
                if not scroll_root_element:
                    scroll_root_element = self.driver.find_element_by_tag_name(
                        "html")
            logger.debug("scroll_root_element {}".format(scroll_root_element))

            position_provider = self._element_position_provider_from(
                scroll_root_element)
            position_provider.set_position(prev_frame.location)
            reg = Region.from_location_size(Point.zero(),
                                            prev_frame.inner_size)
            self._effective_viewport.intersect(reg)
        self.driver.switch_to.frames(original_fc)
        return original_fc
    def get_stitched_region(self, region, full_area, position_provider):
        # type: (Region, Optional[Region], Optional[PositionProvider]) -> Image.Image
        argument_guard.not_none(region)
        argument_guard.not_none(position_provider)

        logger.info("get_stitched_region()")
        logger.info("PositionProvider: %s ; Region: %s" %
                    (position_provider, region))

        with self.origin_provider:
            self.origin_provider.set_position(
                Point.zero())  # first scroll to 0,0 so CSS stitching works.

            # Saving the original position (in case we were already in the outermost frame).
            with position_provider:
                logger.info("Getting top/left image...")
                image = self.image_provider.get_image()
                self.debug_screenshot_provider.save(
                    image, self._debug_msg("original"))
                pixel_ratio = self._get_pixel_ratio(image)
                scaled_cut_provider = self.cut_provider.scale(pixel_ratio)
                image = self._cut_if_needed(image, scaled_cut_provider)
                region_in_screenshot = self._get_region_in_screenshot(
                    region, image, pixel_ratio)
                image = self._crop_if_needed(image, region_in_screenshot)
                image = self._scale_if_needed(image, pixel_ratio)
                if full_area is None or full_area.is_empty:
                    entire_size = self._get_entire_size(
                        image, position_provider)
                    # Notice that this might still happen even if we used
                    # "get_image_part", since "entire_page_size" might be that of a
                    # frame
                    if (image.width >= entire_size.width
                            and image.height >= entire_size.height):
                        return image

                    full_area = Region.from_location_size(
                        Point.zero(), entire_size)

                image_parts = self._get_image_parts(full_area, image)

                stitched_image = self._create_stitched_image(full_area, image)
                # These will be used for storing the actual stitched size (it is
                # sometimes less than the size extracted via "get_entire_size").
                last_successful_location = Point.zero()
                last_successful_part_size = RectangleSize.from_(image)

                # Take screenshot and stitch for each screenshot part
                logger.debug("Getting the rest of the image parts...")
                part_image = None
                for part_region in image_parts:
                    logger.debug("Taking screenshot for %s" % part_region)

                    # Scroll to the part's top/left
                    origin_position = position_provider.set_position(
                        part_region.location)
                    target_position = origin_position.offset(
                        -full_area.left, -full_area.top)
                    logger.debug("Origin Position is set to %s" %
                                 origin_position)
                    logger.debug("Target Position is %s" % target_position)

                    # Actually taking the screenshot.
                    logger.debug("Getting image...")
                    part_image = self.image_provider.get_image()
                    self.debug_screenshot_provider.save(
                        part_image,
                        self._debug_msg("original-scrolled-{}".format(
                            position_provider.get_current_position())),
                    )
                    part_image = self._cut_if_needed(part_image,
                                                     scaled_cut_provider)
                    part_image = self._crop_if_needed(part_image,
                                                      region_in_screenshot)
                    part_image = self._scale_if_needed(part_image, pixel_ratio)

                    # Stitching the current part.
                    stitched_image.paste(part_image,
                                         box=(target_position.x,
                                              target_position.y))
                    last_successful_location = origin_position

                if part_image:
                    last_successful_part_size = RectangleSize.from_(part_image)

            logger.info("Stitching done!")
        # If the actual image size is smaller than the extracted size, we crop the image.
        stitched_image = self._crop_if_smaller(
            full_area,
            last_successful_location,
            last_successful_part_size,
            stitched_image,
        )

        self.debug_screenshot_provider.save(stitched_image,
                                            self._debug_msg("stitched"))
        return stitched_image