robotframework-testdoc 0.1.4__py3-none-any.whl → 0.1.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of robotframework-testdoc might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-testdoc
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: A CLI Tool to generate a Test Documentation for your RobotFramework Test Scripts.
5
5
  Author-email: Marvin Klerx <marvinklerx1@gmail.com>
6
6
  License: MIT
@@ -107,8 +107,8 @@ You can select between several themes (color configurations) for your HTML docum
107
107
 
108
108
  ### Default Themes
109
109
 
110
- There are a few predefined default themes available that you can choose via the toml-configuration file.
111
- Therefore, please use the following syntax:
110
+ There are a few predefined default themes available that you can choose via the toml-configuration file OR cli.
111
+ Therefore, please use the following syntax: for the toml file
112
112
  ```toml
113
113
  [colors]
114
114
  # Use the default theme
@@ -125,6 +125,15 @@ default = "robot"
125
125
  default = 3
126
126
  ```
127
127
 
128
+ For setting it via CLI, please use the following:
129
+ ```shell
130
+ # Applying dark theme
131
+ testdoc ... -S dark PATH OUTPUT_FILE
132
+
133
+ # Applying blue theme
134
+ testdoc ... --style blue PATH OUTPUT_FILE
135
+ ```
136
+
128
137
  > [!TIP]
129
138
  > You can select the default theme using either a string value or an integer value.
130
139
 
@@ -146,3 +155,17 @@ robot_icon = "#00ffb9"
146
155
 
147
156
  > [!TIP]
148
157
  > Please make sure to configure all available color values from this example — missing values may cause layout or rendering issues in the generated HTML document!
158
+
159
+ ### Default Themes - Screenshot
160
+
161
+ #### Dark
162
+
163
+ ![alt text](docs/style_dark.png)
164
+
165
+ #### Blue
166
+
167
+ ![alt text](docs/style_blue.png)
168
+
169
+ #### Robot / Default
170
+
171
+ ![alt text](docs/style_robot.png)
@@ -0,0 +1,25 @@
1
+ robotframework_testdoc-0.1.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
2
+ testdoc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ testdoc/__main__.py,sha256=09c4nsw4Vnp1LaK0CnlofJQFbKmeFexOXyTBDY9NrFk,67
4
+ testdoc/cli.py,sha256=WyiuX9ONHMeeXAxXrF3XjR8Pal_WFg04dGVON7msrLc,4623
5
+ testdoc/default.toml,sha256=PK7O2gat8326ZYOXBC1mt6-5ceBhdbgs0BL1uo4XLjQ,87
6
+ testdoc/testdoc.py,sha256=cVJguXoFhkCM2nkUlZGB8m-6rBhKwthFFtdtz0T2l4Q,772
7
+ testdoc/helper/cliargs.py,sha256=eT7-1WGhHXbVSdC4LetkQQmhrhuISF35V3Aody-ymEk,1285
8
+ testdoc/helper/datetimeconverter.py,sha256=1IuJ_rZlKKut3pallS9WSdlQ00YNQX2Nhf2oYWt7QDc,159
9
+ testdoc/helper/logger.py,sha256=STPEEdMIGpK004xHDskj8zzW3knBWP05GllYajQMaSY,272
10
+ testdoc/helper/pathconverter.py,sha256=Il4SX8EdpKPjOiZt97zC4TBLxp2tKUhfyyS2J1qWpyg,1656
11
+ testdoc/html/images/robotframework.svg,sha256=w1yNL6XtuHOCCwzjGX3pZQG7ZcJghzllvc7cQ9MKKbQ,1426
12
+ testdoc/html/templates/jinja_template_01.html,sha256=gw2hEx2P7zLsQP5-4fA2hErWJuhkUTZkEakXxRzWKtU,18213
13
+ testdoc/html/themes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
+ testdoc/html/themes/theme_config.py,sha256=3AFUSoddhAZswcEsshbvqcnmbLOFaBYUFy-lrfNBV3Q,1495
15
+ testdoc/html/themes/themes.py,sha256=6xlHW7O-XO9Z1B33_aRwzffkuWR65jM7CYXsZWUjdmY,1091
16
+ testdoc/html_rendering/render.py,sha256=BzPGyePwjCFZAXRHDF-ccM2xRKY-6Cnym1-uDb9i1AQ,1083
17
+ testdoc/parser/testcaseparser.py,sha256=69WGA2aM2NsC1mU8PVGXfW23TEoYhJDjEfsyNwW2AoM,1243
18
+ testdoc/parser/testsuiteparser.py,sha256=eqFMaEa2aXYCkoAl8wLmA7NsPOx8oxY8KfTKVxyGIPU,2595
19
+ testdoc/parser/modifier/sourceprefixmodifier.py,sha256=Vy_keEKztF7UrjtWjmkU7usGR7E-xLvxJOWocPRu6KI,3950
20
+ testdoc/parser/modifier/suitefilemodifier.py,sha256=OuDuleQj4dRjUcu0AROEPZ-2vR3lWJfWmQVuoWLkXuY,4865
21
+ robotframework_testdoc-0.1.5.dist-info/METADATA,sha256=xzo1mMtpPf_-pQ8nU4cZ5bB1vcBcwf8AStjqwN7ABpE,4970
22
+ robotframework_testdoc-0.1.5.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
23
+ robotframework_testdoc-0.1.5.dist-info/entry_points.txt,sha256=BUHy23mdlGCqYOWpsvRhSb1c0tPMzIwyTwr-sHI6xUs,45
24
+ robotframework_testdoc-0.1.5.dist-info/top_level.txt,sha256=p1axpYooAmdwwXQOzFsSXF3u_-88QFKCDxPf67siv3Y,8
25
+ robotframework_testdoc-0.1.5.dist-info/RECORD,,
testdoc/__main__.py CHANGED
@@ -1,3 +1,4 @@
1
1
  from testdoc.cli import main
2
+
2
3
  if __name__ == "__main__":
3
4
  main()
testdoc/cli.py CHANGED
@@ -19,6 +19,7 @@ from .helper.cliargs import CommandLineArguments
19
19
  @click.option("--hide-suite-doc", is_flag=True, required=False, help="If given, suite documentation is hidden")
20
20
  @click.option("--hide-source", is_flag=True, required=False, help="If given, test suite/ test case source is hidden")
21
21
  @click.option("--hide-keywords", is_flag=True, required=False, help="If given, keyword calls in test cases are hidden")
22
+ @click.option("-S", "--style", required=False, help="Choose a predefined default style theme - 'default', 'robot', 'dark' or 'blue' ")
22
23
  @click.option("-c", "--configfile", required=False, help="Optional .toml configuration file (includes all cmd-args)")
23
24
  @click.option("-v", "--verbose", is_flag=True, required=False, help="More precise debugging into shell")
24
25
  @click.argument("PATH")
@@ -36,6 +37,7 @@ def main(
36
37
  hide_suite_doc,
37
38
  hide_source,
38
39
  hide_keywords,
40
+ style,
39
41
  configfile,
40
42
  verbose,
41
43
  path,
@@ -77,6 +79,7 @@ def main(
77
79
  "hide_source": hide_source or None,
78
80
  "hide_keywords": hide_keywords or None,
79
81
  "verbose_mode": verbose or None,
82
+ "style": style or None,
80
83
  "config_file": configfile or None,
81
84
  }
82
85
  args.suite_file = path
testdoc/default.toml ADDED
@@ -0,0 +1,3 @@
1
+ # Find here some default settings like the used default theme
2
+ [default]
3
+ theme = "dark"
testdoc/helper/cliargs.py CHANGED
@@ -19,6 +19,7 @@ class CommandLineArgumentsData:
19
19
  config_file: str = None
20
20
  verbose_mode: bool = False
21
21
  suite_file: str = None
22
+ style: str = None
22
23
  output_file: str = None
23
24
  colors: dict = None
24
25
 
@@ -1,18 +1,32 @@
1
1
  from ...helper.cliargs import CommandLineArguments
2
2
  from .themes import DEFAULT_THEME, ROBOT_THEME, DARK_THEME, BLUE_THEME
3
3
 
4
+ import os
5
+ import tomli
6
+
4
7
  class ThemeConfig():
5
8
 
9
+ default_config = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..", "default.toml")
10
+
6
11
  def __init__(self):
7
12
  self.args = CommandLineArguments().data
13
+ with open(self.default_config, "rb") as file:
14
+ self.config = tomli.load(file)
15
+
16
+ #######################################################################################################
8
17
 
9
18
  def theme(self):
10
- _theme = self.args.colors
11
- if _theme:
12
- if "default" in _theme:
13
- return self._get_predefined_theme(_theme.get("default"))
14
- return _theme
15
- return DARK_THEME
19
+ _cli_style = self.args.style
20
+ if _cli_style:
21
+ return self._get_predefined_theme(_cli_style)
22
+ _toml_theme = self.args.colors
23
+ if _toml_theme:
24
+ if "default" in _toml_theme:
25
+ return self._get_predefined_theme(_toml_theme.get("default"))
26
+ return _toml_theme
27
+ return self._get_predefined_theme(self.config["default"]["theme"])
28
+
29
+ #######################################################################################################
16
30
 
17
31
  def _get_predefined_theme(self, theme: str):
18
32
  theme = theme.strip()
@@ -1,23 +1,45 @@
1
1
  import os
2
+ from abc import ABC, abstractmethod
2
3
 
3
4
  from robot.api import TestSuite
4
5
 
5
6
  from ...helper.cliargs import CommandLineArguments
6
7
  from ...helper.logger import Logger
7
8
 
9
+ available_implementations = "gitlab"
10
+
11
+ ########################################
12
+ # Interface
13
+ ########################################
14
+ class SourceModifier(ABC):
15
+ @abstractmethod
16
+ def apply(self, suite_dict, prefix):
17
+ pass
18
+
19
+ ########################################
20
+ # Factory
21
+ ########################################
22
+ class SourceModifierFactory:
23
+ @staticmethod
24
+ def get_modifier(prefix_type: str) -> SourceModifier:
25
+ if prefix_type.lower() == "gitlab":
26
+ return GitLabModifier()
27
+ # EXAMPLE Extension:
28
+ # elif prefix_type.lower() == "github":
29
+ # return GitHubModifier()
30
+ raise ValueError(
31
+ f"No source modifier found for type '{prefix_type}' - actually available implementation are:\n{available_implementations}"
32
+ )
33
+
34
+ ########################################
35
+ # Prefix Modifier - Implementation
36
+ ########################################
8
37
  class SourcePrefixModifier():
9
38
 
10
39
  GITLAB_CONNECTOR = "-/blob/main/"
11
40
 
12
41
  def __init__(self):
13
42
  self.args = CommandLineArguments().data
14
-
15
- def _modify(self, suite: TestSuite, prefix: str):
16
- prefix_type, prefix = self._prefix_validation(prefix)
17
- if "gitlab" in prefix_type:
18
- SourcePrefixGitLab()._apply_gitlab_source_to_suite(suite, prefix)
19
- else:
20
- raise ValueError(f"No matching source-prefix modifier found for: {prefix_type} with prefix: {prefix}")
21
43
 
22
44
  def _prefix_validation(self, prefix: str) -> list:
23
45
  if "::" not in prefix:
@@ -27,11 +49,16 @@ class SourcePrefixModifier():
27
49
 
28
50
  def modify_source_prefix(self, suite_object: TestSuite) -> TestSuite:
29
51
  Logger().LogKeyValue("Using Prefix for Source: ", self.args.sourceprefix, "yellow") if self.args.verbose_mode else None
52
+ prefix_type, prefix = self._prefix_validation(self.args.sourceprefix)
53
+ modifier = SourceModifierFactory.get_modifier(prefix_type)
30
54
  for suite in suite_object:
31
- self._modify(suite, self.args.sourceprefix)
55
+ modifier.apply(suite, prefix)
32
56
  return suite_object
33
57
 
34
- class SourcePrefixGitLab():
58
+ ########################################
59
+ # Low-Level Implementation for GitLab
60
+ ########################################
61
+ class GitLabModifier():
35
62
  """
36
63
  Source Prefix Modifier for "GitLab" Projects.
37
64
  Expected CMD Line Arg: "gitlab::prefix"
@@ -62,7 +89,7 @@ class SourcePrefixGitLab():
62
89
  rel_path = os.path.relpath(file_path, git_root).replace(os.sep, "/")
63
90
  return prefix.rstrip("/") + "/-/blob/" + git_branch + "/" + rel_path
64
91
 
65
- def _apply_gitlab_source_to_suite(self, suite_dict, prefix):
92
+ def apply(self, suite_dict, prefix):
66
93
  try:
67
94
  suite_dict["source"] = self._convert_to_gitlab_url(suite_dict["source"], prefix)
68
95
  except:
@@ -75,4 +102,9 @@ class SourcePrefixGitLab():
75
102
  test["source"] = "GitLink error"
76
103
 
77
104
  for sub_suite in suite_dict.get("sub_suites", []):
78
- self._apply_gitlab_source_to_suite(sub_suite, prefix)
105
+ self.apply(sub_suite, prefix)
106
+
107
+ ########################################
108
+ # Low-Level Implementation for ...
109
+ # [FUTURE EXTENSIONS LIKE GITHUB]
110
+ ########################################
@@ -18,9 +18,6 @@ class SuiteFileModifier():
18
18
  self.suite = suite_object
19
19
 
20
20
  # Modify generic params / hide some params
21
- self._modify_root_suite_name()
22
- self._modify_root_suite_doc()
23
- self._modify_root_suite_metadata()
24
21
  self._modify_tags()
25
22
  self._modify_test_doc()
26
23
  self._modify_suite_doc()
@@ -29,29 +26,16 @@ class SuiteFileModifier():
29
26
  return self.suite
30
27
 
31
28
  #############################################################################################################################
32
-
33
- def _modify_root_suite_name(self):
34
- if not self.args.name:
35
- return
36
- Logger().LogKeyValue("Modified Name of Root Suite: ", self.args.name, "yellow") if self.args.verbose_mode else None
37
- self.suite[0]["name"] = self.args.name
38
-
39
- #############################################################################################################################
40
-
41
- def _modify_root_suite_doc(self):
42
- if not self.args.doc:
43
- return
44
- Logger().LogKeyValue("Modified Doc of Root Suite: ", self.args.name, "yellow") if self.args.verbose_mode else None
45
- self.suite[0]["doc"] = self.args.doc
46
-
47
- #############################################################################################################################
48
-
49
- def _modify_root_suite_metadata(self):
50
- if not self.args.metadata:
51
- return
52
- Logger().LogKeyValue("Modified Metadata of Root Suite: ", self.args.metadata, "yellow") if self.args.verbose_mode else None
53
- formatted_metadata = "<br>".join([f"{k}: {v}" for k, v in self.args.metadata.items()])
54
- self.suite[0]["metadata"] = formatted_metadata
29
+
30
+ # Modify name, doc & metadata via officially provided robot api
31
+ def _modify_root_suite_details(self, suite: TestSuite):
32
+ if self.args.name:
33
+ suite.configure(name=self.args.name)
34
+ if self.args.doc:
35
+ suite.configure(doc=self.args.doc)
36
+ if self.args.metadata:
37
+ suite.configure(metadata=self.args.metadata)
38
+ return suite
55
39
 
56
40
  #############################################################################################################################
57
41
 
@@ -23,6 +23,7 @@ class TestCaseParser():
23
23
  suite_info["tests"].append(test_info)
24
24
  return suite_info
25
25
 
26
+ # Consider tags via officially provided robot api
26
27
  def consider_tags(self, suite: TestSuite) -> TestSuite:
27
28
  if len(self.args.include) > 0:
28
29
  suite.configure(include_tags=self.args.include)
@@ -2,6 +2,7 @@ import os
2
2
 
3
3
  from robot.api import SuiteVisitor, TestSuite
4
4
  from .testcaseparser import TestCaseParser
5
+ from .modifier.suitefilemodifier import SuiteFileModifier
5
6
 
6
7
  class RobotSuiteParser(SuiteVisitor):
7
8
  def __init__(self):
@@ -23,7 +24,7 @@ class RobotSuiteParser(SuiteVisitor):
23
24
  "total_tests": 0,
24
25
  "tests": [],
25
26
  "sub_suites": [],
26
- "metadata": None
27
+ "metadata": "<br>".join([f"{k}: {v}" for k, v in suite.metadata.items()]) if suite.metadata else None
27
28
  }
28
29
 
29
30
  # Parse Test Cases
@@ -39,6 +40,7 @@ class RobotSuiteParser(SuiteVisitor):
39
40
  def parse_suite(self, suite_path):
40
41
  suite = TestSuite.from_file_system(suite_path)
41
42
  suite = TestCaseParser().consider_tags(suite)
43
+ suite = SuiteFileModifier()._modify_root_suite_details(suite)
42
44
  suite.visit(self)
43
45
  return self.suites
44
46
 
@@ -65,4 +67,4 @@ class RobotSuiteParser(SuiteVisitor):
65
67
  def _already_parsed(self, suite):
66
68
  existing_suite = next((s for s in self.suites if s["name"] == suite.name), None)
67
69
  if existing_suite:
68
- return
70
+ return
@@ -1,24 +0,0 @@
1
- robotframework_testdoc-0.1.4.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
2
- testdoc/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
- testdoc/__main__.py,sha256=FXuSYwSHojtkWAz8l6xeETxklc3cVdUBqo1GiBGt2Rg,66
4
- testdoc/cli.py,sha256=VOpy3jPHQVNgwGBQgQmXcgYAeQRsjhgrnzOsJKwSsyM,4441
5
- testdoc/testdoc.py,sha256=cVJguXoFhkCM2nkUlZGB8m-6rBhKwthFFtdtz0T2l4Q,772
6
- testdoc/helper/cliargs.py,sha256=PYz6hcKTo-MLzmXWum4foszuHhYrMubAG7nP9xKZ5b8,1263
7
- testdoc/helper/datetimeconverter.py,sha256=1IuJ_rZlKKut3pallS9WSdlQ00YNQX2Nhf2oYWt7QDc,159
8
- testdoc/helper/logger.py,sha256=STPEEdMIGpK004xHDskj8zzW3knBWP05GllYajQMaSY,272
9
- testdoc/helper/pathconverter.py,sha256=Il4SX8EdpKPjOiZt97zC4TBLxp2tKUhfyyS2J1qWpyg,1656
10
- testdoc/html/images/robotframework.svg,sha256=w1yNL6XtuHOCCwzjGX3pZQG7ZcJghzllvc7cQ9MKKbQ,1426
11
- testdoc/html/templates/jinja_template_01.html,sha256=gw2hEx2P7zLsQP5-4fA2hErWJuhkUTZkEakXxRzWKtU,18213
12
- testdoc/html/themes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- testdoc/html/themes/theme_config.py,sha256=UHqNlkff5Q_68uRAsCIODflxJxmLSyH8LMbdJXkHSdw,849
14
- testdoc/html/themes/themes.py,sha256=6xlHW7O-XO9Z1B33_aRwzffkuWR65jM7CYXsZWUjdmY,1091
15
- testdoc/html_rendering/render.py,sha256=BzPGyePwjCFZAXRHDF-ccM2xRKY-6Cnym1-uDb9i1AQ,1083
16
- testdoc/parser/testcaseparser.py,sha256=4EyUFOuo6AtobKN7jveWAXTTs-KlvhzqXQuXnseTGj0,1189
17
- testdoc/parser/testsuiteparser.py,sha256=F4zWTw4_ccipoOnRHl3LDLn6qPO-AhkSx7cZ7DLKC8U,2381
18
- testdoc/parser/modifier/sourceprefixmodifier.py,sha256=UUZ0Gp5hZIYv4dvZV6XUOE5UkIFONLFj_mZczC40mzI,3013
19
- testdoc/parser/modifier/suitefilemodifier.py,sha256=VA-4rAniQugXefWfXSaZoDzOafqXTqGDKLk2BZd6_hE,5785
20
- robotframework_testdoc-0.1.4.dist-info/METADATA,sha256=cVFYyfYBlVnay7lJ-pb89HgGsWyp_L4oF5s5hZG-TTM,4577
21
- robotframework_testdoc-0.1.4.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
22
- robotframework_testdoc-0.1.4.dist-info/entry_points.txt,sha256=BUHy23mdlGCqYOWpsvRhSb1c0tPMzIwyTwr-sHI6xUs,45
23
- robotframework_testdoc-0.1.4.dist-info/top_level.txt,sha256=p1axpYooAmdwwXQOzFsSXF3u_-88QFKCDxPf67siv3Y,8
24
- robotframework_testdoc-0.1.4.dist-info/RECORD,,