コード例 #1
0
def collect_test_results(tests, should_raise_exception):
    # type: (Dict[RunningTest, TestResults], bool) -> List[TestResultContainer]
    all_results = []
    for test, test_result in iteritems(tests):
        if test.pending_exceptions:
            logger.error(
                "During test execution above exception raised. \n {:s}".join(
                    str(e) for e in test.pending_exceptions))
        if test.has_checks:
            exception = None
        else:
            exception = TestFailedError("Test has no checks")
        if test_result:
            scenario_id_or_name = test_result.name
            app_id_or_name = test_result.app_name
            if test_result.is_unresolved and not test_result.is_new:
                exception = DiffsFoundError(test_result, scenario_id_or_name,
                                            app_id_or_name)
            if test_result.is_new:
                exception = NewTestError(test_result, scenario_id_or_name,
                                         app_id_or_name)
            if test_result.is_failed:
                exception = TestFailedError(test_result, scenario_id_or_name,
                                            app_id_or_name)
        else:
            exception = TestFailedError("Test haven't finished correctly")
        all_results.append(
            TestResultContainer(test_result, test.browser_info, exception))
        if exception and should_raise_exception:
            raise exception
    return all_results
コード例 #2
0
 def __call__(self):
     # type: () -> Optional[TestResults]
     logger.debug("%s called %s" % (self.__class__.__name__, self.name))
     res = None
     try:
         if callable(self.func_to_run):
             logger.debug("VGTask().func_to_run: {}".format(
                 self.func_to_run.__name__))
             res = self.func_to_run()
         if callable(self.callback):
             logger.debug("VGTask().callback: {}".format(
                 self.callback.__name__))
             self.callback(res)
     except Exception as e:
         logger.error("Failed to execute task! \n\t %s" % self.name)
         logger.exception(e)
         if callable(self.error_callback):
             logger.debug("VGTask().error_callback: {}".format(
                 self.error_callback.__name__))
             self.error_callback(e)
     finally:
         if callable(self.complete_callback):
             logger.debug("VGTask().complete_callback: {}".format(
                 self.complete_callback.__name__))
             self.complete_callback()
     return res
コード例 #3
0
    def obj_came(obj):
        def cleaned_params(params, fields):
            return {
                key: val
                for key, val in iteritems(params) if key in fields
            }

        params = make_snake(dict(obj))
        convidenced = defaultdict(int)
        for kls, fields in iteritems(klasses):
            fields = tuple(fields)
            if len(klasses) == 1:
                return kls(**cleaned_params(params, fields))
            if set(params.keys()) == set(fields):
                return kls(**cleaned_params(params, fields))

            for key in params.keys():
                if key in fields:
                    convidenced[(kls, fields)] += 1
        try:
            kls, fields = sorted(convidenced, reverse=True)[0]
            return kls(**cleaned_params(params, fields))
        except IndexError:
            logger.error("Failed to convert: {} to any class".format(obj))
            return params
コード例 #4
0
 def request(
     self, method, url_resource, use_api_key=True, request_id=None, **kwargs
 ):
     # type: (Text, Text, bool, Optional[UUID], **Any) -> Response
     req_id = str(uuid.uuid4() if request_id is None else request_id)
     if url_resource is not None:
         # makes URL relative
         url_resource = url_resource.lstrip("/")
     url_resource = urljoin(self.server_url.rstrip("/"), url_resource)
     params = {}
     if use_api_key:
         params["apiKey"] = self.api_key
     params.update(kwargs.get("params", {}))
     headers = self.headers.copy()
     headers.update(kwargs.get("headers", {}))
     headers["x-applitools-eyes-client-request-id"] = req_id
     timeout_sec = kwargs.get("timeout", None)
     if timeout_sec is None:
         timeout_sec = datetime_utils.to_sec(self.timeout_ms)
     response = self.client_session.request(
         method,
         url_resource,
         data=kwargs.get("data", None),
         verify=False,
         params=params,
         headers=headers,
         timeout=timeout_sec,
     )
     try:
         response.raise_for_status()
     except requests.HTTPError as e:
         logger.exception(e)
         logger.error("Error response content is: {}".format(response.text))
     return response
コード例 #5
0
def get_urls_from_css_resource(bytes_text):
    # type: (bytes) -> List[Text]
    def is_import_node(n):
        return n.type == "at-rule" and n.lower_at_keyword == "import"

    def is_font_node(n):
        return n.type == "at-rule" and n.lower_at_keyword == "font-face"

    try:
        rules, encoding = tinycss2.parse_stylesheet_bytes(css_bytes=bytes_text,
                                                          skip_comments=True,
                                                          skip_whitespace=True)
    except Exception:
        logger.error("Failed to read CSS string")
        return []
    urls = []
    for rule in rules:
        tags = rule.content
        if is_import_node(rule):
            logger.debug("The node has @import")
            tags = rule.prelude
        if is_font_node(rule):
            logger.debug("The node has @font-face")
            tags = rule.content
        if tags:
            urls.extend(list(_url_from_tags(tags)))
    return urls
コード例 #6
0
    def perform(self):  # noqa
        # type: () -> List[RenderStatusResults]

        def get_and_put_resource(url, running_render):
            # type: (str, RunningRender) -> VGResource
            logger.debug(
                "get_and_put_resource({0}, render_id={1}) call".format(
                    url, running_render.render_id))
            resource = self.request_resources.get(url)
            self.eyes_connector.render_put_resource(running_render, resource)
            return resource

        requests = self.prepare_data_for_rg(self.script)
        fetch_fails = 0
        render_requests = None
        already_force_putted = False
        while True:
            try:
                self.put_cache.process_all()
                render_requests = self.eyes_connector.render(*requests)
            except Exception as e:
                logger.exception(e)
                fetch_fails += 1
                datetime_utils.sleep(
                    1500, msg="/render throws exception... sleeping for 1.5s")
            if not render_requests:
                logger.error("running_renders is null")
                continue
            need_more_dom = need_more_resources = False
            for i, running_render in enumerate(render_requests):
                requests[i].render_id = running_render.render_id
                need_more_dom = running_render.need_more_dom
                need_more_resources = (running_render.render_status ==
                                       RenderStatus.NEED_MORE_RESOURCE)
                get_and_put_resource_wtih_render = partial(
                    get_and_put_resource, running_render=running_render)
                dom_resource = requests[i].dom.resource

                if self.is_force_put_needed and not already_force_putted:
                    for url in self.request_resources:
                        self.put_cache.fetch_and_store(
                            url, get_and_put_resource_wtih_render)
                    already_force_putted = True

                if need_more_resources:
                    for url in running_render.need_more_resources:
                        self.put_cache.fetch_and_store(
                            url, get_and_put_resource_wtih_render)

                if need_more_dom:
                    self.eyes_connector.render_put_resource(
                        running_render, dom_resource)
            still_running = (need_more_resources or need_more_dom
                             or fetch_fails > self.MAX_FAILS_COUNT)
            if not still_running:
                break

        return self.poll_render_status(requests)
コード例 #7
0
 def _process_future(self, val):
     if isinstance(val, Future):
         try:
             val = val.result()
         except HTTPError as e:
             logger.error("Resource haven't been downloaded.")
             logger.exception(e)
         except Exception as e:
             self.executor.shutdown()
             raise e
     return val
コード例 #8
0
 def delete_session(self, test_results):
     # type: (TestResults) -> None
     argument_guard.not_none(test_results)
     if None in (test_results.id, test_results.batch_id, test_results.secret_token):
         logger.error("Can't delete session, results are None")
         return
     self._com.request(
         "delete",
         "{}/{}/{}".format(
             self.API_SESSIONS_BATCHES, test_results.batch_id, test_results.id
         ),
         params={"AccessToken": test_results.secret_token},
     ).raise_for_status()
コード例 #9
0
    def _init_driver(self, driver):
        # type: (AnyWebDriver) -> None
        if isinstance(driver, EyesWebDriver):
            # If the driver is an EyesWebDriver (as might be the case when tests are ran
            # consecutively using the same driver object)
            self._driver = driver
        else:
            self._driver = EyesWebDriver(driver, self)

        if self._driver.is_mobile_app and not isinstance(driver, AppiumWebDriver):
            logger.error("To test a mobile app you need to use appium webdriver")
            if Feature.SCALE_MOBILE_APP in self.configure.features:
                raise EyesError(
                    "For mobile app testing the appium driver should be used"
                )
コード例 #10
0
 def render_task_succeeded(render_status):
     # type: (RenderStatusResults) -> None
     logger.debug("render_task_succeeded: task.uuid: {}".format(
         render_task.uuid))
     if render_status:
         self.eyes.render_status_for_task(render_task.uuid,
                                          render_status)
         for vgr in render_status.selector_regions:
             if vgr.error:
                 logger.error(vgr.error)
             else:
                 self.regions.append(vgr.to_region())
     self.watch_render[render_task] = True
     if self.all_tasks_completed(self.watch_render):
         self.becomes_rendered()
コード例 #11
0
    def close(self, raise_ex=True):  # noqa
        # type: (Optional[bool]) -> Optional[TestResults]
        if not self.test_list:
            return TestResults()
        logger.debug("VisualGridEyes.close()\n\t test_list %s" %
                     self.test_list)
        self.close_async()

        while True:
            states = list(set(t.state for t in self.test_list))
            logger.debug("Current test states: \n {}".format(states))
            if len(states) == 1 and states[0] == "completed":
                break
            datetime_utils.sleep(
                1500,
                msg="Waiting for state completed in VisualGridEyes.close")

        self._is_opened = False

        for test in self.test_list:
            if test.pending_exceptions:
                logger.error(
                    "During test execution above exception raised. \n {:s}".
                    join(str(e) for e in test.pending_exceptions))
        if raise_ex:
            for test in self.test_list:
                if test.test_result is None:
                    raise TestFailedError("Test haven't finished correctly")
                results = test.test_result
                scenario_id_or_name = results.name
                app_id_or_name = results.app_name
                if results.is_unresolved and not results.is_new:
                    raise DiffsFoundError(results, scenario_id_or_name,
                                          app_id_or_name)
                if results.is_new:
                    raise NewTestError(results, scenario_id_or_name,
                                       app_id_or_name)
                if results.is_failed:
                    raise TestFailedError(results, scenario_id_or_name,
                                          app_id_or_name)

        all_results = [t.test_result for t in self.test_list if t.test_result]
        if not all_results:
            return TestResults()
        return all_results[0]
コード例 #12
0
    def _try_upload_data(self, bytes_data, content_type, media_type):
        # type: (bytes, Text, Text) -> Optional[Text]
        argument_guard.not_none(bytes_data)

        rendering_info = self.render_info()
        if rendering_info and rendering_info.results_url:
            try:
                target_url = rendering_info.results_url
                guid = uuid.uuid4()
                target_url = target_url.replace("__random__", str(guid))
                logger.debug("Uploading {} to {}".format(media_type, target_url))
                if self._upload_data(
                    bytes_data, rendering_info, target_url, content_type, media_type
                ):
                    return target_url
            except Exception as e:
                logger.error("Error uploading {}".format(media_type))
                logger.exception(e)
コード例 #13
0
ファイル: running_test.py プロジェクト: brent-brown/CFAHome
 def render_task_succeeded(render_statuses):
     # type: (List[RenderStatusResults]) -> None
     logger.debug(
         "render_task_succeeded: task.uuid: {}".format(render_task.uuid)
     )
     logger.debug(
         "render_task_succeeded: task.uuid: {}".format(render_task.uuid)
     )
     render_status = render_statuses[render_index]
     if render_status:
         if not render_status.device_size:
             render_status.device_size = self.browser_info.viewport_size
         self.eyes.render_status_for_task(render_task.uuid, render_status)
         if render_status.status == RenderStatus.RENDERED:
             for vgr in render_status.selector_regions:
                 if vgr.error:
                     logger.error(vgr.error)
                 else:
                     self.regions[render_task].append(vgr.to_region())
             self.watch_render[render_task] = True
             if self.all_tasks_completed(self.watch_render):
                 self.becomes_rendered()
         elif render_status and render_status.status == RenderStatus.ERROR:
             self.watch_render[render_task] = True
             del self.task_queue[:]
             del self.open_queue[:]
             del self.close_queue[:]
             self.watch_open = {}
             self.watch_task = {}
             self.watch_close = {}
             self.abort()
             if self.all_tasks_completed(self.watch_render):
                 self.becomes_tested()
     else:
         logger.error(
             "Wrong render status! Render returned status {}".format(
                 render_status
             )
         )
         self.becomes_completed()
コード例 #14
0
def get_urls_from_css_resource(bytes_text):
    # type: (bytes) -> List[Text]
    def is_import_node(n):
        return n.prelude and n.type == "at-rule" and n.lower_at_keyword == "import"

    try:
        rules, encoding = tinycss2.parse_stylesheet_bytes(css_bytes=bytes_text,
                                                          skip_comments=True,
                                                          skip_whitespace=True)
    except Exception:
        logger.error("Failed to read CSS string")
        return []
    urls = []
    for rule in rules:
        if is_import_node(rule):
            extracted = _url_from_tags(rule.prelude, ("url", "string"))
        elif rule.content:
            extracted = _url_from_tags(rule.content, ("url", ))
        else:
            continue
        urls.extend(list(extracted))
    return urls
コード例 #15
0
        def render_task_succeeded(render_status):
            # type: (List[RenderStatusResults]) -> None
            logger.debug(
                "render_task_succeeded: task.uuid: {}".format(render_task.uuid)
            )
            if render_status:
                self.running_test.eyes.render_status_for_task(
                    render_task.uuid, render_status
                )
                if render_status.status == RenderStatus.RENDERED:
                    for vgr in render_status.selector_regions:
                        if vgr.error:
                            logger.error(vgr.error)
                        else:
                            self.regions.append(vgr.to_region())
                    logger.debug(
                        "render_task_succeeded: uuid: {}\n\tregions {}".format(
                            render_task.uuid, self.regions
                        )
                    )
                    # schedule check task
                    self.queue.append(self._check_task(render_task, tag))
                elif render_status and render_status.status == RenderStatus.ERROR:
                    self.running_test.task_queue.clear()
                    self.running_test.open_queue.clear()
                    self.running_test.close_queue.clear()
                    self.running_test.watch_open = {}
                    self.running_test.watch_task = {}
                    self.running_test.watch_close = {}

                    self.running_test.abort()
                    self.running_test.becomes_tested()
            else:
                logger.error(
                    "Wrong render status! Render returned status {}".format(
                        render_status
                    )
                )
                self.running_test.becomes_completed()
コード例 #16
0
    def _get_all_test_results_impl(self, should_raise_exception=True):
        # type: (bool) -> TestResultsSummary
        while True:
            states = list(set(t.state for t in self._get_all_running_tests()))
            logger.debug("Current test states: \n {}".format(states))
            if len(states) == 1 and states[0] == "completed":
                break
            datetime_utils.sleep(
                1500,
                msg="Waiting for state completed in get_all_test_results_impl",
            )

        all_results = []
        for test, test_result in iteritems(self._all_test_result):
            if test.pending_exceptions:
                logger.error(
                    "During test execution above exception raised. \n {:s}".
                    join(str(e) for e in test.pending_exceptions))
            exception = None
            if test.test_result is None:
                exception = TestFailedError("Test haven't finished correctly")
            scenario_id_or_name = test_result.name
            app_id_or_name = test_result.app_name
            if test_result and test_result.is_unresolved and not test_result.is_new:
                exception = DiffsFoundError(test_result, scenario_id_or_name,
                                            app_id_or_name)
            if test_result and test_result.is_new:
                exception = NewTestError(test_result, scenario_id_or_name,
                                         app_id_or_name)
            if test_result and test_result.is_failed:
                exception = TestFailedError(test_result, scenario_id_or_name,
                                            app_id_or_name)
            all_results.append(
                TestResultContainer(test_result, test.browser_info, exception))
            if exception and should_raise_exception:
                raise exception
        return TestResultsSummary(all_results)
コード例 #17
0
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:
        logger.info("Required viewport size already set")
        return None
    logger.info(
        "Actual Viewport Size: {}\n\tTrying to set viewport size to: {}".
        format(str(actual_viewport_size), str(required_size)))

    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)")
    if set_browser_size_by_viewport_size(driver, 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...")
    if set_browser_size_by_viewport_size(driver, 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.")

    # Attempt to fix by minimizing window
    logger.info("Trying workaround for minimization...")
    try:
        # some webdriver's don't support minimize_window
        driver.minimize_window()
    except WebDriverException as e:
        logger.exception(e)
    if set_browser_size_by_viewport_size(driver, actual_viewport_size,
                                         required_size):
        return None
    logger.error("Minimization workaround failed.")
    raise EyesError("Failed to set the viewport size.")
コード例 #18
0
    def perform(self):  # noqa
        # type: () -> List[RenderStatusResults]

        requests = self.prepare_data_for_rg(self.script)
        fetch_fails = 0
        render_requests = None
        already_force_putted = False
        while True:
            try:
                self.put_cache.wait_for_all_uploaded()
                render_requests = self.eyes_connector.render(*requests)
            except Exception:
                logger.exception("During rendering for requests {}".format(requests))
                fetch_fails += 1
                datetime_utils.sleep(
                    1500, msg="/render throws exception... sleeping for 1.5s"
                )
            if fetch_fails > self.MAX_FAILS_COUNT:
                raise EyesError(
                    "Render is failed. Max count retries reached for {}".format(
                        requests
                    )
                )
            if not render_requests:
                logger.error("running_renders is null")
                continue
            need_more_dom = need_more_resources = False
            for i, running_render in enumerate(render_requests):
                requests[i].render_id = running_render.render_id
                need_more_dom = running_render.need_more_dom
                need_more_resources = (
                    running_render.render_status == RenderStatus.NEED_MORE_RESOURCE
                )
                dom_resource = requests[i].dom.resource

                if self.is_force_put_needed and not already_force_putted:
                    self.put_cache.put(
                        self.full_request_resources,
                        self.full_request_resources,
                        running_render.render_id,
                        self.eyes_connector,
                        force=True,
                    )
                    already_force_putted = True

                if need_more_resources:
                    self.put_cache.put(
                        running_render.need_more_resources,
                        self.full_request_resources,
                        running_render.render_id,
                        self.eyes_connector,
                    )

                if need_more_dom:
                    self.eyes_connector.render_put_resource(
                        running_render.render_id, dom_resource
                    )
            still_running = (
                need_more_resources
                or need_more_dom
                or fetch_fails > self.MAX_FAILS_COUNT
            )
            if not still_running:
                break

        return self.poll_render_status(requests)