diff --git a/testit-adapter-behave/setup.py b/testit-adapter-behave/setup.py index ad94cb2..0decebb 100644 --- a/testit-adapter-behave/setup.py +++ b/testit-adapter-behave/setup.py @@ -1,6 +1,6 @@ from setuptools import find_packages, setup -VERSION = "3.10.4" +VERSION = "3.10.5" setup( name='testit-adapter-behave', diff --git a/testit-adapter-nose/setup.py b/testit-adapter-nose/setup.py index a9253f3..f3d2dd1 100644 --- a/testit-adapter-nose/setup.py +++ b/testit-adapter-nose/setup.py @@ -1,6 +1,6 @@ from setuptools import setup, find_packages -VERSION = "3.10.4" +VERSION = "3.10.5" setup( name='testit-adapter-nose', diff --git a/testit-adapter-pytest/setup.py b/testit-adapter-pytest/setup.py index 31104b4..16308e0 100644 --- a/testit-adapter-pytest/setup.py +++ b/testit-adapter-pytest/setup.py @@ -1,6 +1,6 @@ from setuptools import find_packages, setup -VERSION = "3.10.4" +VERSION = "3.10.5" setup( name='testit-adapter-pytest', diff --git a/testit-adapter-robotframework/setup.py b/testit-adapter-robotframework/setup.py index b5918bb..0b61bc3 100644 --- a/testit-adapter-robotframework/setup.py +++ b/testit-adapter-robotframework/setup.py @@ -1,6 +1,6 @@ from setuptools import find_packages, setup -VERSION = "3.10.4" +VERSION = "3.10.5" setup( name='testit-adapter-robotframework', diff --git a/testit-python-commons/setup.py b/testit-python-commons/setup.py index a1d0efc..9f1128b 100644 --- a/testit-python-commons/setup.py +++ b/testit-python-commons/setup.py @@ -1,6 +1,6 @@ from setuptools import find_packages, setup -VERSION = "3.10.4" +VERSION = "3.10.5" setup( name='testit-python-commons', diff --git a/testit-python-commons/src/testit_python_commons/client/api_client.py b/testit-python-commons/src/testit_python_commons/client/api_client.py index 9411acb..22f1d77 100644 --- a/testit-python-commons/src/testit_python_commons/client/api_client.py +++ b/testit-python-commons/src/testit_python_commons/client/api_client.py @@ -23,8 +23,7 @@ from testit_python_commons.models.test_result import TestResult from testit_python_commons.services.logger import adapter_logger from testit_python_commons.services.retry import retry -from testit_python_commons.utils.html_escape_utils import HtmlEscapeUtils -from typing import List, Any +from typing import List class ApiClientWorker: @@ -61,11 +60,6 @@ def __get_api_client(api_client_config: Configuration, token: str) -> ApiClient: header_name='Authorization', header_value='PrivateToken ' + token) - @staticmethod - def _escape_html_in_model(model: Any) -> Any: - """Apply HTML escaping to all models before sending to API""" - return HtmlEscapeUtils.escape_html_in_object(model) - @adapter_logger def create_test_run(self, test_run_name: str = None) -> str: test_run_name = f'TestRun_{datetime.today().strftime("%Y-%m-%dT%H:%M:%S")}' if \ @@ -74,7 +68,6 @@ def create_test_run(self, test_run_name: str = None) -> str: self.__config.get_project_id(), test_run_name ) - model = self._escape_html_in_model(model) response = self.__test_run_api.create_empty(create_empty_request=model) @@ -95,7 +88,6 @@ def get_test_run(self, test_run_id: str) -> TestRunV2ApiResult: def update_test_run(self, test_run: TestRunV2ApiResult) -> None: """Function updates test run.""" model = Converter.build_update_empty_request(test_run) - model = HtmlEscapeUtils.escape_html_in_object(model) logging.debug(f"Updating test run with model: {model}") self.__test_run_api.update_empty(update_empty_request=model) @@ -321,7 +313,6 @@ def __create_test(self, test_result: TestResult) -> str: test_result, self.__config.get_project_id(), work_item_ids_for_link_with_auto_test) - model = self._escape_html_in_model(model) autotest_response = self.__autotest_api.create_auto_test(create_auto_test_request=model) @@ -333,7 +324,6 @@ def __create_test(self, test_result: TestResult) -> str: def __create_tests(self, autotests_for_create: List[AutoTestPostModel]) -> None: logging.debug(f'Creating autotests: "{autotests_for_create}') - autotests_for_create = self._escape_html_in_model(autotests_for_create) self.__autotest_api.create_multiple(auto_test_post_model=autotests_for_create) logging.debug(f'Autotests were created') @@ -343,7 +333,6 @@ def __update_test(self, test_result: TestResult, autotest: AutoTestApiResult) -> logging.debug(f'Autotest "{test_result.get_autotest_name()}" was found') model = Converter.prepare_to_update_autotest(test_result, autotest, self.__config.get_project_id()) - model = self._escape_html_in_model(model) try: self.__autotest_api.update_auto_test(update_auto_test_request=model) @@ -356,7 +345,6 @@ def __update_test(self, test_result: TestResult, autotest: AutoTestApiResult) -> def __update_tests(self, autotests_for_update: List[AutoTestPutModel]) -> None: logging.debug(f'Updating autotests: {autotests_for_update}') - autotests_for_update = self._escape_html_in_model(autotests_for_update) self.__autotest_api.update_multiple(auto_test_put_model=autotests_for_update) logging.debug(f'Autotests were updated') @@ -384,7 +372,6 @@ def __load_test_result(self, test_result: TestResult) -> str: model = Converter.test_result_to_testrun_result_post_model( test_result, self.__config.get_configuration_id()) - model = self._escape_html_in_model(model) response = self.__test_run_api.set_auto_test_results_for_test_run( id=self.__config.get_test_run_id(), @@ -412,8 +399,6 @@ def update_test_results(self, fixtures_containers: dict, test_result_ids: dict) test_result.get_setup_results()) model.teardown_results = Converter.step_results_to_auto_test_step_result_update_request( test_result.get_teardown_results()) - - model = self._escape_html_in_model(model) try: self.__test_results_api.api_v2_test_results_id_put( diff --git a/testit-python-commons/src/testit_python_commons/models/link.py b/testit-python-commons/src/testit_python_commons/models/link.py index 1968fe7..9d917d5 100644 --- a/testit-python-commons/src/testit_python_commons/models/link.py +++ b/testit-python-commons/src/testit_python_commons/models/link.py @@ -1,5 +1,6 @@ from testit_python_commons.models.link_type import LinkType from testit_python_commons.services.logger import adapter_logger +from testit_python_commons.utils import HtmlEscapeUtils class Link: @@ -20,7 +21,7 @@ def get_url(self) -> str: @adapter_logger def set_title(self, title: str): - self.__title = title + self.__title = HtmlEscapeUtils.escape_html_tags(title) return self @@ -40,7 +41,7 @@ def get_link_type(self) -> LinkType: @adapter_logger def set_description(self, description: str): - self.__description = description + self.__description = HtmlEscapeUtils.escape_html_tags(description) return self diff --git a/testit-python-commons/src/testit_python_commons/models/step_result.py b/testit-python-commons/src/testit_python_commons/models/step_result.py index 72315f8..0750b38 100644 --- a/testit-python-commons/src/testit_python_commons/models/step_result.py +++ b/testit-python-commons/src/testit_python_commons/models/step_result.py @@ -1,3 +1,6 @@ +from testit_python_commons.utils.html_escape_utils import HtmlEscapeUtils + + class StepResult: __title: str = None __outcome: str = None @@ -15,7 +18,7 @@ def __init__(self): self.__parameters = {} def set_title(self, title: str): - self.__title = title + self.__title = HtmlEscapeUtils.escape_html_tags(title) return self @@ -23,7 +26,7 @@ def get_title(self) -> str: return self.__title def set_outcome(self, outcome: str): - self.__outcome = outcome + self.__outcome = HtmlEscapeUtils.escape_html_tags(outcome) return self @@ -31,7 +34,7 @@ def get_outcome(self) -> str: return self.__outcome def set_description(self, description: str): - self.__description = description + self.__description = HtmlEscapeUtils.escape_html_tags(description) return self @@ -79,7 +82,7 @@ def get_attachments(self) -> list: return self.__attachments def set_parameters(self, parameters: dict): - self.__parameters = parameters + self.__parameters = HtmlEscapeUtils.escape_html_in_object(parameters) return self diff --git a/testit-python-commons/src/testit_python_commons/models/test_result.py b/testit-python-commons/src/testit_python_commons/models/test_result.py index c60a678..174bb76 100644 --- a/testit-python-commons/src/testit_python_commons/models/test_result.py +++ b/testit-python-commons/src/testit_python_commons/models/test_result.py @@ -3,6 +3,7 @@ from testit_python_commons.models.link import Link from testit_python_commons.models.step_result import StepResult from testit_python_commons.services.logger import adapter_logger +from testit_python_commons.utils import HtmlEscapeUtils class TestResult: @@ -33,7 +34,7 @@ class TestResult: @adapter_logger def set_external_id(self, external_id: str): - self.__external_id = external_id + self.__external_id = HtmlEscapeUtils.escape_html_tags(external_id) return self @@ -43,7 +44,7 @@ def get_external_id(self) -> str: @adapter_logger def set_autotest_name(self, autotest_name: str): - self.__autotest_name = autotest_name + self.__autotest_name = HtmlEscapeUtils.escape_html_tags(autotest_name) return self @@ -53,7 +54,7 @@ def get_autotest_name(self) -> str: @adapter_logger def set_outcome(self, outcome: str): - self.__outcome = outcome + self.__outcome = HtmlEscapeUtils.escape_html_tags(outcome) return self @@ -63,7 +64,7 @@ def get_outcome(self) -> str: @adapter_logger def set_title(self, title: str): - self.__title = title + self.__title = HtmlEscapeUtils.escape_html_tags(title) return self @@ -73,7 +74,7 @@ def get_title(self) -> str: @adapter_logger def set_description(self, description: str): - self.__description = description + self.__description = HtmlEscapeUtils.escape_html_tags(description) return self @@ -113,7 +114,7 @@ def get_completed_on(self) -> str: @adapter_logger def set_namespace(self, namespace: str): - self.__namespace = namespace + self.__namespace = HtmlEscapeUtils.escape_html_tags(namespace) return self @@ -123,7 +124,7 @@ def get_namespace(self) -> str: @adapter_logger def set_classname(self, classname: str): - self.__classname = classname + self.__classname = HtmlEscapeUtils.escape_html_tags(classname) return self @@ -133,7 +134,7 @@ def get_classname(self) -> str: @adapter_logger def set_message(self, message: str): - self.__message = message + self.__message = HtmlEscapeUtils.escape_html_tags(message) return self @@ -143,7 +144,7 @@ def get_message(self) -> str: @adapter_logger def set_traces(self, traces: str): - self.__traces = traces + self.__traces = HtmlEscapeUtils.escape_html_tags(traces) return self @@ -213,7 +214,7 @@ def get_attachments(self) -> list: @adapter_logger def set_labels(self, labels: list): - self.__labels = labels + self.__labels = HtmlEscapeUtils.escape_html_in_object(labels) return self @@ -233,7 +234,7 @@ def get_work_item_ids(self) -> list: @adapter_logger def set_parameters(self, parameters: dict): - self.__parameters = parameters + self.__parameters = HtmlEscapeUtils.escape_html_in_object(parameters) return self @@ -243,7 +244,7 @@ def get_parameters(self) -> dict: @adapter_logger def set_properties(self, properties: dict): - self.__properties = properties + self.__properties = HtmlEscapeUtils.escape_html_in_object(properties) return self diff --git a/testit-python-commons/src/testit_python_commons/models/test_result_with_all_fixture_step_results_model.py b/testit-python-commons/src/testit_python_commons/models/test_result_with_all_fixture_step_results_model.py index c147b2e..69e512c 100644 --- a/testit-python-commons/src/testit_python_commons/models/test_result_with_all_fixture_step_results_model.py +++ b/testit-python-commons/src/testit_python_commons/models/test_result_with_all_fixture_step_results_model.py @@ -1,6 +1,7 @@ from testit_python_commons.models.step_result import StepResult from typing import List + class TestResultWithAllFixtureStepResults: def __init__(self, test_result_id: str): self.__test_result_id = test_result_id diff --git a/testit-python-commons/src/testit_python_commons/utils/html_escape_utils.py b/testit-python-commons/src/testit_python_commons/utils/html_escape_utils.py index 98eebf2..14f41d0 100644 --- a/testit-python-commons/src/testit_python_commons/utils/html_escape_utils.py +++ b/testit-python-commons/src/testit_python_commons/utils/html_escape_utils.py @@ -21,8 +21,8 @@ class HtmlEscapeUtils: # Regex patterns to escape only non-escaped characters # Using negative lookbehind to avoid double escaping - _LESS_THAN_PATTERN = re.compile(r'(?') + _LESS_THAN_PATTERN = re.compile('<') + _GREATER_THAN_PATTERN = re.compile('>') @staticmethod def escape_html_tags(text: Optional[str]) -> Optional[str]: @@ -52,8 +52,8 @@ def escape_html_tags(text: Optional[str]) -> Optional[str]: return text # No HTML tags found, return original string # Use regex with negative lookbehind to escape only non-escaped characters - result = HtmlEscapeUtils._LESS_THAN_PATTERN.sub(r'\\<', text) - result = HtmlEscapeUtils._GREATER_THAN_PATTERN.sub(r'\\>', result) + result = HtmlEscapeUtils._LESS_THAN_PATTERN.sub('<', text) + result = HtmlEscapeUtils._GREATER_THAN_PATTERN.sub('>', result) return result diff --git a/testit-python-commons/tests/test_html_escape_utils.py b/testit-python-commons/tests/test_html_escape_utils.py index 4875f1f..08a598b 100644 --- a/testit-python-commons/tests/test_html_escape_utils.py +++ b/testit-python-commons/tests/test_html_escape_utils.py @@ -16,7 +16,7 @@ def test_escape_html_tags_basic(self): """Test basic HTML tag escaping""" text = "Hello world" result = HtmlEscapeUtils.escape_html_tags(text) - expected = "Hello \\alert('test')\\ world" + expected = "Hello <script>alert('test')</script> world" self.assertEqual(result, expected) def test_escape_html_tags_no_html_content(self): @@ -38,18 +38,18 @@ def test_escape_html_tags_none(self): def test_escape_html_tags_no_double_escaping(self): """Test that already escaped characters are not double-escaped""" - text = "Already \\ and " + text = "Already <escaped> and " result = HtmlEscapeUtils.escape_html_tags(text) - expected = "Already \\ and \\" + expected = "Already <escaped> and <not_escaped>" self.assertEqual(result, expected) def test_escape_html_tags_various_tags(self): """Test escaping of various HTML tag types""" test_cases = [ - ("
content
", "\\content\\"), - ("", "\\"), - ("
", "\\"), - ("text", "\\text\\"), + ("
content
", "<div>content</div>"), + ("", "<img src='test.jpg'/>"), + ("
", "<br>"), + ("text", "<span class='test'>text</span>"), ("No tags here", "No tags here"), # Should remain unchanged ("<>", "<>"), # Empty angle brackets - should remain unchanged ("< >", "< >"), # Spaced angle brackets - should remain unchanged @@ -66,8 +66,8 @@ def test_escape_html_in_object(self): result = HtmlEscapeUtils.escape_html_in_object(test_obj) self.assertEqual(result.name, "Test Name") # No escaping needed - self.assertEqual(result.description, "\\alert('xss')\\") # Escaped - self.assertEqual(result.tags[0], "\\") # Escaped + self.assertEqual(result.description, "<script>alert('xss')</script>") # Escaped + self.assertEqual(result.tags[0], "<tag>") # Escaped self.assertEqual(result.tags[1], "normal_tag") # No escaping needed def test_escape_html_in_object_list(self): @@ -78,8 +78,8 @@ def test_escape_html_in_object_list(self): ] result = HtmlEscapeUtils.escape_html_in_object_list(test_list) - self.assertEqual(result[0].description, "\\content\\") - self.assertEqual(result[1].description, "\\more\\") + self.assertEqual(result[0].description, "<div>content</div>") + self.assertEqual(result[1].description, "<span>more</span>") def test_escape_disabled_by_env_var(self): """Test that escaping can be disabled via environment variable""" @@ -107,8 +107,8 @@ def test_escape_html_in_dictionary(self): result = HtmlEscapeUtils.escape_html_in_object(test_dict) self.assertEqual(result["name"], "Test") - self.assertEqual(result["description"], "\\alert('xss')\\") - self.assertEqual(result["tags"][0], "\\") + self.assertEqual(result["description"], "<script>alert('xss')</script>") + self.assertEqual(result["tags"][0], "<tag>") self.assertEqual(result["tags"][1], "normal_tag")