Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions allure-behave/src/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ def attach_data(self, body, name, attachment_type, extension):
def attach_file(self, source, name, attachment_type, extension):
self.logger.attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)

@allure_commons.hookimpl
def global_attach_data(self, body, name, attachment_type, extension):
self.logger.global_attach_data(uuid4(), body, name=name, attachment_type=attachment_type, extension=extension)

@allure_commons.hookimpl
def global_attach_file(self, source, name, attachment_type, extension):
self.logger.global_attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)

@allure_commons.hookimpl
def global_error(self, message, trace):
self.logger.global_error(message=message, trace=trace)

@allure_commons.hookimpl
def add_description(self, test_description):
test_result = self.logger.get_test(None)
Expand Down
15 changes: 15 additions & 0 deletions allure-pytest-bdd/src/allure_api_listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
from .utils import apply_link_pattern
from .utils import attach_data
from .utils import attach_file
from .utils import global_attach_data
from .utils import global_attach_file
from .utils import global_error
from .utils import get_link_patterns
from .steps import start_step
from .steps import stop_step
Expand Down Expand Up @@ -117,3 +120,15 @@ def attach_data(self, body, name, attachment_type, extension):
@allure_commons.hookimpl
def attach_file(self, source, name, attachment_type, extension):
attach_file(self.lifecycle, source, name, attachment_type, extension)

@allure_commons.hookimpl
def global_attach_data(self, body, name, attachment_type, extension):
global_attach_data(self.lifecycle, body, name, attachment_type, extension)

@allure_commons.hookimpl
def global_attach_file(self, source, name, attachment_type, extension):
global_attach_file(self.lifecycle, source, name, attachment_type, extension)

@allure_commons.hookimpl
def global_error(self, message, trace):
global_error(self.lifecycle, message, trace)
24 changes: 24 additions & 0 deletions allure-pytest-bdd/src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,30 @@ def attach_file(lifecycle, source, name, attachment_type, extension=None):
)


def global_attach_data(lifecycle, body, name, attachment_type, extension=None):
lifecycle.global_attach_data(
uuid4(),
body,
name=name,
attachment_type=attachment_type,
extension=extension,
)


def global_attach_file(lifecycle, source, name, attachment_type, extension=None):
lifecycle.global_attach_file(
uuid4(),
source,
name=name,
attachment_type=attachment_type,
extension=extension,
)


def global_error(lifecycle, message, trace=None):
lifecycle.global_error(message=message, trace=trace)


def format_csv(rows):
with io.StringIO() as buffer:
writer = csv.writer(buffer)
Expand Down
13 changes: 0 additions & 13 deletions allure-pytest/setup.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
import os
import sys
from setuptools import setup
from pkg_resources import require, DistributionNotFound, VersionConflict

try:
require("pytest-allure-adaptor")
print("""
You have pytest-allure-adaptor installed.
You need to remove pytest-allure-adaptor from your site-packages
before installing allure-pytest, or conflicts may result.
""")
sys.exit()
except (DistributionNotFound, VersionConflict):
pass

PACKAGE = "allure-pytest"

Expand Down
24 changes: 24 additions & 0 deletions allure-pytest/src/listener.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,30 @@ def attach_data(self, body, name, attachment_type, extension):
def attach_file(self, source, name, attachment_type, extension):
self.allure_logger.attach_file(uuid4(), source, name=name, attachment_type=attachment_type, extension=extension)

@allure_commons.hookimpl
def global_attach_data(self, body, name, attachment_type, extension):
self.allure_logger.global_attach_data(
uuid4(),
body,
name=name,
attachment_type=attachment_type,
extension=extension,
)

@allure_commons.hookimpl
def global_attach_file(self, source, name, attachment_type, extension):
self.allure_logger.global_attach_file(
uuid4(),
source,
name=name,
attachment_type=attachment_type,
extension=extension,
)

@allure_commons.hookimpl
def global_error(self, message, trace):
self.allure_logger.global_error(message=message, trace=trace)

@allure_commons.hookimpl
def add_title(self, test_title):
test_result = self.allure_logger.get_test(None)
Expand Down
6 changes: 6 additions & 0 deletions allure-python-commons-test/src/report.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ def __init__(self, result):
"*attachment.*"
)
}
self.globals = [
json.load(file) for _, file in self._report_items(
result,
"*globals.json"
)
]

@staticmethod
def _report_items(report_dir, glob):
Expand Down
33 changes: 33 additions & 0 deletions allure-python-commons-test/src/result.py
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,25 @@ def has_attachment_with_content(
)


def has_global_attachment_with_content(
attachments,
content_matcher,
attach_type=None,
name=None
):
return has_entry(
"attachments",
has_item(
all_of(
has_entry("name", name) if name else anything(),
has_entry("type", attach_type) if attach_type else anything(),
has_entry("timestamp", not_none()),
has_entry("source", maps_to(attachments, content_matcher))
)
)
)


def with_id():
return has_entry("uuid", not_none())

Expand All @@ -213,13 +232,27 @@ def has_status_details(*matchers):
return has_entry("statusDetails", all_of(*matchers))


def has_global_error(*matchers):
return has_entry(
"errors",
has_item(
all_of(
has_entry("timestamp", not_none()),
*matchers
)
)
)


def with_message_contains(string):
return has_entry("message", contains_string(string))


def with_trace_contains(string):
return has_entry("trace", contains_string(string))

def with_no_trace():
return not_(has_entry("trace", anything()))

def with_excluded():
return has_entry("excluded", True)
Expand Down
4 changes: 4 additions & 0 deletions allure-python-commons/src/allure/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
from allure_commons._allure import Dynamic as dynamic
from allure_commons._allure import step
from allure_commons._allure import attach
from allure_commons._allure import global_attach
from allure_commons._allure import global_error
from allure_commons._allure import manual
from allure_commons.types import Severity as severity_level
from allure_commons.types import AttachmentType as attachment_type
Expand Down Expand Up @@ -38,6 +40,8 @@
"dynamic",
"severity_level",
"attach",
"global_attach",
"global_error",
"attachment_type",
"parameter_mode"
]
43 changes: 43 additions & 0 deletions allure-python-commons/src/allure_commons/_allure.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from allure_commons._core import plugin_manager
from allure_commons.types import LabelType, LinkType, ParameterMode
from allure_commons.utils import uuid4
from allure_commons.utils import format_exception, format_traceback
from allure_commons.utils import func_parameters, represent

_TFunc = TypeVar("_TFunc", bound=Callable[..., Any])
Expand Down Expand Up @@ -216,6 +217,48 @@ def file(self, source, name=None, attachment_type=None, extension=None):
attach = Attach()


class GlobalAttach:

def __call__(self, body, name=None, attachment_type=None, extension=None):
plugin_manager.hook.global_attach_data(
body=body,
name=name,
attachment_type=attachment_type,
extension=extension,
)

def file(self, source, name=None, attachment_type=None, extension=None):
plugin_manager.hook.global_attach_file(
source=source,
name=name,
attachment_type=attachment_type,
extension=extension,
)


global_attach = GlobalAttach()


@overload
def global_error(value: BaseException) -> None:
...


@overload
def global_error(value: str, trace: Union[str, None] = None) -> None:
...


def global_error(value, trace=None):
message = None
if isinstance(value, BaseException):
message = format_exception(type(value), value)
trace = format_traceback(value.__traceback__)
else:
message = value
plugin_manager.hook.global_error(message=message, trace=trace)


class fixture:
def __init__(self, fixture_function, parent_uuid=None, name=None):
self._fixture_function = fixture_function
Expand Down
16 changes: 16 additions & 0 deletions allure-python-commons/src/allure_commons/_hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,18 @@ def attach_data(self, body, name, attachment_type, extension):
def attach_file(self, source, name, attachment_type, extension):
""" attach file """

@hookspec
def global_attach_data(self, body, name, attachment_type, extension):
""" attach global data """

@hookspec
def global_attach_file(self, source, name, attachment_type, extension):
""" attach global file """

@hookspec
def global_error(self, message, trace):
""" global error """


class AllureDeveloperHooks:

Expand Down Expand Up @@ -100,3 +112,7 @@ def report_attached_file(self, source, file_name):
@hookspec
def report_attached_data(self, body, file_name):
""" reporting """

@hookspec
def report_globals(self, globals_item):
""" reporting """
52 changes: 44 additions & 8 deletions allure-python-commons/src/allure_commons/lifecycle.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from allure_commons.model2 import TestResultContainer
from allure_commons.model2 import TestResult
from allure_commons.model2 import Attachment, ATTACHMENT_PATTERN
from allure_commons.model2 import GlobalAttachment, GlobalError, Globals
from allure_commons.model2 import TestStepResult
from allure_commons.model2 import ExecutableItem
from allure_commons.model2 import TestBeforeResult
Expand Down Expand Up @@ -124,14 +125,11 @@ def stop_after_fixture(self, uuid=None):
fixture.stop = now()

def _attach(self, uuid, name=None, attachment_type=None, extension=None, parent_uuid=None):
mime_type = attachment_type
extension = extension if extension else "attach"

if type(attachment_type) is AttachmentType:
extension = attachment_type.extension
mime_type = attachment_type.mime_type

file_name = ATTACHMENT_PATTERN.format(prefix=uuid, ext=extension)
file_name, mime_type = self.__resolve_attachment_filename_and_type(
uuid,
attachment_type=attachment_type,
extension=extension,
)
attachment = Attachment(source=file_name, name=name, type=mime_type)
last_uuid = parent_uuid if parent_uuid else self._last_item_uuid(ExecutableItem)
self._items[last_uuid].attachments.append(attachment)
Expand All @@ -147,3 +145,41 @@ def attach_data(self, uuid, body, name=None, attachment_type=None, extension=Non
file_name = self._attach(uuid, name=name, attachment_type=attachment_type,
extension=extension, parent_uuid=parent_uuid)
plugin_manager.hook.report_attached_data(body=body, file_name=file_name)

def global_attach_file(self, uuid, source, name=None, attachment_type=None, extension=None):
file_name, mime_type = self.__resolve_attachment_filename_and_type(
uuid,
attachment_type=attachment_type,
extension=extension,
)
plugin_manager.hook.report_attached_file(source=source, file_name=file_name)
plugin_manager.hook.report_globals(globals_item=Globals(attachments=[
GlobalAttachment(source=file_name, name=name, type=mime_type, timestamp=now())
]))

def global_attach_data(self, uuid, body, name=None, attachment_type=None, extension=None):
file_name, mime_type = self.__resolve_attachment_filename_and_type(
uuid,
attachment_type=attachment_type,
extension=extension,
)
plugin_manager.hook.report_attached_data(body=body, file_name=file_name)
plugin_manager.hook.report_globals(globals_item=Globals(attachments=[
GlobalAttachment(source=file_name, name=name, type=mime_type, timestamp=now())
]))

def global_error(self, message=None, trace=None):
plugin_manager.hook.report_globals(globals_item=Globals(errors=[
GlobalError(message=message, trace=trace, timestamp=now())
]))

def __resolve_attachment_filename_and_type(self, uuid, attachment_type=None, extension=None):
mime_type = attachment_type
extension = extension if extension else "attach"

if type(attachment_type) is AttachmentType:
extension = attachment_type.extension
mime_type = attachment_type.mime_type

file_name = ATTACHMENT_PATTERN.format(prefix=uuid, ext=extension)
return file_name, mime_type
10 changes: 10 additions & 0 deletions allure-python-commons/src/allure_commons/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,18 @@ def report_attached_data(self, body, file_name):
else:
attached_file.write(body)

@hookimpl
def report_globals(self, globals_item):
self._report_item(globals_item)


class AllureMemoryLogger:

def __init__(self):
self.test_cases = []
self.test_containers = []
self.attachments = {}
self.globals = []

@hookimpl
def report_result(self, result):
Expand All @@ -72,3 +77,8 @@ def report_attached_file(self, source, file_name):
@hookimpl
def report_attached_data(self, body, file_name):
self.attachments[file_name] = body

@hookimpl
def report_globals(self, globals_item):
data = asdict(globals_item, filter=lambda _, v: v or v is False)
self.globals.append(data)
Loading
Loading