Ejemplo n.º 1
0
    def _taking_screenshot_loop(
            self,
            user_inputs,  # type: UserInputs
            region,  # type: Region
            check_settings,  # type: CheckSettings
            retry_timeout_ms,  # type: int
            retry_ms,  # type: int
            start,  # type: datetime
            source,  # type: Optional[Text]
            screenshot,  # type: Optional[EyesScreenshot]
    ):
        # type: (...) -> Optional[EyesScreenshot]

        if retry_ms >= retry_timeout_ms:
            return screenshot

        datetime_utils.sleep(self._MATCH_INTERVAL_MS)

        new_screenshot = self._try_take_screenshot(user_inputs, region,
                                                   check_settings, source)
        if self._match_result.as_expected:
            return new_screenshot

        retry_ms = (start - datetime.now()).seconds
        return self._taking_screenshot_loop(
            user_inputs,
            region,
            check_settings,
            retry_timeout_ms,
            retry_ms,
            start,
            source,
            new_screenshot,
        )
Ejemplo n.º 2
0
def create_dom_snapshot_loop(script, deadline_time, poll_interval_ms,
                             chunk_byte_length, **script_args):
    # type: (DomSnapshotScript, float, int, int, **Any) -> Dict
    chunks = []
    result = script.run(**script_args)
    while result.status is ProcessPageStatus.WIP or (
            result.status is ProcessPageStatus.SUCCESS_CHUNKED
            and not result.done):
        if time() > deadline_time:
            raise DomSnapshotTimeout
        result = script.poll_result(chunk_byte_length)
        if result.status is ProcessPageStatus.WIP:
            datetime_utils.sleep(poll_interval_ms,
                                 "Waiting for the end of DOM extraction")
        elif result.status is ProcessPageStatus.SUCCESS_CHUNKED:
            logger.info("Snapshot chunk {}, {}B".format(
                len(chunks), len(result.value)))
            chunks.append(result.value)
    if result.status is ProcessPageStatus.SUCCESS:
        return result.value
    elif result.status.SUCCESS_CHUNKED and result.done:
        return json.loads("".join(chunks))
    elif result.status is ProcessPageStatus.ERROR:
        raise DomSnapshotScriptError(result.error)
    else:
        raise DomSnapshotFailure("Unexpected script result", result)
Ejemplo n.º 3
0
def set_browser_size(driver, required_size):
    # type: (AnyWebDriver, ViewPort) -> bool

    retries_left = _RETRIES

    # set browser size for mobile devices isn't working
    if is_mobile_platform(driver):
        return True

    while True:
        logger.debug("Trying to set browser size to: " + str(required_size))
        set_window_size(driver, required_size)
        datetime_utils.sleep(_SLEEP_MS)
        current_size = get_window_size(driver)
        logger.debug("Current browser size: " + str(current_size))

        if retries_left or current_size != required_size:
            break
        retries_left -= 1

    if current_size == required_size:
        logger.debug("Browser size has been successfully set to {}".format(
            current_size))
        return True
    logger.debug("Browser size wasn't set: {}".format(current_size))
    return False
Ejemplo n.º 4
0
 def poll_render_status(self, requests):
     # type: (List[RenderRequest]) -> List[RenderStatusResults]
     logger.debug(
         "poll_render_status call with Requests {}".format(requests))
     iterations = 0
     statuses = []  # type: List[RenderStatusResults]
     fails_count = 0
     finished = False
     while True:
         if finished:
             break
         while True:
             try:
                 statuses = self.eyes_connector.render_status_by_id(
                     *[rq.render_id for rq in requests])
             except Exception as e:
                 logger.exception(e)
                 datetime_utils.sleep(
                     1000,
                     msg="/render-status throws exception... sleeping for 1s"
                 )
                 fails_count += 1
             finally:
                 iterations += 1
                 datetime_utils.sleep(1500, msg="Rendering...")
             if statuses or 0 < fails_count < 3:
                 break
         finished = bool(statuses
                         and (all(s.status != RenderStatus.RENDERING
                                  for s in statuses)
                              or iterations > self.MAX_ITERATIONS or False))
     return statuses
Ejemplo n.º 5
0
 def poll_render_status(self, render_request):
     # type: (RenderRequest) -> List[RenderStatusResults]
     iterations = 0
     statuses = []  # type: List[RenderStatusResults]
     if not render_request.render_id:
         raise EyesError("RenderStatus: Got empty renderId!")
     fails_count = 0
     finished = False
     while True:
         if finished:
             break
         while True:
             try:
                 statuses = self.eyes_connector.render_status_by_id(
                     render_request.render_id)
             except Exception as e:
                 logger.exception(e)
                 datetime_utils.sleep(1000)
                 fails_count += 1
             finally:
                 iterations += 1
                 datetime_utils.sleep(500)
             if statuses or 0 < fails_count < 3:
                 break
         finished = bool(statuses and statuses[0] is not None
                         and (statuses[0].status != RenderStatus.RENDERING
                              or iterations > self.MAX_ITERATIONS or False))
     if statuses[0].status == RenderStatus.ERROR:
         raise EyesError("Got error during rendering: \n\t{}".format(
             statuses[0].error))
     return statuses
def set_browser_size(driver, required_size):
    # type: (AnyWebDriver, ViewPort) -> bool
    if is_mobile_platform(driver):
        return True
    previous_size = get_window_size(driver)
    current_size = None
    set_window_size(driver, required_size)
    for _ in range(10):  # Poll up to 1 second until window is resized
        datetime_utils.sleep(100)
        current_size = get_window_size(driver)
        if current_size != previous_size:
            if current_size == required_size:
                logger.debug("set_browser_size succeeded",
                             current_size=current_size)
                return True
            else:
                # Window size probably have exceeded minimal size or screen resolution
                # and was adjusted to fit these constraints
                break
    logger.info(
        "set_browser_size failed",
        required_size=required_size,
        previous_size=previous_size,
        current_size=current_size,
    )
    return False
Ejemplo n.º 7
0
 def _create_dom_snapshot_loop(self):
     # type: () -> Dict
     chunks = []
     result = self._script.run(**self._script_args)
     while result.status is ProcessPageStatus.WIP or (
             result.status is ProcessPageStatus.SUCCESS_CHUNKED
             and not result.done):
         if time() > self._deadline_time:
             raise DomSnapshotTimeout
         result = self._script.poll_result(self._chunk_byte_length)
         if result.status is ProcessPageStatus.WIP:
             datetime_utils.sleep(
                 self.POLL_INTERVAL_MS,
                 "Waiting for the end of DOM extraction",
             )
         elif result.status is ProcessPageStatus.SUCCESS_CHUNKED:
             self._logger.info("Snapshot chunk {}, {}B".format(
                 len(chunks), len(result.value)))
             chunks.append(result.value)
     if result.status is ProcessPageStatus.SUCCESS:
         return result.value
     elif result.status.SUCCESS_CHUNKED and result.done:
         return json.loads("".join(chunks))
     elif result.status is ProcessPageStatus.ERROR:
         raise DomSnapshotScriptError(result.error)
     else:
         raise DomSnapshotFailure("Unexpected script result", result)
    def _take_screenshot(
            self,
            user_inputs,  # type: UserInputs
            region,  # type: Region
            tag,  # type: Text
            should_run_once_on_timeout,  # type: bool
            check_settings,  # type: CheckSettings
            retry_timeout,  # type: int
            source,  # type: Optional[Text],
    ):
        # type: (...) -> EyesScreenshot

        time_start = datetime.now()
        if retry_timeout == 0 or should_run_once_on_timeout:
            if should_run_once_on_timeout:
                datetime_utils.sleep(retry_timeout)

            screenshot = self._try_take_screenshot(user_inputs, region, tag,
                                                   check_settings, source)
        else:
            screenshot = self._retry_taking_screenshot(user_inputs, region,
                                                       tag, check_settings,
                                                       retry_timeout, source)
        time_end = datetime.now()
        summary_ms = datetime_utils.to_ms((time_end - time_start).seconds)
        logger.debug(
            "MatchWindowTask._take_screenshot completed in {} ms".format(
                summary_ms))
        return screenshot
Ejemplo n.º 9
0
    def _run_render_status_requests(self):
        status_tasks = []
        while True:
            with self._have_status_tasks:
                while not (self._shutdown or status_tasks
                           or self._status_tasks):
                    self._have_status_tasks.wait()
                if self._shutdown:
                    break
                new_tasks, self._status_tasks = self._status_tasks, []
            status_tasks.extend(new_tasks)
            ids = [t.render_id for t in status_tasks]
            logger.debug("render_status_by_id call with ids: {}".format(ids))
            try:

                statuses = self._server_connector.render_status_by_id(*ids)
            except Exception as e:
                for task in status_tasks:
                    task.on_error(e)
                continue
            rendering = []
            current_time = time()
            for status, task in zip(statuses, status_tasks):
                if status.status == RenderStatus.RENDERING:
                    if current_time > task.timeout_time:
                        task.on_error(EyesError("Render time out"))
                    else:
                        rendering.append(task)
                else:
                    task.on_success(status)
            status_tasks = rendering
            if status_tasks:
                datetime_utils.sleep(1000, "Render status polling delay")
Ejemplo n.º 10
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.all_running_tests]))
            if len(states) == 1 and states[0] == "completed":
                break
            datetime_utils.sleep(500)

        all_results = []
        for test, test_result in iteritems(self._all_test_result):
            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)
Ejemplo n.º 11
0
 def poll_render_status(self, requests):
     # type: (List[RenderRequest]) -> List[RenderStatusResults]
     iterations = 0
     statuses = []  # type: List[RenderStatusResults]
     fails_count = 0
     finished = False
     while True:
         if finished:
             break
         while True:
             try:
                 statuses = self.eyes_connector.render_status_by_id(
                     *[rq.render_id for rq in requests])
             except Exception as e:
                 logger.exception(e)
                 datetime_utils.sleep(1000)
                 fails_count += 1
             finally:
                 iterations += 1
                 datetime_utils.sleep(500)
             if statuses or 0 < fails_count < 3:
                 break
         finished = bool(statuses and statuses[0] is not None
                         and (statuses[0].status != RenderStatus.RENDERING
                              or iterations > self.MAX_ITERATIONS or False))
     return statuses
Ejemplo n.º 12
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)
Ejemplo n.º 13
0
    def _stitch_screenshot(
            self,
            original_stitch_state,  # type: PositionMemento
            stitch_provider,  # type: PositionProvider
            screenshot_parts,  # type: List[SubregionForStitching]
            stitched_image,  # type: Image.Image
            scale_ratio,  # type: float
            scaled_cut_provider,  # type: CutProvider
    ):
        # type: (...) -> Image
        logger.info("enter: scale_ratio {}".format(scale_ratio))
        for part_region in screenshot_parts:
            logger.debug("Part: {}".format(part_region))
            # Scroll to the part's top/left
            part_region_location = part_region.scroll_to.offset(
                original_stitch_state.position)
            origin_position = stitch_provider.set_position(
                part_region_location)

            target_position = part_region.paste_physical_location.offset(
                part_region_location - origin_position)

            # Actually taking the screenshot.
            datetime_utils.sleep(self.wait_before_screenshots)
            part_image = self.image_provider.get_image()
            self.debug_screenshot_provider.save(part_image,
                                                self._debug_msg("part_image"))

            cut_part = scaled_cut_provider.cut(part_image)
            self.debug_screenshot_provider.save(cut_part,
                                                self._debug_msg("cut_part"))

            r = part_region.physical_crop_area
            if not r.is_size_empty:
                cropped_part = image_utils.crop_image(cut_part, r)
            else:
                cropped_part = cut_part
            self.debug_screenshot_provider.save(
                cropped_part, self._debug_msg("cropped_part"))
            scaled_part_image = image_utils.scale_image(
                cropped_part, scale_ratio)
            self.debug_screenshot_provider.save(
                scaled_part_image, self._debug_msg("scaled_part_image"))

            r2 = part_region.logical_crop_area
            scaled_cropped_part_image = image_utils.crop_image(
                scaled_part_image, r2)
            self.debug_screenshot_provider.save(
                scaled_cropped_part_image,
                self._debug_msg("scaled_cropped_part_image"))

            logger.debug("pasting part at {}".format(target_position))

            stitched_image.paste(scaled_cropped_part_image,
                                 box=(target_position.x, target_position.y))
            self.debug_screenshot_provider.save(
                stitched_image, self._debug_msg("stitched_image"))
        return stitched_image
Ejemplo n.º 14
0
def test_agent_id(driver_mock, monkeypatch, library, runner, agent_id):
    monkeypatch.setattr(eyes_selenium_utils, "set_viewport_size", lambda *_: None)
    eyes = Eyes(runner())
    # avoid use custom setter on Eyes object
    # eyes._current_eyes.server_connector = fake_connector_class()

    eyes.open(driver_mock, "A", "B", {"width": 100, "height": 100})
    eyes.abort_async()
    while "start_session" not in eyes.server_connector.calls:
        sleep(1)  # wait until runner opens session in background thread
    assert eyes.server_connector.calls["start_session"].agent_id.startswith(agent_id)
Ejemplo n.º 15
0
 def _element_screenshot(self, scale_provider):
     # type: (ScaleProvider) -> EyesWebDriverScreenshot
     logger.info("Element screenshot requested")
     with self._ensure_element_visible(self._target_element):
         datetime_utils.sleep(self.configure.wait_before_screenshots)
         image = self._get_scaled_cropped_image(scale_provider)
         if not self._is_check_region and not self._driver.is_mobile_platform:
             # Some browsers return always full page screenshot (IE).
             # So we cut such images to viewport size
             image = cut_to_viewport_size_if_required(self.driver, image)
         return EyesWebDriverScreenshot.create_viewport(self._driver, image)
Ejemplo n.º 16
0
 def _run(self):
     logger.debug("VisualGridRunner.run()")
     while self.still_running:
         try:
             task = self._task_queue.pop()
             logger.debug("VisualGridRunner got task %s" % task)
         except IndexError:
             datetime_utils.sleep(1000, msg="Waiting for task")
             continue
         future = self._executor.submit(lambda task: task(), task)
         self._future_to_task[future] = task
 def _run(self):
     logger.debug("VisualGridRunner.run()")
     for test_queue in self._get_parallel_tests_by_round_robin():
         try:
             task = test_queue.popleft()
             logger.debug("VisualGridRunner got task %s" % task)
         except IndexError:
             datetime_utils.sleep(10, msg="Waiting for task", verbose=False)
             continue
         future = self._executor.submit(task)
         self._future_to_task[future] = task
     logger.debug("VisualGridRunner.run() done")
Ejemplo n.º 18
0
    def perform(self):
        # type: () -> RenderStatusResults

        def get_and_put_resource(url):
            # type: (str) -> VGResource
            resource = self.request_resources.get(url)
            self.eyes_connector.render_put_resource(running_render, resource)
            return resource

        requests = []
        rq = self.prepare_data_for_rg(self.script)
        requests.append(rq)
        fetch_fails = 0
        render_requests = None
        while True:

            try:
                render_requests = self.eyes_connector.render(*requests)
            except Exception as e:
                logger.exception(e)
                fetch_fails += 1
                datetime_utils.sleep(1500)
            if not render_requests:
                continue

            running_render = render_requests[0]
            rq.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)
            still_running = (need_more_resources or need_more_dom
                             or fetch_fails > self.MAX_FAILS_COUNT)

            dom_resource = rq.dom.resource

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

            if need_more_dom:
                self.eyes_connector.render_put_resource(
                    running_render, dom_resource)

            if not still_running:
                break

        statuses = self.poll_render_status(rq)
        if statuses and statuses[0].status == RenderStatus.ERROR:
            raise EyesError("Render failed for {} with the message: {}".format(
                statuses[0].status, statuses[0].error))
        return statuses[0]
Ejemplo n.º 19
0
    def _long_request_loop(self, url, delay=LONG_REQUEST_DELAY_MS):
        delay = min(
            self.MAX_LONG_REQUEST_DELAY_MS,
            math.floor(delay * self.LONG_REQUEST_DELAY_MULTIPLICATIVE_INCREASE_FACTOR),
        )
        logger.debug("Long request. Still running... Retrying in {} ms".format(delay))

        datetime_utils.sleep(delay)
        response = self.request(
            "get", url, headers={"Eyes-Date": datetime_utils.current_time_in_rfc1123()},
        )
        if response.status_code != requests.codes.ok:
            return response
        return self._long_request_loop(url, delay)
def wait_till_tests_completed(test_provider):
    # type: (Union[Callable, List]) -> None
    def get_tests(provider):
        if isinstance(test_provider, list):
            return test_provider
        return test_provider()

    while True:
        states = list(set(t.state for t in get_tests(test_provider)))
        if not states:
            # probably some exception is happened during execution
            break
        if len(states) == 1 and states[0] == "completed":
            break
        datetime_utils.sleep(1500, msg="Waiting for state completed!")
Ejemplo n.º 21
0
def test_special_rendering(url, test_name, batch_info, driver):
    runner = VisualGridRunner(30)
    eyes = Eyes(runner)
    sconf = Configuration(
        test_name=test_name, app_name="Visual Grid Render Test", batch=batch_info
    )
    sconf.add_device_emulation(DeviceName.Galaxy_S5)
    sconf.add_browser(1200, 800, BrowserType.CHROME)
    sconf.add_browser(1200, 800, BrowserType.FIREFOX)

    eyes.set_configuration(sconf)
    eyes.open(driver)
    driver.get(url)
    datetime_utils.sleep(500)
    eyes.check(test_name, Target.window().fully())
    eyes.close(False)
    all_results = runner.get_all_test_results(False)
Ejemplo n.º 22
0
    def close(self, raise_ex=True):  # noqa
        # type: (Optional[bool]) -> Optional[TestResults]
        if self.configuration.is_disabled:
            logger.debug("close(): ignored (disabled)")
            return 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]))
            if len(states) == 1 and states[0] == "completed":
                break
            datetime_utils.sleep(500)

        self._is_opened = False

        for test in self.test_list:
            if test.pending_exceptions:
                raise EyesError(
                    "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]
Ejemplo n.º 23
0
    def perform(self):
        # type: () -> RenderStatusResults

        def get_and_put_resource(url):
            # type: (str) -> VGResource
            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
        while True:

            try:
                render_requests = self.eyes_connector.render(*requests)
            except Exception as e:
                logger.exception(e)
                fetch_fails += 1
                datetime_utils.sleep(1500)
            if not render_requests:
                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 need_more_resources:
                    for url in running_render.need_more_resources:
                        self.put_cache.fetch_and_store(url,
                                                       get_and_put_resource)

                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)
Ejemplo n.º 24
0
    def _stop(self):
        # type: () -> None
        logger.debug("VisualGridRunner.stop()")
        while sum(r.score for r in self._get_all_running_tests()) > 0:
            datetime_utils.sleep(500, msg="Waiting for finishing tests in stop")
        self.still_running = False
        for future in concurrent.futures.as_completed(self._future_to_task):
            task = self._future_to_task[future]
            try:
                future.result()
            except Exception as exc:
                logger.exception("%r generated an exception: %s" % (task, exc))
            else:
                logger.debug("%s task ran" % task)

        self.put_cache.executor.shutdown()
        self.resource_cache.executor.shutdown()
        self._executor.shutdown()
        self._thread.join()
Ejemplo n.º 25
0
def set_browser_size(driver, required_size):
    # type: (AnyWebDriver, ViewPort) -> bool

    retries_left = _RETRIES

    # set browser size for mobile devices isn't working
    if is_mobile_web(driver):
        return True

    while True:
        logger.info("Trying to set browser size to: " + str(required_size))
        set_window_size(driver, required_size)
        datetime_utils.sleep(_SLEEP_MS)
        current_size = get_window_size(driver)
        logger.info("Current browser size: " + str(required_size))

        if retries_left or current_size != required_size:
            break
        retries_left -= 1

    return current_size == required_size
Ejemplo n.º 26
0
 def _long_request_loop(self, url, request_id):
     delays = delays_gen(500, 5, 2, 5000)
     delay = next(delays)
     while True:
         datetime_utils.sleep(
             delay, "Long request {} still running".format(request_id)
         )
         response = self.request(
             "get",
             url,
             request_id=request_id,
             headers={"Eyes-Date": datetime_utils.current_time_in_rfc1123()},
         )
         if response.status_code == requests.codes.ok:
             url = response.headers.get("Location", url)
             if "Retry-After" in response.headers:
                 delay = int(response.headers["Retry-After"]) * 1000
             else:
                 delay = next(delays)
         else:
             return response
Ejemplo n.º 27
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)
Ejemplo n.º 28
0
def get_dom_script_result(driver, dom_extraction_timeout, timer_name,
                          script_for_run):
    # type: (AnyWebDriver, int, Text, Text) -> Dict
    is_check_timer_timeout = []
    script_response = {}
    status = None

    def start_timer():
        def set_timer():
            is_check_timer_timeout.append(True)

        timer = threading.Timer(datetime_utils.to_sec(dom_extraction_timeout),
                                set_timer)
        timer.daemon = True
        timer.setName(timer_name)
        timer.start()
        return timer

    timer = start_timer()
    while True:
        if status == "SUCCESS" or is_check_timer_timeout:
            del is_check_timer_timeout[:]
            break
        script_result_string = driver.execute_script(script_for_run)
        try:
            script_response = json.loads(script_result_string,
                                         object_pairs_hook=OrderedDict)
            status = script_response.get("status")
        except Exception as e:
            logger.exception(e)
        datetime_utils.sleep(1000, "Waiting for the end of DOM extraction")
    timer.cancel()
    script_result = script_response.get("value")
    if script_result is None or status == "ERROR":
        raise EyesError("Failed to capture script_result")
    return script_result
Ejemplo n.º 29
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
Ejemplo n.º 30
0
def timeout(timeout_ms):
    # type: (Num) -> Generator
    datetime_utils.sleep(timeout_ms)
    yield