diff --git a/qase-robotframework/changelog.md b/qase-robotframework/changelog.md index c0283cdb..89a7e393 100644 --- a/qase-robotframework/changelog.md +++ b/qase-robotframework/changelog.md @@ -1,10 +1,28 @@ +# qase-pytest 3.1.2 + +## What's new + +Support `qase.fields` tag. You can specify the fields that you want to send to Qase. + +```robotframework +Simple test + [Tags] qase.fields:{ "suite": "my suite", "description": "It is simple test" } + Should Be Equal As Numbers 1 1 +``` + # qase-pytest 3.1.1 ## What's new Minor release that includes all changes from beta versions 3.1.1b. -Support `ignore` tag. If the test has the `ignore` tag, the reporter will not send the result to Qase. +Support `qase.ignore` tag. If the test has the `qase.ignore` tag, the reporter will not send the result to Qase. + +```robotframework +Simple test + [Tags] qase.ignore + Should Be Equal As Numbers 1 1 +``` # qase-pytest 3.1.1b2 diff --git a/qase-robotframework/pyproject.toml b/qase-robotframework/pyproject.toml index e4df7719..314cada5 100644 --- a/qase-robotframework/pyproject.toml +++ b/qase-robotframework/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "qase-robotframework" -version = "3.1.1" +version = "3.1.2" description = "Qase Robot Framework Plugin" readme = "README.md" authors = [{name = "Qase Team", email = "support@qase.io"}] diff --git a/qase-robotframework/src/qase/robotframework/listener.py b/qase-robotframework/src/qase/robotframework/listener.py index 794ab38d..35cb3b8d 100644 --- a/qase-robotframework/src/qase/robotframework/listener.py +++ b/qase-robotframework/src/qase/robotframework/listener.py @@ -1,6 +1,5 @@ import logging import os -import re import uuid from qase.commons import ConfigManager @@ -9,6 +8,7 @@ from qase.commons.reporters import QaseCoreReporter from .plugin import QaseRuntimeSingleton +from .tag_parser import TagParser from .types import STATUSES from .models import * @@ -55,13 +55,14 @@ def end_test(self, name, attributes: EndTestModel): self.step_uuid = None - if self.__is_test_ignore(attributes.get("tags")): + test_metadata = TagParser.parse_tags(attributes.get("tags")) + + if test_metadata.ignore: logger.info("Test '%s' is ignored", name) return - case_id = self._extract_ids(attributes.get("tags")) - if case_id: - self.runtime.result.testops_id = int(case_id) + if test_metadata.qase_id: + self.runtime.result.testops_id = int(test_metadata.qase_id) self.runtime.result.execution.complete() self.runtime.result.execution.set_status(STATUSES[attributes.get("status")]) @@ -70,6 +71,10 @@ def end_test(self, name, attributes: EndTestModel): self.runtime.result.add_field(Field("description", attributes.get("doc"))) + if test_metadata.fields: + for key, value in test_metadata.fields.items(): + self.runtime.result.add_field(Field(key, value)) + if self.suite: self.runtime.result.suite = Suite(self.suite.get("title"), self.suite.get("description")) @@ -124,15 +129,3 @@ def close(self): @staticmethod def log_message(message): logger.debug("Log:", message) - - @staticmethod - def _extract_ids(list_of_tags: List[str]): - qase_id = re.compile(r"Q-(\d+)", re.IGNORECASE) - for tag in list_of_tags: - if qase_id.fullmatch(tag): - return int(qase_id.match(tag).groups()[0]) - return None - - @staticmethod - def __is_test_ignore(list_of_tags: List[str]): - return any(tag.lower() == "ignore" for tag in list_of_tags) diff --git a/qase-robotframework/src/qase/robotframework/models.py b/qase-robotframework/src/qase/robotframework/models.py index be2625d8..a1d8565d 100644 --- a/qase-robotframework/src/qase/robotframework/models.py +++ b/qase-robotframework/src/qase/robotframework/models.py @@ -1,5 +1,5 @@ import sys -from typing import List +from typing import List, Union if sys.version_info >= (3, 8): from typing import TypedDict @@ -85,3 +85,14 @@ class EndKeywordModel(TypedDict): endtime: str elapsedtime: int status: str + + +class TestMetadata: + qase_id: Union[int, None] + ignore: bool + fields: dict + + def __init__(self) -> None: + self.qase_id = None + self.ignore = False + self.fields = {} diff --git a/qase-robotframework/src/qase/robotframework/tag_parser.py b/qase-robotframework/src/qase/robotframework/tag_parser.py new file mode 100644 index 00000000..0a9a4928 --- /dev/null +++ b/qase-robotframework/src/qase/robotframework/tag_parser.py @@ -0,0 +1,41 @@ +import json +import logging +import re + +from .models import TestMetadata + + +class TagParser: + __logger = logging.getLogger("qase-robotframework") + + @staticmethod + def parse_tags(tags: list[str]) -> TestMetadata: + metadata = TestMetadata() + for tag in tags: + if tag.lower().startswith("q-"): + metadata.qase_id = TagParser.__extract_ids(tag) + + if tag.lower() == "qase.ignore": + metadata.ignore = True + + if tag.lower().startswith("qase.fields"): + metadata.fields = TagParser.__extract_fields(tag) + + return metadata + + @staticmethod + def __extract_ids(tag: str) -> int or None: + qase_id = re.compile(r"Q-(\d+)", re.IGNORECASE) + if qase_id.fullmatch(tag): + return int(qase_id.match(tag).groups()[0]) + + return None + + @staticmethod + def __extract_fields(tag: str) -> dict: + value = tag.split(':', 1)[-1].strip() + try: + return json.loads(value) + except ValueError as e: + TagParser.__logger.error(f"Error parsing fields from tag '{tag}': {e}") + return {}