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 \\ 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, "\\") # 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"], "\\")
- 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")