예제 #1
0
 def push_state(self):
     """
     Adds the transform to the states list.
     """
     transforms = self._get_current_transform()
     if not all(transforms.values()):
         self._current_position = Point.create_top_left()
     else:
         point = Point(0, 0)
         for transform in transforms.values():
             point += self._get_position_from_transform(transform)
         self._current_position = point
     self._states.append(self._current_position)
예제 #2
0
 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)
예제 #3
0
class CSSTranslatePositionProvider(SeleniumPositionProvider):
    _JS_TRANSFORM_KEYS = ["transform", "-webkit-transform"]

    def __init__(self, driver):
        super(CSSTranslatePositionProvider, self).__init__(driver)
        self._current_position = Point(0, 0)

    def _set_transform(self, transform_list):
        script = ''
        for key, value in transform_list.items():
            script += "document.documentElement.style['{}'] = '{}';".format(key, value)
        self._execute_script(script)

    def _get_current_transform(self):
        script = 'return {'
        for key in self._JS_TRANSFORM_KEYS:
            script += "'{0}': document.documentElement.style['{0}'],".format(key)
        script += ' }'
        return self._execute_script(script)

    def get_current_position(self):
        return self._current_position.clone()

    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 set_position(self, location):
        translate_command = "translate(-{}px, -{}px)".format(location.x, location.y)
        logger.debug(translate_command)
        transform_list = dict((key, translate_command) for key in self._JS_TRANSFORM_KEYS)
        self._set_transform(transform_list)
        self._current_position = location.clone()

    def push_state(self):
        """
        Adds the transform to the states list.
        """
        transforms = self._get_current_transform()
        if not all(transforms.values()):
            self._current_position = Point.create_top_left()
        else:
            point = Point(0, 0)
            for transform in transforms.values():
                point += self._get_position_from_transform(transform)
            self._current_position = point
        self._states.append(self._current_position)
예제 #4
0
 def __init__(self, image, location=None):
     super(EyesImagesScreenshot, self).__init__(image)
     if location is None:
         location = Point.create_top_left()
     argument_guard.is_a(location, Point)
     self._location = location
     self._bounds = Region.from_location_size(
         location, dict(width=self._image.width, height=self._image.height)
     )
예제 #5
0
def get_full_window_dom(driver, position_provider=None):
    # type: (EyesWebDriver, PositionProvider) -> str
    if position_provider:
        position_provider.push_state()
        position_provider.set_position(Point.create_top_left())

    dom = _get_window_dom(driver)
    dom_json = json.dumps(dom)

    if position_provider:
        position_provider.pop_state()
    return dom_json
예제 #6
0
    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 get_sub_screenshot_by_region(self, region):
     sub_screenshot_region = self.get_intersected_region(region)
     if sub_screenshot_region.is_empty:
         raise OutOfBoundsError("Region {0} is out of bounds!".format(region))
     # If we take a screenshot of a region inside a frame, then the frame's (0,0) is in the
     # negative offset of the region..
     sub_screenshot_frame_location = Point(-region.left, -region.top)
     # FIXME Calculate relative region location? (same as the java version)
     screenshot = image_utils.get_image_part(self._screenshot, sub_screenshot_region)
     return EyesWebDriverScreenshot(
         self._driver,
         screenshot,
         is_viewport_screenshot=self._is_viewport_screenshot,
         frame_location_in_screenshot=sub_screenshot_frame_location,
     )
예제 #8
0
 def calc_frame_location_in_screenshot(frame_chain, is_viewport_screenshot):
     first_frame = frame_chain[0]
     location_in_screenshot = Point(first_frame.location['x'],
                                    first_frame.location['y'])
     # 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 is_viewport_screenshot:
         location_in_screenshot.x -= first_frame.parent_scroll_position.x
         location_in_screenshot.y -= first_frame.parent_scroll_position.y
     # For inner frames we must calculate the scroll
     inner_frames = frame_chain[1:]
     for frame in inner_frames:
         location_in_screenshot.x += frame.location[
             'x'] - frame.parent_scroll_position.x
         location_in_screenshot.y += frame.location[
             'y'] - frame.parent_scroll_position.y
     return location_in_screenshot
예제 #9
0
 def __init__(self, driver):
     super(CSSTranslatePositionProvider, self).__init__(driver)
     self._current_position = Point(0, 0)
예제 #10
0
 def get_current_position(self):
     position = Point(
         self._element.get_scroll_left(), self._element.get_scroll_top()
     )
     logger.info("Current position: {}".format(position))
     return position
예제 #11
0
    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))
예제 #12
0
 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)
예제 #13
0
 def current_frame_offset(self):
     # type: () -> Point
     location = Point.create_top_left()
     for frame in self:
         location.offset_by_location(frame.location)
     return location
예제 #14
0
 def test_position_scrolled_to_origin_after_traversing(self):
     # Page must contain scrolling
     dom_json = dom_capture.get_full_window_dom(self.driver)  # noqa: F841
     assert self.driver.get_current_position() == Point(0, 0)