示例#1
0
def is_landscape_orientation(driver):
    if is_mobile_web(driver):
        # could be AppiumRemoteWebDriver
        appium_driver = get_underlying_driver(
            driver)  # type: tp.Union[AppiumWebDriver, WebDriver]

        try:
            # We must be in native context in order to ask for orientation,
            # because of an Appium bug.
            original_context = appium_driver.context
            if (len(appium_driver.contexts) > 1
                    and not original_context.uppar() == "NATIVE_APP"):
                appium_driver.switch_to.context("NATIVE_APP")
            else:
                original_context = None
        except WebDriverException:
            original_context = None

        try:
            orieintation = appium_driver.orientation
            return orieintation.lower() == "landscape"
        except WebDriverException:
            logger.warning(
                "Couldn't get device orientation. Assuming Portrait.")
        finally:
            if original_context is not None:
                appium_driver.switch_to.context(original_context)

        return False
示例#2
0
 def put(
         self,
         all_resources,  # type: List[VGResource]
         server_connector,  # type: ServerConnector
 ):
     # type: (...) -> None
     logger.debug("PutCache.put({} call".format(all_resources))
     with self._lock:
         not_puted = [
             r for r in all_resources if r.hash not in self._sent_hashes
         ]
         if not self._force_put:
             check_result = server_connector.check_resource_status(
                 not_puted)
             resources_to_upload = []
             for resource, exists in zip(not_puted, check_result):
                 if exists:
                     self._sent_hashes.add(resource.hash)
                     resource.clear()
                     continue
                 if resource.content is None:
                     logger.warning(
                         "This resource was requested by server but is cleared: "
                         "{} {}".format(resource.hash, resource.url))
                 else:
                     resources_to_upload.append(resource)
         else:
             resources_to_upload = not_puted
         results_iterable = self._executor.map(
             server_connector.render_put_resource, resources_to_upload)
         self._sent_hashes.update(list(results_iterable))
         for resource in resources_to_upload:
             resource.clear()
def crop_image(image, region_to_crop):
    # type: (Image.Image, Region) -> Image.Image
    argument_guard.is_a(image, Image.Image)
    argument_guard.is_a(region_to_crop, Region)

    image_region = Region.from_(image)
    image_region = image_region.intersect(region_to_crop)
    if image_region.is_size_empty:
        logger.warning(
            "requested cropped area results in zero-size image! "
            "Cropped not performed. Returning original image."
        )
        return image

    if image_region != region_to_crop:
        logger.warning("requested cropped area overflows image boundaries.")

    cropped_image = image.crop(
        box=(
            image_region.left,
            image_region.top,
            image_region.right,
            image_region.bottom,
        )
    )
    return cropped_image
示例#4
0
def get_viewport_size_or_display_size(driver):
    logger.debug("get_viewport_size_or_display_size()")

    if not is_mobile_app(driver):
        try:
            return get_viewport_size(driver)
        except Exception as e:
            logger.warning(
                "Failed to extract viewport size using Javascript: {}".format(
                    str(e)))
    # If we failed to extract the viewport size using JS, will use the
    # window size instead.

    logger.debug("Using window size as viewport size.")
    window_size = get_window_size(driver)
    width = window_size["width"]
    height = window_size["height"]
    try:
        if is_landscape_orientation(driver) and height > width:
            height, width = width, height
    except WebDriverException:
        # Not every WebDriver supports querying for orientation.
        pass
    logger.debug("Done! Size {:d} x {:d}".format(width, height))
    return RectangleSize(width=width, height=height)
 def _try_hide_caret(self):
     if self.configuration.hide_caret:
         try:
             self.driver.execute_script(
                 "var activeElement = document.activeElement; activeElement "
                 "&& activeElement.blur(); return activeElement;")
         except WebDriverException as e:
             logger.warning("Cannot hide caret! \n{}".format(e))
 def _try_capture_dom(self):
     try:
         dom_json = dom_capture.get_full_window_dom(self._driver)
         return dom_json
     except Exception as e:
         logger.warning(
             "Exception raising during capturing DOM Json. Passing...\n "
             "Got next error: {}".format(str(e)))
         return None
def _collect_regions(region_providers, screenshot, eyes):
    # type: (List[GET_REGION], EyesScreenshot, EyesBase) -> List[REGION]
    collected = []  # type: List[REGION]
    for provider in region_providers:
        try:
            regions = provider.get_regions(eyes, screenshot)
            collected.extend(regions)
        except OutOfBoundsError:
            logger.warning("Region was out of bounds")
    return collected
示例#8
0
 def _get_viewport_scroll_bounds(self):
     switch_to = self.driver.switch_to
     with switch_to.frames_and_back(self._original_fc):
         try:
             location = eyes_selenium_utils.get_current_position(
                 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, self._get_viewport_size())
     return viewport_bounds
def set_window_size(driver, size):
    # type: (AnyWebDriver, ViewPort) -> None
    # We move the window to (0,0) to have the best chance to set size as requested
    try:
        driver.set_window_rect(0, 0, size["width"], size["height"])
    except WebDriverException:
        logger.warning("set_window_rect has failed, using set_window_size")
        try:
            driver.set_window_position(0, 0)
        except WebDriverException:
            logger.warning("set_window_position has failed, ignoring")
        driver.set_window_size(size["width"], size["height"])
示例#10
0
def set_overflow(driver, overflow, root_element):
    # type: (EyesWebDriver, Text, AnyWebElement) -> Optional[Text]
    root_element = get_underlying_webelement(root_element)
    with timeout(0.1):
        try:
            return driver.execute_script(
                _JS_SET_OVERFLOW % (overflow, overflow), root_element)
        except WebDriverException as e:
            logger.warning("Couldn't sent overflow {} to element {}".format(
                overflow, root_element))
            logger.exception(e)
    return None
示例#11
0
 def _get_entire_size(self, image, position_provider):
     # type: (Image, PositionProvider) -> RectangleSize
     try:
         entire_size = position_provider.get_entire_size()
         logger.info(
             "Entire size of region context: {}".format(entire_size))
     except WebDriverException as e:
         logger.warning(
             "Failed to extract entire size of region context {}".format(e))
         logger.debug("Using image size instead: {} x {}".format(
             image.width, image.height))
         entire_size = RectangleSize(image.width, image.height)
     return entire_size
 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 _try_capture_dom(self):
     if self.driver.is_mobile_app:
         # While capture dom for native apps, appium throw an exception
         # "Method is not implemented" which shown in output as a warning msg
         # and mislead users.
         return None
     try:
         dom_json = dom_capture.get_full_window_dom(self._driver)
         return dom_json
     except Exception:
         logger.warning("dom-capture script failed, skipping it",
                        exc_info=True)
         return None
示例#14
0
 def _try_capture_dom(self):
     if self.driver.is_mobile_app:
         # While capture dom for native apps, appium throw an exception
         # "Method is not implemented" which shown in output as a warning msg
         # and mislead users.
         return None
     try:
         dom_json = dom_capture.get_full_window_dom(self._driver)
         return dom_json
     except Exception as e:
         logger.warning(
             "Exception raising during capturing DOM Json. Passing...\n "
             "Got next error: {}".format(str(e)))
         return None
示例#15
0
 def _try_post_dom_snapshot(self, dom_json):
     # type: (Text) -> Optional[Text]
     """
     In case DOM data is valid uploads it to the server and return URL where it stored.
     """
     if dom_json is None:
         return None
     try:
         return self._server_connector.post_dom_snapshot(dom_json)
     except Exception as e:
         logger.warning(
             "Couldn't send DOM Json. Passing...\n Got next error: {}".
             format(e))
         return None
示例#16
0
def get_viewport_size(driver):
    # type: (AnyWebDriver) -> RectangleSize
    """
    Tries to get the viewport size using Javascript. If fails, gets the entire browser window
    size!

    :param driver: The webdriver to use for getting the viewport size.
    """
    # noinspection PyBroadException
    try:
        width, height = driver.execute_script(_JS_GET_VIEWPORT_SIZE)
        return RectangleSize(width=width, height=height)
    except WebDriverException:
        logger.warning(
            "Failed to get viewport size. Only window size is available")
        return get_window_size(driver)
示例#17
0
    def _try_hide_caret(self):
        active_element = None
        if self.configure.hide_caret and not self.driver.is_mobile_app:
            try:
                active_element = self.driver.execute_script(
                    "var activeElement = document.activeElement; activeElement "
                    "&& activeElement.blur(); return activeElement;")
            except WebDriverException as e:
                logger.warning("Cannot hide caret! \n{}".format(e))
        yield

        if self.configure.hide_caret and not self.driver.is_mobile_app:
            try:
                self.driver.execute_script("arguments[0].focus();",
                                           active_element)
            except WebDriverException as e:
                logger.warning("Cannot hide caret! \n{}".format(e))
示例#18
0
def process_dom_snapshot_frames(
        dom,  # type: Dict
        switch_to,  # type : _EyesSwitchTo
        script,  # type: DomSnapshotScript
        deadline_time,  # type: float
        poll_interval_ms,  # type: int
        chunk_byte_length,  # type: int
        **script_args  # type: Any
):
    # type: (...) -> None
    for frame in dom["crossFrames"]:
        selector = frame.get("selector", None)
        if not selector:
            logger.warning("cross frame with null selector")
            continue
        frame_index = frame["index"]
        try:
            with switch_to.frame_and_back(
                    FrameLocator(frame_selector=[By.CSS_SELECTOR, selector])):
                frame_dom = create_cross_frames_dom_snapshots(
                    switch_to,
                    script,
                    deadline_time,
                    poll_interval_ms,
                    chunk_byte_length,
                    cross_origin_rendering=True,
                    **script_args)
                dom.setdefault("frames", []).append(frame_dom)
                frame_url = frame_dom["url"]
                dom["cdt"][frame_index]["attributes"].append({
                    "name": "data-applitools-src",
                    "value": frame_url
                })
                logger.info(
                    "Created cross origin frame snapshot {}".format(frame_url))
        except Exception as e:
            logger.warning(
                "Failed extracting cross frame with selector {}. Reason: {!r}".
                format(selector, e))
    for frame in dom["frames"]:
        if not has_cross_subframes(frame):
            continue
        selector = frame.get("selector", None)
        if not selector:
            logger.warning("inner frame with null selector")
            continue
        try:
            with switch_to.frame_and_back(
                    FrameLocator(frame_selector=[By.CSS_SELECTOR, selector])):
                process_dom_snapshot_frames(frame, switch_to, script,
                                            deadline_time, poll_interval_ms,
                                            chunk_byte_length, **script_args)
        except Exception as e:
            logger.warning(
                "Failed switching to frame with selector {}. Reason: {!r}".
                format(selector, e))
示例#19
0
 def download_resource(self, url, cookies):
     # type: (Text, Dict) -> Response
     headers = {
         "Accept-Encoding": "identity",
         "Accept-Language": "*",
     }
     cookies = {c["name"]: c["value"] for c in cookies}
     if self._ua_string:
         headers["User-Agent"] = self._ua_string
     logger.debug("Fetching URL {}\nwith headers {}".format(url, headers))
     timeout_sec = datetime_utils.to_sec(self._com.timeout_ms)
     try:
         return self._try_download_resources(headers, timeout_sec, url, cookies)
     except (requests.HTTPError, requests.ConnectionError) as e:
         logger.warning("Failed to download resource", url=url, exc=e)
         response = Response()
         response._content = b""
         response.status_code = requests.codes.no_response
         return response
示例#20
0
 def __ensure_viewport_size(self):
     # type: () -> None
     """
     Assign the viewport size we need to be in the default content frame.
     """
     if not self._is_viewport_size_set:
         try:
             if self.configure.viewport_size is None:
                 # TODO: ignore if viewport_size settled explicitly
                 target_size = self._get_viewport_size()
                 self.configure.viewport_size = target_size
             else:
                 target_size = self.configure.viewport_size
                 self._set_viewport_size(target_size)
             self._is_viewport_size_set = True
         except Exception as e:
             logger.warning("Viewport has not been setup. {}".format(e))
             self._is_viewport_size_set = False
             raise e
def set_viewport_size(driver, required_size):  # noqa
    # type: (AnyWebDriver, ViewPort) -> None
    actual_viewport_size = get_viewport_size(driver)
    if actual_viewport_size != required_size:
        actual_viewport_size = set_browser_size_by_viewport_size(
            driver, actual_viewport_size, required_size)
        if actual_viewport_size != required_size:
            # Additional attempt. This Solves the "non-resizable maximized browser" case
            # Attempt to fix it by minimizing window and retrying again
            logger.info("Trying workaround with minimization...")
            try:
                driver.minimize_window()
                actual_viewport_size = set_browser_size_by_viewport_size(
                    driver, actual_viewport_size, required_size)
            except WebDriverException:
                logger.warning("minimize_window failed")
            if actual_viewport_size != required_size:
                raise EyesError("Failed to set the viewport size.")
    else:
        logger.info("Required viewport size is already set")
示例#22
0
    def job_info(self):
        # type: () ->  JobInfo
        if self._job_info:
            return self._job_info

        logger.warning("JobInfo is empty. Calling it again")
        render_requests = [
            RenderRequest(
                render_info=RenderInfo.from_(
                    size_mode=None,
                    region=None,
                    selector=None,
                    render_browser_info=self._browser_info,
                ),
                platform_name=self._browser_info.platform,
                browser_name=self._browser_info.browser,
            )
        ]

        self._job_info = self.server_connector.job_info(render_requests)[0]
        return self._job_info
示例#23
0
def _parse_and_serialize_css(node, text, minimize=False):
    # type: (CssNode, tp.Text, bool) -> tp.Generator
    def is_import_node(n):
        return n.type == "at-rule" and n.lower_at_keyword == "import"

    stylesheet = tinycss2.parse_stylesheet(text,
                                           skip_comments=True,
                                           skip_whitespace=True)
    for style_node in stylesheet:
        if is_import_node(style_node):
            for tag in style_node.prelude:
                if tag.type == "url":
                    logger.debug("The node has import")
                    yield CssNode.create_sub_node(parent_node=node,
                                                  href=tag.value)
            continue

        try:
            if minimize and style_node.content:
                try:
                    # remove whitespaces inside blocks
                    style_node.content = [
                        tok for tok in style_node.content
                        if tok.type != "whitespace"
                    ]
                except AttributeError as e:
                    logger.warning(
                        "Cannot serialize item: {}, cause error: {}".format(
                            style_node, str(e)))
            serialized = style_node.serialize()
            if minimize:
                serialized = (serialized.replace("\n", "").replace(
                    "/**/", " ").replace(" {", "{"))

        except TypeError as e:
            logger.warning(str(e))
            continue
        yield CssNode.create_serialized_node(text=serialized)
示例#24
0
 def get_css(url):
     if url.startswith("blob:") or url.startswith("data:"):
         logger.warning("Passing blob URL: {}".format(url))
         return ""
     return requests.get(url, timeout=CSS_DOWNLOAD_TIMEOUT).text.strip()
示例#25
0
def set_viewport_size(driver, required_size):
    # type: (AnyWebDriver, ViewPort) -> None

    logger.debug("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.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 WebDriverException("Failed to set the viewport size.")
示例#26
0
def save_image(image, filename):
    try:
        logger.info("Saving file: {}".format(filename))
        image.save(filename)
    except Exception:
        logger.warning("Failed to save image")