Exemple #1
0
 def set_position(self, location):
     if self._element:
         element_location = self._element.location  # scroll to element
         if Point.from_(location) == element_location:
             # hide header which hides actual element
             self._driver.execute_script(
                 "arguments[0].style.transform='translate(0px,0px)';",
                 self._scroll_root_element,
             )
             return Point.from_(element_location)
     return super(CSSMobileSafariPositionProvider,
                  self).set_position(location)
Exemple #2
0
def parse_location_string(position):
    # type: (Union[Text, Dict]) -> Point
    if isinstance(position, dict):
        return Point.from_(position)
    xy = position.split(";")
    if len(xy) != 2:
        raise WebDriverException("Could not get scroll position!")
    return Point(round(float(xy[0])), round(float(xy[1])))
    def convert_location(self, location, from_, to):  # noqa: C901
        # type: (Point, CoordinatesType, CoordinatesType) -> Point
        argument_guard.not_none(location)
        argument_guard.not_none(from_)
        argument_guard.not_none(to)

        result = Point.from_(location)
        if from_ == to:
            return result

        # If we're not inside a frame, and the screenshot is the entire
        # page, then the context as-is/relative are the same (notice
        # screenshot as-is might be different, e.g.,
        # if it is actually a sub-screenshot of a region).
        if (len(self.frame_chain) == 0
                and self._screenshot_type == ScreenshotType.ENTIRE_FRAME):
            if (from_ == self.CONTEXT_RELATIVE or from_
                    == self.CONTEXT_AS_IS) and to == self.SCREENSHOT_AS_IS:
                # If this is not a sub-screenshot, this will have no effect.
                result = result.offset(self._frame_location_in_screenshot)
                # If this is not a region subscreenshot, this will have no effect.
                result = result.offset(-self.region_window.left,
                                       -self.region_window.top)
            elif from_ == self.SCREENSHOT_AS_IS and (
                    to == self.CONTEXT_RELATIVE or to == self.CONTEXT_AS_IS):
                result = result.offset(-self._frame_location_in_screenshot)
            return result

        if from_ == self.CONTEXT_AS_IS:
            if to == self.CONTEXT_RELATIVE:
                result = result.offset(self._current_frame_scroll_position)
            elif to == self.SCREENSHOT_AS_IS:
                result = result.offset(self._frame_location_in_screenshot)
            else:
                raise CoordinatesTypeConversionError(from_, to)
        elif from_ == self.CONTEXT_RELATIVE:
            if to == self.SCREENSHOT_AS_IS:
                # First, convert context-relative to context-as-is.
                result = result.offset(-self._current_frame_scroll_position)
                # Now convert context-as-is to screenshot-as-is
                result = result.offset(self._frame_location_in_screenshot)
            elif to == self.CONTEXT_AS_IS:
                result = result.offset(-self._current_frame_scroll_position)
            else:
                raise CoordinatesTypeConversionError(from_, to)
        elif from_ == self.SCREENSHOT_AS_IS:
            if to == self.CONTEXT_RELATIVE:
                # First, convert context-relative to context-as-is.
                result = result.offset(-self._frame_location_in_screenshot)
                # Now convert context-as-is to screenshot-as-is
                result = result.offset(self._current_frame_scroll_position)
            elif to == self.CONTEXT_AS_IS:
                result = result.offset(-self._frame_location_in_screenshot)
            else:
                raise CoordinatesTypeConversionError(from_, to)
        else:
            raise CoordinatesTypeConversionError(from_, to)
        return result
def calc_frame_location_in_screenshot(driver, frame_chain, screenshot_type):
    window_scroll = eyes_selenium_utils.get_default_content_scroll_position(
        frame_chain, driver)
    logger.info("Getting first frame...")
    first_frame = frame_chain[0]
    location_in_screenshot = Point.from_(first_frame.location)

    # We only need to consider the scroll of the default content if the screenshot is a
    # viewport screenshot. If this is a full page screenshot, the frame location will
    # not change anyway.
    if screenshot_type == ScreenshotType.VIEWPORT:
        location_in_screenshot = location_in_screenshot.offset(
            Point(-window_scroll.x, 0))

    # For inner frames we must calculate the scroll
    inner_frames = frame_chain[1:]
    for frame in inner_frames:
        location_in_screenshot = location_in_screenshot.offset(
            frame.location - frame.parent_scroll_position)
    return location_in_screenshot
Exemple #5
0
    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(
            "region: %s ; full_area: %s ; position_provider: %s"
            % (region, full_area, position_provider.__class__.__name__)
        )

        origin_state = self.origin_provider.get_state()

        if self.origin_provider != position_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).
        original_stitched_state = position_provider.get_state()

        datetime_utils.sleep(self.wait_before_screenshots)
        initial_screenshot = self.image_provider.get_image()
        initial_size = RectangleSize.from_(initial_screenshot)

        pixel_ratio = self._get_pixel_ratio(initial_screenshot)
        scaled_cut_provider = self.cut_provider.scale(pixel_ratio)
        cutted_initial_screenshot = self._cut_if_needed(
            initial_screenshot, scaled_cut_provider
        )
        self.debug_screenshot_provider.save(
            cutted_initial_screenshot, self._debug_msg("cutted_initial_screenshot")
        )

        region_in_initial_screenshot = self._get_region_in_screenshot(
            region, cutted_initial_screenshot, pixel_ratio
        )
        cropped_initial_screenshot = self._crop_if_needed(
            cutted_initial_screenshot, region_in_initial_screenshot
        )
        self.debug_screenshot_provider.save(
            cropped_initial_screenshot, self._debug_msg("cropped_initial_screenshot")
        )

        scaled_initial_screenshot = image_utils.scale_image(
            cropped_initial_screenshot, self.scale_provider
        )
        self.debug_screenshot_provider.save(
            scaled_initial_screenshot, self._debug_msg("scaled_initial_screenshot")
        )
        if full_area is None or full_area.is_empty:
            entire_size = self._get_entire_size(initial_screenshot, 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 (
                scaled_initial_screenshot.width >= entire_size.width
                and scaled_initial_screenshot.height >= entire_size.height
            ):
                self.origin_provider.restore_state(origin_state)
                return scaled_initial_screenshot

            full_area = Region.from_(Point.ZERO(), entire_size)

        scaled_cropped_location = full_area.location
        physical_crop_location = Point.from_(scaled_cropped_location).scale(pixel_ratio)

        if region_in_initial_screenshot.is_empty:
            physical_crop_size = RectangleSize(
                initial_size.width - physical_crop_location.x,
                initial_size.height - physical_crop_location.y,
            )
            source_region = Region.from_(physical_crop_location, physical_crop_size)
        else:
            # Starting with the screenshot we already captured at (0,0).
            source_region = region_in_initial_screenshot

        scaled_cropped_source_rect = self.cut_provider.to_region(source_region.size)
        scaled_cropped_source_rect = scaled_cropped_source_rect.offset(
            source_region.left, source_region.top
        )
        scaled_cropped_source_region = dict(
            x=int(math.ceil(scaled_cropped_source_rect.left / pixel_ratio)),
            y=int(math.ceil(scaled_cropped_source_rect.top / pixel_ratio)),
            width=int(math.ceil(scaled_cropped_source_rect.width / pixel_ratio)),
            height=int(math.ceil(scaled_cropped_source_rect.height / pixel_ratio)),
        )
        scaled_cropped_size = dict(
            width=scaled_cropped_source_region["width"],
            height=scaled_cropped_source_region["height"],
        )

        # Getting the list of viewport regions composing the page
        # (we'll take screenshot for each one).
        if region_in_initial_screenshot.is_empty:
            x = max(0, full_area.left)
            y = max(0, full_area.top)
            w = min(full_area.width, scaled_cropped_size["width"])
            h = min(full_area.height, scaled_cropped_size["height"])
            rect_in_initial_screenshot = Region(
                round(x * pixel_ratio),
                round(y * pixel_ratio),
                round(w * pixel_ratio),
                round(h * pixel_ratio),
            )
        else:
            rect_in_initial_screenshot = region_in_initial_screenshot

        screenshot_parts = self._get_image_parts(
            full_area, scaled_cropped_size, pixel_ratio, rect_in_initial_screenshot
        )

        # Starting with element region size part of the screenshot. Use it as a size
        # template.
        stitched_image = Image.new("RGBA", (full_area.width, full_area.height))
        # Take screenshot and stitch for each screenshot part.
        stitched_image = self._stitch_screenshot(
            original_stitched_state,
            position_provider,
            screenshot_parts,
            stitched_image,
            self.scale_provider.scale_ratio,
            scaled_cut_provider,
        )
        position_provider.restore_state(original_stitched_state)
        self.origin_provider.restore_state(origin_state)
        return stitched_image