From 81147c6f370e08eb549f4c7abc082d8938190041 Mon Sep 17 00:00:00 2001 From: "reportportal.io" Date: Fri, 6 Sep 2024 13:33:19 +0000 Subject: [PATCH 01/11] Changelog update --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7267487..46dc21a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] + +## [5.5.4] ### Fixed - Issue [#187](https://github.com/reportportal/agent-Python-RobotFramework/issues/187): Distutils in the agent, by @HardNorth ### Added From 1c8f87f0a0812951dea16d711291e71c5e5f0538 Mon Sep 17 00:00:00 2001 From: "reportportal.io" Date: Fri, 6 Sep 2024 13:33:20 +0000 Subject: [PATCH 02/11] Version update --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 802f7ec..ee8e1b5 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ from setuptools import setup -__version__ = '5.5.4' +__version__ = '5.5.5' def read_file(fname): From 7257d1a2dd791aea320cdd5a1b7cfe59bd764176 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Mon, 16 Sep 2024 15:04:43 +0300 Subject: [PATCH 03/11] Add rkie keyword test --- examples/rkie_keyword.robot | 18 ++++++++++++ tests/integration/test_rkie_keyword.py | 39 ++++++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100644 examples/rkie_keyword.robot create mode 100644 tests/integration/test_rkie_keyword.py diff --git a/examples/rkie_keyword.robot b/examples/rkie_keyword.robot new file mode 100644 index 0000000..ad74cd5 --- /dev/null +++ b/examples/rkie_keyword.robot @@ -0,0 +1,18 @@ +*** Settings *** +Documentation Example of 'Run Keyword And Ignore Error' keyword reporting + +*** Variables *** +${countval} 0 + +*** Test Cases *** +Rkie test + Run Keyword And Ignore Error Fail on first try + Fail on first try + +*** Keywords *** +Fail on first try + ${counter} Evaluate ${countval} + 1 + Set Suite Variable ${countval} ${counter} + IF ${countval} < 2 + Fail To less executions + END diff --git a/tests/integration/test_rkie_keyword.py b/tests/integration/test_rkie_keyword.py new file mode 100644 index 0000000..a39dd73 --- /dev/null +++ b/tests/integration/test_rkie_keyword.py @@ -0,0 +1,39 @@ +# Copyright 2023 EPAM Systems +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest import mock + +from tests import REPORT_PORTAL_SERVICE +from tests.helpers import utils + + +@mock.patch(REPORT_PORTAL_SERVICE) +def test_before_after_suite_with_steps(mock_client_init): + mock_client = mock_client_init.return_value + mock_client.start_test_item.side_effect = utils.item_id_gen + + result = utils.run_robot_tests(['examples/rkie_keyword.robot']) + assert result == 0 + + launch_start = mock_client.start_launch.call_args_list + launch_finish = mock_client.finish_launch.call_args_list + assert len(launch_start) == len(launch_finish) == 1 + + item_start_calls = mock_client.start_test_item.call_args_list + item_finish_calls = mock_client.finish_test_item.call_args_list + assert len(item_start_calls) == len(item_finish_calls) == 13 + + statuses = [finish[1]['status'] for finish in item_finish_calls] + assert statuses == ['PASSED'] * 2 + ['FAILED'] * 3 + ['PASSED'] * 3 + [ + 'SKIPPED'] * 2 + ['PASSED'] * 3 From 3d0a689bb7f61873d73e6400a267b7061498bdd5 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Mon, 16 Sep 2024 15:46:23 +0300 Subject: [PATCH 04/11] Closes #193 --- CHANGELOG.md | 2 ++ robotframework_reportportal/listener.py | 1 + 2 files changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46dc21a..9600a40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +### Added +- Issue [#193](https://github.com/reportportal/agent-Python-RobotFramework/issues/193): Listener self registration, by @HardNorth ## [5.5.4] ### Fixed diff --git a/robotframework_reportportal/listener.py b/robotframework_reportportal/listener.py index 4de50fa..0783c5f 100644 --- a/robotframework_reportportal/listener.py +++ b/robotframework_reportportal/listener.py @@ -94,6 +94,7 @@ class listener: def __init__(self) -> None: """Initialize listener attributes.""" + self.ROBOT_LIBRARY_LISTENER = self self._items = LifoQueue() self._service = None self._variables = None From 4624f2cddecae80b8a61674e5c52977a4b231a16 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Mon, 16 Sep 2024 16:11:17 +0300 Subject: [PATCH 05/11] Update on absolute path imports --- robotframework_reportportal/listener.py | 8 ++++---- robotframework_reportportal/logger.py | 2 +- robotframework_reportportal/result_visitor.py | 9 ++++----- robotframework_reportportal/result_visitor.pyi | 5 ++++- robotframework_reportportal/service.py | 11 +++++------ 5 files changed, 18 insertions(+), 17 deletions(-) diff --git a/robotframework_reportportal/listener.py b/robotframework_reportportal/listener.py index 0783c5f..57b4d06 100644 --- a/robotframework_reportportal/listener.py +++ b/robotframework_reportportal/listener.py @@ -25,10 +25,10 @@ from reportportal_client.helpers import LifoQueue, is_binary, guess_content_type_from_bytes -from .model import Keyword, Launch, Test, LogMessage, Suite -from .service import RobotService -from .static import MAIN_SUITE_ID, PABOT_WITHOUT_LAUNCH_ID_MSG -from .variables import Variables +from robotframework_reportportal.model import Keyword, Launch, Test, LogMessage, Suite +from robotframework_reportportal.service import RobotService +from robotframework_reportportal.static import MAIN_SUITE_ID, PABOT_WITHOUT_LAUNCH_ID_MSG +from robotframework_reportportal.variables import Variables logger = logging.getLogger(__name__) VARIABLE_PATTERN = r'^\s*\${[^}]*}\s*=\s*' diff --git a/robotframework_reportportal/logger.py b/robotframework_reportportal/logger.py index 0494971..e895325 100644 --- a/robotframework_reportportal/logger.py +++ b/robotframework_reportportal/logger.py @@ -39,7 +39,7 @@ def log_free_memory(self): from robot.api import logger -from .model import LogMessage +from robotframework_reportportal.model import LogMessage def write(msg: str, level: str = 'INFO', html: bool = False, attachment: Optional[Dict[str, str]] = None, diff --git a/robotframework_reportportal/result_visitor.py b/robotframework_reportportal/result_visitor.py index 23ab5ab..df5886a 100644 --- a/robotframework_reportportal/result_visitor.py +++ b/robotframework_reportportal/result_visitor.py @@ -15,15 +15,14 @@ import re import string from datetime import datetime +from urllib.parse import unquote from robot.api import ResultVisitor -from urllib.parse import unquote -from . import listener -from .time_visitor import corrections +from robotframework_reportportal import listener +from robotframework_reportportal.time_visitor import corrections # noinspection PyUnresolvedReferences -from .variables import _variables - +from robotframework_reportportal.variables import _variables listener = listener.listener() diff --git a/robotframework_reportportal/result_visitor.pyi b/robotframework_reportportal/result_visitor.pyi index a50d5ed..80e778f 100644 --- a/robotframework_reportportal/result_visitor.pyi +++ b/robotframework_reportportal/result_visitor.pyi @@ -13,11 +13,14 @@ # limitations under the License. from typing import Pattern, List -from .listener import listener as ls + from robot.result import ResultVisitor, Result, TestSuite, TestCase, Keyword, Message +from robotframework_reportportal.listener import listener as ls + listener: ls + class RobotResultsVisitor(ResultVisitor): def __init__(self): self._link_pattern = Pattern diff --git a/robotframework_reportportal/service.py b/robotframework_reportportal/service.py index 8cc1869..7f34ce8 100644 --- a/robotframework_reportportal/service.py +++ b/robotframework_reportportal/service.py @@ -14,22 +14,21 @@ """This module is a Robot service for reporting results to ReportPortal.""" +import logging from typing import Optional from dateutil.parser import parse -import logging - +from reportportal_client import RP, create_client from reportportal_client.helpers import ( dict_to_payload, get_launch_sys_attrs, get_package_version, timestamp ) -from reportportal_client import RP, create_client -from .model import Launch, Suite, Test, Keyword, LogMessage -from .variables import Variables -from .static import LOG_LEVEL_MAPPING, STATUS_MAPPING +from robotframework_reportportal.model import Launch, Suite, Test, Keyword, LogMessage +from robotframework_reportportal.static import LOG_LEVEL_MAPPING, STATUS_MAPPING +from robotframework_reportportal.variables import Variables logger = logging.getLogger(__name__) From 4f66e200a7ab84ef2f5a6043ffa14e0570dd4db3 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Mon, 16 Sep 2024 16:18:33 +0300 Subject: [PATCH 06/11] Revert "Closes #193" This reverts commit 3d0a689bb7f61873d73e6400a267b7061498bdd5. --- CHANGELOG.md | 2 -- robotframework_reportportal/listener.py | 1 - 2 files changed, 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9600a40..46dc21a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,6 @@ # Changelog ## [Unreleased] -### Added -- Issue [#193](https://github.com/reportportal/agent-Python-RobotFramework/issues/193): Listener self registration, by @HardNorth ## [5.5.4] ### Fixed diff --git a/robotframework_reportportal/listener.py b/robotframework_reportportal/listener.py index 57b4d06..85e7f2c 100644 --- a/robotframework_reportportal/listener.py +++ b/robotframework_reportportal/listener.py @@ -94,7 +94,6 @@ class listener: def __init__(self) -> None: """Initialize listener attributes.""" - self.ROBOT_LIBRARY_LISTENER = self self._items = LifoQueue() self._service = None self._variables = None From 4dbd0a1bf8fdd64626dcfb53f778bb917b393325 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Tue, 17 Sep 2024 14:45:42 +0300 Subject: [PATCH 07/11] Remove stub file and inline type annotations --- robotframework_reportportal/result_visitor.py | 30 ++++++++----- .../result_visitor.pyi | 44 ------------------- 2 files changed, 18 insertions(+), 56 deletions(-) delete mode 100644 robotframework_reportportal/result_visitor.pyi diff --git a/robotframework_reportportal/result_visitor.py b/robotframework_reportportal/result_visitor.py index df5886a..99c4474 100644 --- a/robotframework_reportportal/result_visitor.py +++ b/robotframework_reportportal/result_visitor.py @@ -15,9 +15,10 @@ import re import string from datetime import datetime +from typing import List, Pattern from urllib.parse import unquote -from robot.api import ResultVisitor +from robot.result import ResultVisitor, Result, TestSuite, TestCase, Keyword, Message from robotframework_reportportal import listener from robotframework_reportportal.time_visitor import corrections @@ -35,15 +36,16 @@ def to_timestamp(time_str): class RobotResultsVisitor(ResultVisitor): - _link_pattern = re.compile("src=[\"\']([^\"\']+)[\"\']") + _link_pattern: Pattern = re.compile("src=[\"\']([^\"\']+)[\"\']") - def start_result(self, result): + def start_result(self, result: Result) -> bool: if "RP_LAUNCH" not in _variables: _variables["RP_LAUNCH"] = result.suite.name if "RP_LAUNCH_DOC" not in _variables: _variables["RP_LAUNCH_DOC"] = result.suite.doc + return True - def start_suite(self, suite): + def start_suite(self, suite: TestSuite) -> bool: ts = to_timestamp(suite.starttime if suite.id not in corrections else corrections[suite.id][0]) attrs = { 'id': suite.id, @@ -57,8 +59,9 @@ def start_suite(self, suite): 'starttime': ts } listener.start_suite(suite.name, attrs, ts) + return True - def end_suite(self, suite): + def end_suite(self, suite: TestSuite) -> None: ts = to_timestamp(suite.endtime if suite.id not in corrections else corrections[suite.id][1]) attrs = { 'id': suite.id, @@ -77,7 +80,7 @@ def end_suite(self, suite): } listener.end_suite(None, attrs, ts) - def start_test(self, test): + def start_test(self, test: TestCase) -> bool: ts = to_timestamp(test.starttime if test.id not in corrections else corrections[test.id][0]) attrs = { 'id': test.id, @@ -94,8 +97,9 @@ def start_test(self, test): 'starttime': ts, } listener.start_test(test.name, attrs, ts) + return True - def end_test(self, test): + def end_test(self, test: TestCase) -> None: ts = to_timestamp(test.endtime if test.id not in corrections else corrections[test.id][1]) attrs = { 'id': test.id, @@ -116,7 +120,7 @@ def end_test(self, test): } listener.end_test(test.name, attrs, ts) - def start_keyword(self, kw): + def start_keyword(self, kw: Keyword) -> bool: ts = to_timestamp(kw.starttime if kw.id not in corrections else corrections[kw.id][0]) attrs = { 'type': string.capwords(kw.type), @@ -129,8 +133,9 @@ def start_keyword(self, kw): 'starttime': ts, } listener.start_keyword(kw.name, attrs, ts) + return True - def end_keyword(self, kw): + def end_keyword(self, kw: Keyword) -> None: ts = to_timestamp(kw.endtime if kw.id not in corrections else corrections[kw.id][1]) attrs = { 'type': string.capwords(kw.type), @@ -146,7 +151,7 @@ def end_keyword(self, kw): } listener.end_keyword(kw.name, attrs, ts) - def start_message(self, msg): + def start_message(self, msg: Message) -> bool: if msg.message: message = { 'message': msg.message, @@ -161,8 +166,9 @@ def start_message(self, msg): try: listener.log_message(message) except Exception: - pass + return False + return True - def parse_message(self, msg): + def parse_message(self, msg: str) -> List[str]: m = self._link_pattern.search(msg) return [m.group(), unquote(m.group(1))] diff --git a/robotframework_reportportal/result_visitor.pyi b/robotframework_reportportal/result_visitor.pyi deleted file mode 100644 index 80e778f..0000000 --- a/robotframework_reportportal/result_visitor.pyi +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2022 EPAM Systems -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Pattern, List - -from robot.result import ResultVisitor, Result, TestSuite, TestCase, Keyword, Message - -from robotframework_reportportal.listener import listener as ls - -listener: ls - - -class RobotResultsVisitor(ResultVisitor): - def __init__(self): - self._link_pattern = Pattern - - def start_result(self, result: Result) -> bool: ... - - def start_suite(self, suite: TestSuite) -> bool: ... - - def end_suite(self, suite: TestSuite) -> None: ... - - def start_test(self, test: TestCase) -> bool: ... - - def end_test(self, test: TestCase) -> None: ... - - def start_keyword(self, kw: Keyword) -> bool: ... - - def end_keyword(self, kw: Keyword) -> None: ... - - def start_message(self, msg: Message) -> bool: ... - - def parse_message(self, param) -> List[str]: ... From 95adb0f658d66c197db14c01f50260fd754411f7 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Tue, 17 Sep 2024 14:46:29 +0300 Subject: [PATCH 08/11] Remove stub file and inline type annotations --- robotframework_reportportal/result_visitor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/robotframework_reportportal/result_visitor.py b/robotframework_reportportal/result_visitor.py index 99c4474..9a0ba10 100644 --- a/robotframework_reportportal/result_visitor.py +++ b/robotframework_reportportal/result_visitor.py @@ -15,7 +15,7 @@ import re import string from datetime import datetime -from typing import List, Pattern +from typing import List, Pattern, Optional from urllib.parse import unquote from robot.result import ResultVisitor, Result, TestSuite, TestCase, Keyword, Message @@ -28,7 +28,7 @@ listener = listener.listener() -def to_timestamp(time_str): +def to_timestamp(time_str: str) -> Optional[str]: if time_str: dt = datetime.strptime(time_str, '%Y%m%d %H:%M:%S.%f') return str(int(dt.timestamp() * 1000)) From e2a9d2d931a0d9316b305a4aa3b8b41d836ea799 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Tue, 17 Sep 2024 16:22:52 +0300 Subject: [PATCH 09/11] Closes #192 - Add Robot link markup to Markdown conversion --- CHANGELOG.md | 2 + examples/suite_doc_with_urls.robot | 6 +++ robotframework_reportportal/helpers.py | 40 +++++++++++++++++++ robotframework_reportportal/model.py | 7 ++-- tests/integration/test_suite_doc_with_urls.py | 39 ++++++++++++++++++ 5 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 examples/suite_doc_with_urls.robot create mode 100644 robotframework_reportportal/helpers.py create mode 100644 tests/integration/test_suite_doc_with_urls.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 46dc21a..054287f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Changelog ## [Unreleased] +### Added +- Issue [#192](https://github.com/reportportal/agent-Python-RobotFramework/issues/192): Robot link markup to Markdown conversion, by @HardNorth ## [5.5.4] ### Fixed diff --git a/examples/suite_doc_with_urls.robot b/examples/suite_doc_with_urls.robot new file mode 100644 index 0000000..d36e1b6 --- /dev/null +++ b/examples/suite_doc_with_urls.robot @@ -0,0 +1,6 @@ +*** Settings *** +Documentation This is a test suite with URLs: [https://www.google.com | Google] and [https://www.google.com] + +*** Test Cases *** +Simple test + Log Hello, world! diff --git a/robotframework_reportportal/helpers.py b/robotframework_reportportal/helpers.py new file mode 100644 index 0000000..7466914 --- /dev/null +++ b/robotframework_reportportal/helpers.py @@ -0,0 +1,40 @@ +# Copyright 2024 EPAM Systems +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""This module contains functions to ease reporting to ReportPortal.""" + +import re +from typing import Iterable + + +def replace_patterns(text: str, patterns: Iterable[tuple[re.Pattern, str]]) -> str: + """Removes starting patterns from the text.""" + result = text + for p, repl in patterns: + result = p.sub(repl, result) + return result + + +BARE_LINK_PATTERN = re.compile(r'\[\s*([^]|]+)]') +NAMED_LINK_PATTERN = re.compile(r'\[\s*([^]|]+)\|\s*([^]]+)]') + +ROBOT_MARKUP_REPLACEMENT_PATTERS = [ + (BARE_LINK_PATTERN, r'<\1>'), + (NAMED_LINK_PATTERN, r'[\2](\1)'), +] + + +def robot_markup_to_markdown(text: str) -> str: + """Convert Robot Framework's text markup to Markdown format.""" + return replace_patterns(text, ROBOT_MARKUP_REPLACEMENT_PATTERS) diff --git a/robotframework_reportportal/model.py b/robotframework_reportportal/model.py index d530987..51bdbd7 100644 --- a/robotframework_reportportal/model.py +++ b/robotframework_reportportal/model.py @@ -17,6 +17,7 @@ import os from typing import Any, Dict, List, Optional, Union +from robotframework_reportportal.helpers import robot_markup_to_markdown from reportportal_client.helpers import gen_attributes @@ -48,7 +49,7 @@ def __init__(self, name: str, robot_attributes: Dict[str, Any]): :param robot_attributes: Suite attributes passed through the listener """ self.robot_attributes = robot_attributes - self.doc = robot_attributes['doc'] + self.doc = robot_markup_to_markdown(robot_attributes['doc']) self.end_time = robot_attributes.get('endtime', '') self.longname = robot_attributes['longname'] self.message = robot_attributes.get('message') @@ -145,7 +146,7 @@ def __init__(self, name: str, robot_attributes: Dict[str, Any], test_attributes: self._tags = robot_attributes['tags'] self.test_attributes = gen_attributes(test_attributes) self.robot_attributes = robot_attributes - self.doc = robot_attributes['doc'] + self.doc = robot_markup_to_markdown(robot_attributes['doc']) self.end_time = robot_attributes.get('endtime', '') self.longname = robot_attributes['longname'] self.message = robot_attributes.get('message') @@ -242,7 +243,7 @@ def __init__(self, name: str, robot_attributes: Dict[str, Any], parent_type: Opt self.robot_attributes = robot_attributes self.args = robot_attributes['args'] self.assign = robot_attributes['assign'] - self.doc = robot_attributes['doc'] + self.doc = robot_markup_to_markdown(robot_attributes['doc']) self.end_time = robot_attributes.get('endtime') self.keyword_name = robot_attributes['kwname'] self.keyword_type = robot_attributes['type'] diff --git a/tests/integration/test_suite_doc_with_urls.py b/tests/integration/test_suite_doc_with_urls.py new file mode 100644 index 0000000..c09dd85 --- /dev/null +++ b/tests/integration/test_suite_doc_with_urls.py @@ -0,0 +1,39 @@ +# Copyright 2022 EPAM Systems +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest import mock + +from tests import REPORT_PORTAL_SERVICE +from tests.helpers import utils + +SIMPLE_TEST = 'examples/suite_doc_with_urls.robot' + + +@mock.patch(REPORT_PORTAL_SERVICE) +def test_suite_doc_with_urls(mock_client_init): + result = utils.run_robot_tests([SIMPLE_TEST]) + assert result == 0 # the test successfully passed + + mock_client = mock_client_init.return_value + launch_start = mock_client.start_launch.call_args_list + launch_finish = mock_client.finish_launch.call_args_list + assert len(launch_start) == len(launch_finish) == 1 + + item_start_calls = mock_client.start_test_item.call_args_list + item_finish_calls = mock_client.finish_test_item.call_args_list + assert len(item_start_calls) == len(item_finish_calls) == 3 + + test_suite = item_start_calls[0] + assert test_suite[1]['description'] == ('This is a test suite with URLs: [Google](https://www.google.com ) and ' + '') From 7bdc814b48fc8aff66195fb644676b993439f5e6 Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Tue, 17 Sep 2024 16:28:20 +0300 Subject: [PATCH 10/11] Fix for Python 3.7 --- robotframework_reportportal/helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/robotframework_reportportal/helpers.py b/robotframework_reportportal/helpers.py index 7466914..e0d9b37 100644 --- a/robotframework_reportportal/helpers.py +++ b/robotframework_reportportal/helpers.py @@ -15,10 +15,10 @@ """This module contains functions to ease reporting to ReportPortal.""" import re -from typing import Iterable +from typing import Iterable, Tuple -def replace_patterns(text: str, patterns: Iterable[tuple[re.Pattern, str]]) -> str: +def replace_patterns(text: str, patterns: Iterable[Tuple[re.Pattern, str]]) -> str: """Removes starting patterns from the text.""" result = text for p, repl in patterns: From 42daccb98b7ac115dca9f326e5e7f53b8cac5fbf Mon Sep 17 00:00:00 2001 From: Vadzim Hushchanskou Date: Tue, 17 Sep 2024 16:31:39 +0300 Subject: [PATCH 11/11] Fix pydocstyle --- robotframework_reportportal/helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/robotframework_reportportal/helpers.py b/robotframework_reportportal/helpers.py index e0d9b37..d7f696c 100644 --- a/robotframework_reportportal/helpers.py +++ b/robotframework_reportportal/helpers.py @@ -19,7 +19,7 @@ def replace_patterns(text: str, patterns: Iterable[Tuple[re.Pattern, str]]) -> str: - """Removes starting patterns from the text.""" + """Replace given patterns in the text.""" result = text for p, repl in patterns: result = p.sub(repl, result)