fix: parse tb for teardown exception (#117)
This commit is contained in:
Родитель
f139aaed0a
Коммит
097bf59dd2
|
@ -16,9 +16,12 @@ import hashlib
|
|||
import shutil
|
||||
import os
|
||||
import sys
|
||||
|
||||
import traceback
|
||||
|
||||
import warnings
|
||||
from typing import Any, Callable, Dict, Generator, List, Optional
|
||||
import logging
|
||||
|
||||
import pytest
|
||||
from playwright.sync_api import (
|
||||
Browser,
|
||||
|
@ -33,8 +36,6 @@ from slugify import slugify
|
|||
import tempfile
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
artifacts_folder = tempfile.TemporaryDirectory(prefix="playwright-pytest-")
|
||||
|
||||
|
||||
|
@ -76,34 +77,6 @@ def pytest_configure(config: Any) -> None:
|
|||
"markers",
|
||||
"browser_context_args(**kwargs): provide additional arguments to browser.new_context()",
|
||||
)
|
||||
log.debug("pytest_configure")
|
||||
class Teardown:
|
||||
failed = False
|
||||
setattr(config, "teardown", Teardown)
|
||||
|
||||
|
||||
def pytest_runtest_teardown(item):
|
||||
# import faulthandler
|
||||
# faulthandler.dump_traceback(all_threads=True)
|
||||
log.debug("pytest_runtest_teardown")
|
||||
item.config.teardown.failed = True
|
||||
|
||||
|
||||
def pytest_sessionfinish(session, exitstatus):
|
||||
log.debug("pytest_runtest_teardown")
|
||||
log.debug(f"{exitstatus=}")
|
||||
|
||||
|
||||
def pytest_exception_interact(node, call, report):
|
||||
log.debug("1pytest_exception_interact")
|
||||
log.debug(f"{node.config.teardown.failed=}")
|
||||
log.debug(f"{node.session.testsfailed=}")
|
||||
excinfo = call.exc_info if hasattr(call, "exc_info") else None
|
||||
log.debug(f"{excinfo=}")
|
||||
|
||||
if call.when == "teardown":
|
||||
log.debug("2pytest_exception_interact")
|
||||
node.config.teardown.failed = True
|
||||
|
||||
|
||||
# Making test result information available in fixtures
|
||||
|
@ -286,52 +259,33 @@ def context(
|
|||
)
|
||||
|
||||
yield context
|
||||
# import traceback
|
||||
# log.debug(f"{dir(traceback)=}")
|
||||
# log.debug(f"{traceback.print_last()=}")
|
||||
# stack = traceback.extract_stack()
|
||||
# log.debug(f"{stack=}")
|
||||
# for frame_summary in stack:
|
||||
# log.debug(f"{frame_summary.filename=}")
|
||||
# log.debug(f"{frame_summary.name=}")
|
||||
# log.debug(f"{frame_summary.colno=}")
|
||||
|
||||
|
||||
# log.debug(f"{traceback.print_stack()=}")
|
||||
|
||||
# log.debug(f"{traceback.print_exc()=}")
|
||||
|
||||
log.debug(f"{request.session.testscollected=}")
|
||||
log.debug(f"{request.session.exitstatus=}")
|
||||
log.debug(f"{request.session.testsfailed=}")
|
||||
|
||||
if request.session.testsfailed:
|
||||
log.debug("Only print if failed")
|
||||
|
||||
log.debug("context")
|
||||
# If request.node is missing rep_call, then some error happened during execution
|
||||
# that prevented teardown, but should still be counted as a failure
|
||||
failed_setup = request.node.rep_setup.failed if hasattr(request.node, "rep_setup") else False
|
||||
failed_call = request.node.rep_call.failed if hasattr(request.node, "rep_call") else False
|
||||
failed_teardown = request.node.rep_teardown.failed if hasattr(request.node, "rep_teardown") else False
|
||||
failed_setup = (
|
||||
request.node.rep_setup.failed if hasattr(request.node, "rep_setup") else False
|
||||
)
|
||||
failed_call = (
|
||||
request.node.rep_call.failed if hasattr(request.node, "rep_call") else False
|
||||
)
|
||||
|
||||
failed_xteardown = request.config.teardown.failed if hasattr(request.config, "teardown") else False
|
||||
passed_setup = (
|
||||
request.node.rep_setup.passed if hasattr(request.node, "rep_setup") else False
|
||||
)
|
||||
passed_call = (
|
||||
request.node.rep_call.passed if hasattr(request.node, "rep_call") else False
|
||||
)
|
||||
|
||||
failed_xteardown = False
|
||||
|
||||
if (passed_setup or passed_call) and not (failed_setup or failed_call):
|
||||
# check tb under stack if any other teardown was failed, False by default
|
||||
# looks like workaround for https://github.com/pytest-dev/pytest/issues/9909
|
||||
for trace, _ in traceback.walk_stack(None):
|
||||
if trace.f_locals.get("these_exceptions"):
|
||||
failed_xteardown = True
|
||||
break
|
||||
|
||||
failed = failed_setup or failed_call or failed_xteardown
|
||||
log.debug(f"{failed=}")
|
||||
log.debug(f"{failed_setup=}")
|
||||
log.debug(f"{failed_call=}")
|
||||
log.debug(f"{failed_teardown=}")
|
||||
log.debug(f"{failed_xteardown=}")
|
||||
|
||||
|
||||
log.debug(f"{hasattr(request.node, 'rep_setup')=}")
|
||||
log.debug(f"{hasattr(request.node, 'rep_call')=}")
|
||||
log.debug(f"{hasattr(request.node, 'rep_teardown')=}")
|
||||
|
||||
log.debug(f"{hasattr(request.config, 'teardown')=}")
|
||||
|
||||
|
||||
if capture_trace:
|
||||
retain_trace = tracing_option == "on" or (
|
||||
|
@ -344,11 +298,9 @@ def context(
|
|||
context.tracing.stop()
|
||||
|
||||
screenshot_option = pytestconfig.getoption("--screenshot")
|
||||
log.debug(f"{screenshot_option=}")
|
||||
capture_screenshot = screenshot_option == "on" or (
|
||||
failed and screenshot_option == "only-on-failure"
|
||||
)
|
||||
log.debug(f"{capture_screenshot=}")
|
||||
if capture_screenshot:
|
||||
for index, page in enumerate(pages):
|
||||
human_readable_status = "failed" if failed else "finished"
|
||||
|
|
Загрузка…
Ссылка в новой задаче