Пример #1
0
def pytest_runtest_makereport(item, call):
    pytest_html = item.config.pluginmanager.getplugin('html')
    outcome = yield
    report = outcome.get_result()
    extra = getattr(report, 'extra', [])
    if report.when in ('call', 'setup'):
        xfail = hasattr(report, 'wasxfail')
        if ((report.passed or report.skipped) and xfail) or (report.failed
                                                             and not xfail):
            # only add additional html on failure
            try:
                if type(factory.get_shared_driver()) is not NoneObject:
                    screen = take_screenshot(
                        webdriver=factory.get_shared_driver(),
                        filename=item.function.__name__)
                    extra.append(pytest_html.extras.image(screen))
                    allure.attach.file(screen, item.function.__name__,
                                       allure.attachment_type.PNG)
            except Exception as e:
                print(f"Could not create a screenshot:\n{e}")
            if xfail:
                extra.append(
                    pytest_html.extras.html(
                        '<div style="color: orange">XFailed reason: {}</div><br />'
                        .format(report.wasxfail)))
        report.extra = extra
Пример #2
0
def take_screenshot(path=None, filename=None):
    if not path:
        path = selene.config.reports_folder
    if not filename:
        filename = "screen_{id}".format(id=next(selene.config.counter))

    screenshot_path = helpers.take_screenshot(driver(), path, filename)

    global _latest_screenshot
    _latest_screenshot = screenshot_path

    return screenshot_path
Пример #3
0
def _wait_with_screenshot(webdriver, entity, condition, timeout=None, polling=None):
    if timeout is None:
        timeout = config.timeout
    if polling is None:
        polling = config.poll_during_waits
    try:
        return wait_for(entity, condition, timeout, polling)
    except TimeoutException as e:
        screenshot = helpers.take_screenshot(webdriver, )
        msg = '''{original_msg}
            screenshot: file://{screenshot}'''.format(original_msg=e.msg, screenshot=screenshot)
        raise TimeoutException(msg, e.screen, e.stacktrace)
Пример #4
0
def screenshot(name, path='./'):
    return take_screenshot(browser(), name, path)
Пример #5
0
def wait_for(code=lambda: None, until=lambda code_result: code_result.is_displayed(), by_demand_after=lambda: None,
             wait_time=config.default_wait_time):
    """
    waits `wait_time` smartly for the `until` conditions to be satisfied on the result of executing `code`
    but after the `after` code was executed optionally in case code() gave no satisfied result at first attempt

    :param code - in case hasattr(code, 'to_str') to_str() method will be called to stringify code at error message in
    case of failed wait_for
    """
    # todo: think on: better name for by_demand_after, or even another way to implement this feature
    # todo: think on: letting the wait_for to accept hamcrest matchers as 'until' conditions
    # todo: think on: renaming 'code' param to element_finder in case wait_for will be only "element wait" implementation.
    #       the `code` name was chosen in order to implement "general case" of waiter
    #       nevertheless, the wait_for implementation has some parts bounded to the "element finding" context,
    #           like throwing specific exception in case element was not found...

    conditions = until if isinstance(until, (tuple, list)) else [until]
    import stopit
    import time

    # todo: catch 'all' possible relevant exceptions below...
    # todo: it was assumed that after() will not be needed once exception was encountered... Though this needs to be proved...
    # todo:     and documented
    result = DummyResult()
    with suppress(StaleElementReferenceException, NoSuchElementException, CannotSendRequest):
        result = code()
        if conditions and not satisfied(result, *conditions):
            by_demand_after()

    # todo: think on: refactoring to match at once the result to all conditions combined into one
    #       since it will check conditions one by one, one after another... and in the final end, some previous
    #       conditions may not be met already...
    for condition_met in conditions:
        with stopit.ThreadingTimeout(wait_time) as to_ctx_mgr:
            while not condition_met(result):
                with suppress(StaleElementReferenceException, NoSuchElementException, CannotSendRequest):
                    time.sleep(0.1)
                    result = code()
        if not to_ctx_mgr:
            # todo: think on: refactor the following code, make it just `raise stopit.TimeoutException(repr(code))` or etc.
            # todo: make the following 'screenshot taking' code optional (controoled via config)
            # todo: think on: unbinding screenshooting from the wait_for implementation
            screenshot = '%s.png' % time.time()
            path = os.path.abspath('./reports/screenshots')  # todo: make screenshots path configurable
            full_path = take_screenshot(browser(), screenshot, path)

            err_message = """
            Timeout reached while waiting...
            During: %ss
            For: %s
            Until: %s
            Screenshot: %s
            """ % (wait_time,
                   code.__name__,  # todo: think on: refactoring to the usage without "underscores"
                   condition_met.__name__,
                   full_path)
            raise stopit.TimeoutException(err_message)
            # todo: improve error message. Also taking into account the proper alternative of condition implementation
            #       e.g. as hamcrest matchers

    return result
Пример #6
0
def wait_for(code=lambda: None,
             until=lambda code_result: code_result.is_displayed(),
             by_demand_after=lambda: None,
             wait_time=config.default_wait_time):
    """
    waits `wait_time` smartly for the `until` conditions to be satisfied on the result of executing `code`
    but after the `after` code was executed optionally in case code() gave no satisfied result at first attempt

    :param code - in case hasattr(code, 'to_str') to_str() method will be called to stringify code at error message in
    case of failed wait_for
    """
    # todo: think on: better name for by_demand_after, or even another way to implement this feature
    # todo: think on: letting the wait_for to accept hamcrest matchers as 'until' conditions
    # todo: think on: renaming 'code' param to element_finder in case wait_for will be only "element wait" implementation.
    #       the `code` name was chosen in order to implement "general case" of waiter
    #       nevertheless, the wait_for implementation has some parts bounded to the "element finding" context,
    #           like throwing specific exception in case element was not found...

    conditions = until if isinstance(until, (tuple, list)) else [until]
    import stopit
    import time

    # todo: catch 'all' possible relevant exceptions below...
    # todo: it was assumed that after() will not be needed once exception was encountered... Though this needs to be proved...
    # todo:     and documented
    result = DummyResult()
    with suppress(StaleElementReferenceException, NoSuchElementException,
                  CannotSendRequest):
        result = code()
        if conditions and not satisfied(result, *conditions):
            by_demand_after()

    # todo: think on: refactoring to match at once the result to all conditions combined into one
    #       since it will check conditions one by one, one after another... and in the final end, some previous
    #       conditions may not be met already...
    for condition_met in conditions:
        with stopit.ThreadingTimeout(wait_time) as to_ctx_mgr:
            while not condition_met(result):
                with suppress(StaleElementReferenceException,
                              NoSuchElementException, CannotSendRequest):
                    time.sleep(0.1)
                    result = code()
        if not to_ctx_mgr:
            # todo: think on: refactor the following code, make it just `raise stopit.TimeoutException(repr(code))` or etc.
            # todo: make the following 'screenshot taking' code optional (controoled via config)
            # todo: think on: unbinding screenshooting from the wait_for implementation
            screenshot = '%s.png' % time.time()
            path = os.path.abspath(
                './reports/screenshots'
            )  # todo: make screenshots path configurable
            full_path = take_screenshot(browser(), screenshot, path)

            err_message = """
            Timeout reached while waiting...
            During: %ss
            For: %s
            Until: %s
            Screenshot: %s
            """ % (
                wait_time,
                code.
                __name__,  # todo: think on: refactoring to the usage without "underscores"
                condition_met.__name__,
                full_path)
            raise stopit.TimeoutException(err_message)
            # todo: improve error message. Also taking into account the proper alternative of condition implementation
            #       e.g. as hamcrest matchers

    return result
Пример #7
0
def screenshot(name=_picture_name(), path=settings.screenshot_path):
    return take_screenshot(browser(), name, path)
Пример #8
0
def screenshot(name, path='./'):
    return take_screenshot(browser(), name, path)