Как прикреплять скриншот на каждом шаге (python, pytest, allure)

#python #pytest #screenshot #allure

Вопрос:

Я потратил много времени на поиск любого решения, поэтому решил спросить здесь. Мы используем python pytest allure, и наш клиент сказал нам, что ему нужны экраны на каждом этапе теста. Внутри у нас есть классы и методы страниц, отмеченные знаком очарования.шаг:

 @step('I login to application by user {user_name}')
def login(self, user_name: str) -> None:
    ....
 

конечно, мы можем использовать allure.attach в конце этих методов, но это не очень красивое решение.
мы попробовали этот вид переопределенного декоратора:

 def step(step_title):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            # with allure.step(step_title):
            _self = args[0]
            allure.step(step_title)(func(*args, **kwargs))
            if get_config().reporting.screen_each_step:
                allure.attach(_self.driver.get_screenshot_as_png(), "step screenshot", allure.attachment_type.PNG)
        return wrapper
    return decorator
 

но allure.step()() вызовы step_end и скриншоты прикрепляются к случаям, а не к шагам, и with allure.step() в этом декораторе возникают проблемы с разрешением заголовка шага (метод agr), и мы не получили аргументы методов во вложениях шагов, как это было с классическими @allure.step

Мы исследовали код allure-pytest и заметили, что в файле есть крючки step_start и step_end /allure_commons/_hooks.py

 class AllureUserHooks(object):
    ..........

    @hookspec
    def start_step(self, uuid, title, params):
        """ step """

    @hookspec
    def stop_step(self, uuid, exc_type, exc_val, exc_tb):
        """ step """
 

Есть ли способ реализовать на них оболочку? Что-то в этом роде

 @allure_commons.hookimpl(hookwrapper=True)
def stop_step():
    take_screen()
    yield
 

мы попробовали код, подобный приведенному выше, но, очевидно, произошла ошибка, которая не сработала.
Так что я буду очень признателен за любой совет, если кто-нибудь здесь сможет мне его дать.