diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 9de6644..f604cfb 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -40,12 +40,6 @@ jobs:
- name: Build Package
run: python -m build
- - name: Publish to PyPI
- env:
- TWINE_USERNAME: __token__
- TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
- run: twine upload dist/*
-
- name: Create GitHub Release
uses: softprops/action-gh-release@v1
with:
@@ -53,3 +47,9 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ - name: Publish to PyPI
+ env:
+ TWINE_USERNAME: __token__
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
+ run: twine upload dist/*
+
diff --git a/atest/config/config_with_colors.toml b/atest/config/config_with_colors.toml
index 193392a..3e38030 100644
--- a/atest/config/config_with_colors.toml
+++ b/atest/config/config_with_colors.toml
@@ -4,7 +4,7 @@ verbose_mode = true
[colors]
# DEFAULT THEME:
-default = "robot"
+default = "dark"
# OR CUSTOM THEME:
# background = "#000028"
# inner_color = "#000028"
diff --git a/src/testdoc/__main__.py b/src/testdoc/__main__.py
index 95f3538..502a396 100644
--- a/src/testdoc/__main__.py
+++ b/src/testdoc/__main__.py
@@ -1,3 +1,4 @@
from testdoc.cli import main
+
if __name__ == "__main__":
main()
\ No newline at end of file
diff --git a/src/testdoc/default.toml b/src/testdoc/default.toml
new file mode 100644
index 0000000..812d283
--- /dev/null
+++ b/src/testdoc/default.toml
@@ -0,0 +1,3 @@
+# Find here some default settings like the used default theme
+[default]
+theme = "dark"
diff --git a/src/testdoc/html/themes/theme_config.py b/src/testdoc/html/themes/theme_config.py
index c94e64d..f5dcda3 100644
--- a/src/testdoc/html/themes/theme_config.py
+++ b/src/testdoc/html/themes/theme_config.py
@@ -1,10 +1,17 @@
from ...helper.cliargs import CommandLineArguments
from .themes import DEFAULT_THEME, ROBOT_THEME, DARK_THEME, BLUE_THEME
+import os
+import tomli
+
class ThemeConfig():
+ default_config = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "default.toml")
+
def __init__(self):
self.args = CommandLineArguments().data
+ with open(self.default_config, "rb") as file:
+ self.config = tomli.load(file)
def theme(self):
_theme = self.args.colors
@@ -12,7 +19,7 @@ def theme(self):
if "default" in _theme:
return self._get_predefined_theme(_theme.get("default"))
return _theme
- return DARK_THEME
+ return self._get_predefined_theme(self.config["default"]["theme"])
def _get_predefined_theme(self, theme: str):
theme = theme.strip()
diff --git a/src/testdoc/parser/modifier/sourceprefixmodifier.py b/src/testdoc/parser/modifier/sourceprefixmodifier.py
index 1ae33a4..7219d38 100644
--- a/src/testdoc/parser/modifier/sourceprefixmodifier.py
+++ b/src/testdoc/parser/modifier/sourceprefixmodifier.py
@@ -1,23 +1,45 @@
import os
+from abc import ABC, abstractmethod
from robot.api import TestSuite
from ...helper.cliargs import CommandLineArguments
from ...helper.logger import Logger
+available_implementations = "gitlab"
+
+########################################
+# Interface
+########################################
+class SourceModifier(ABC):
+ @abstractmethod
+ def apply(self, suite_dict, prefix):
+ pass
+
+########################################
+# Factory
+########################################
+class SourceModifierFactory:
+ @staticmethod
+ def get_modifier(prefix_type: str) -> SourceModifier:
+ if prefix_type.lower() == "gitlab":
+ return GitLabModifier()
+ # EXAMPLE Extension:
+ # elif prefix_type.lower() == "github":
+ # return GitHubModifier()
+ raise ValueError(
+ f"No source modifier found for type '{prefix_type}' - actually available implementation are:\n{available_implementations}"
+ )
+
+########################################
+# Prefix Modifier - Implementation
+########################################
class SourcePrefixModifier():
GITLAB_CONNECTOR = "-/blob/main/"
def __init__(self):
self.args = CommandLineArguments().data
-
- def _modify(self, suite: TestSuite, prefix: str):
- prefix_type, prefix = self._prefix_validation(prefix)
- if "gitlab" in prefix_type:
- SourcePrefixGitLab()._apply_gitlab_source_to_suite(suite, prefix)
- else:
- raise ValueError(f"No matching source-prefix modifier found for: {prefix_type} with prefix: {prefix}")
def _prefix_validation(self, prefix: str) -> list:
if "::" not in prefix:
@@ -27,11 +49,16 @@ def _prefix_validation(self, prefix: str) -> list:
def modify_source_prefix(self, suite_object: TestSuite) -> TestSuite:
Logger().LogKeyValue("Using Prefix for Source: ", self.args.sourceprefix, "yellow") if self.args.verbose_mode else None
+ prefix_type, prefix = self._prefix_validation(self.args.sourceprefix)
+ modifier = SourceModifierFactory.get_modifier(prefix_type)
for suite in suite_object:
- self._modify(suite, self.args.sourceprefix)
+ modifier.apply(suite, prefix)
return suite_object
-class SourcePrefixGitLab():
+########################################
+# Low-Level Implementation for GitLab
+########################################
+class GitLabModifier():
"""
Source Prefix Modifier for "GitLab" Projects.
Expected CMD Line Arg: "gitlab::prefix"
@@ -62,7 +89,7 @@ def _convert_to_gitlab_url(self, file_path, prefix):
rel_path = os.path.relpath(file_path, git_root).replace(os.sep, "/")
return prefix.rstrip("/") + "/-/blob/" + git_branch + "/" + rel_path
- def _apply_gitlab_source_to_suite(self, suite_dict, prefix):
+ def apply(self, suite_dict, prefix):
try:
suite_dict["source"] = self._convert_to_gitlab_url(suite_dict["source"], prefix)
except:
@@ -75,4 +102,9 @@ def _apply_gitlab_source_to_suite(self, suite_dict, prefix):
test["source"] = "GitLink error"
for sub_suite in suite_dict.get("sub_suites", []):
- self._apply_gitlab_source_to_suite(sub_suite, prefix)
+ self.apply(sub_suite, prefix)
+
+########################################
+# Low-Level Implementation for ...
+# [FUTURE EXTENSIONS LIKE GITHUB]
+########################################
\ No newline at end of file
diff --git a/src/testdoc/parser/modifier/suitefilemodifier.py b/src/testdoc/parser/modifier/suitefilemodifier.py
index 7039e8c..1c0048e 100644
--- a/src/testdoc/parser/modifier/suitefilemodifier.py
+++ b/src/testdoc/parser/modifier/suitefilemodifier.py
@@ -18,9 +18,6 @@ def run(self, suite_object: TestSuite = None):
self.suite = suite_object
# Modify generic params / hide some params
- self._modify_root_suite_name()
- self._modify_root_suite_doc()
- self._modify_root_suite_metadata()
self._modify_tags()
self._modify_test_doc()
self._modify_suite_doc()
@@ -29,29 +26,16 @@ def run(self, suite_object: TestSuite = None):
return self.suite
#############################################################################################################################
-
- def _modify_root_suite_name(self):
- if not self.args.name:
- return
- Logger().LogKeyValue("Modified Name of Root Suite: ", self.args.name, "yellow") if self.args.verbose_mode else None
- self.suite[0]["name"] = self.args.name
-
- #############################################################################################################################
-
- def _modify_root_suite_doc(self):
- if not self.args.doc:
- return
- Logger().LogKeyValue("Modified Doc of Root Suite: ", self.args.name, "yellow") if self.args.verbose_mode else None
- self.suite[0]["doc"] = self.args.doc
-
- #############################################################################################################################
-
- def _modify_root_suite_metadata(self):
- if not self.args.metadata:
- return
- Logger().LogKeyValue("Modified Metadata of Root Suite: ", self.args.metadata, "yellow") if self.args.verbose_mode else None
- formatted_metadata = "
".join([f"{k}: {v}" for k, v in self.args.metadata.items()])
- self.suite[0]["metadata"] = formatted_metadata
+
+ # Modify name, doc & metadata via officially provided robot api
+ def _modify_root_suite_details(self, suite: TestSuite):
+ if self.args.name:
+ suite.configure(name=self.args.name)
+ if self.args.doc:
+ suite.configure(doc=self.args.doc)
+ if self.args.metadata:
+ suite.configure(metadata=self.args.metadata)
+ return suite
#############################################################################################################################
diff --git a/src/testdoc/parser/testcaseparser.py b/src/testdoc/parser/testcaseparser.py
index 1662d7d..1ce0c05 100644
--- a/src/testdoc/parser/testcaseparser.py
+++ b/src/testdoc/parser/testcaseparser.py
@@ -23,6 +23,7 @@ def parse_test(self,
suite_info["tests"].append(test_info)
return suite_info
+ # Consider tags via officially provided robot api
def consider_tags(self, suite: TestSuite) -> TestSuite:
if len(self.args.include) > 0:
suite.configure(include_tags=self.args.include)
diff --git a/src/testdoc/parser/testsuiteparser.py b/src/testdoc/parser/testsuiteparser.py
index fe06638..606ca5a 100644
--- a/src/testdoc/parser/testsuiteparser.py
+++ b/src/testdoc/parser/testsuiteparser.py
@@ -2,6 +2,7 @@
from robot.api import SuiteVisitor, TestSuite
from .testcaseparser import TestCaseParser
+from .modifier.suitefilemodifier import SuiteFileModifier
class RobotSuiteParser(SuiteVisitor):
def __init__(self):
@@ -23,7 +24,7 @@ def visit_suite(self, suite):
"total_tests": 0,
"tests": [],
"sub_suites": [],
- "metadata": None
+ "metadata": "
".join([f"{k}: {v}" for k, v in suite.metadata.items()]) if suite.metadata else None
}
# Parse Test Cases
@@ -39,6 +40,7 @@ def visit_suite(self, suite):
def parse_suite(self, suite_path):
suite = TestSuite.from_file_system(suite_path)
suite = TestCaseParser().consider_tags(suite)
+ suite = SuiteFileModifier()._modify_root_suite_details(suite)
suite.visit(self)
return self.suites
@@ -65,4 +67,4 @@ def _is_directory(self, suite) -> bool:
def _already_parsed(self, suite):
existing_suite = next((s for s in self.suites if s["name"] == suite.name), None)
if existing_suite:
- return
\ No newline at end of file
+ return