Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ output_doc.html
output.html
src/testdoc/html/templates/jinja_template_02.html
image.png
output_doc_robot.html
devel.html
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,37 @@ For using this config file, just call the following command:
testdoc -c path/to/config.toml tests/ TestDocumentation.html
```

## HTML Template Selection

You can choose between multiple HTML template for the design of your test documentation.
These template can be configured via ``cli arguments`` or within a ``.toml configuration file`` with the parameter ``html_template (-ht / --html-template)``.

### Default Design

- v2

### Available HTML Templates

You can choose one of the following designs:
- v1
- v2

### Version 1

#### Visit Tests

![alt text](docs/html_v1_common.png)

### Version 2

#### Visit Tests on Root Suite Level

![alt text](docs/html_v2_root.png)

#### Visit Tests on Suite File Level

![alt text](docs/html_v2_suitefile.png)

## Theme Selection / Color Configuration

You can select between several themes (color configurations) for your HTML document to create!
Expand Down
Binary file added docs/html_v1_common.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/html_v2_root.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/html_v2_suitefile.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 14 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ build-backend = "setuptools.build_meta"

[project]
name = "robotframework-testdoc"
version = "0.1.8"
version = "0.2.0"
description = "A CLI Tool to generate a Test Documentation for your RobotFramework Test Scripts."
readme = "README.md"
requires-python = ">=3.7"
authors = [{ name = "Marvin Klerx", email = "[email protected]" }]
authors = [
{ name = "Marvin Klerx", email = "[email protected]" }
]
license = { text = "MIT" }

dependencies = [
Expand All @@ -21,6 +23,16 @@ dependencies = [
[project.scripts]
testdoc = "testdoc.cli:main"

[tool.setuptools]
include-package-data = true

[tool.setuptools.package-data]
"testdoc" = [
"html/images/*.svg",
"html/templates/**/*.html",
"default.toml"
]

[tool.ruff]
line-length = 150
lint.select = ["E", "F"] # Pyflakes & pycodestyle
Expand Down
7 changes: 6 additions & 1 deletion src/testdoc/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
from .testdoc import TestDoc
from .helper.cliargs import CommandLineArguments

@click.command()
CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help'])
@click.command(context_settings=CONTEXT_SETTINGS)
@click.option("-t","--title", required=False, help="Modify the title of the test documentation page")
@click.option("-n","--name", required=False, help="Modify the name of the root suite element")
@click.option("-d","--doc", required=False, help="Modify the documentation of the root suite element")
Expand All @@ -20,8 +21,10 @@
@click.option("--hide-source", is_flag=True, required=False, help="If given, test suite/ test case source is hidden")
@click.option("--hide-keywords", is_flag=True, required=False, help="If given, keyword calls in test cases are hidden")
@click.option("-S", "--style", required=False, help="Choose a predefined default style theme - 'default', 'robot', 'dark' or 'blue' ")
@click.option("-ht","--html-template", required=False, help="Select the HTML template - possible values: 'v1', 'v2'")
@click.option("-c", "--configfile", required=False, help="Optional .toml configuration file (includes all cmd-args)")
@click.option("-v", "--verbose", is_flag=True, required=False, help="More precise debugging into shell")
@click.version_option(package_name='robotframework-testdoc')
@click.argument("PATH")
@click.argument("OUTPUT")
def main(
Expand All @@ -38,6 +41,7 @@ def main(
hide_source,
hide_keywords,
style,
html_template,
configfile,
verbose,
path,
Expand Down Expand Up @@ -81,6 +85,7 @@ def main(
"hide_keywords": hide_keywords or None,
"verbose_mode": verbose or None,
"style": style or None,
"html_template": html_template or None,
"config_file": configfile or None,
}
args.suite_file = path
Expand Down
7 changes: 3 additions & 4 deletions src/testdoc/helper/cliargs.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from dataclasses import dataclass, field
from typing import Any, List
import tomli
from .toml_reader import TOMLReader
import os

@dataclass
Expand All @@ -21,6 +21,7 @@ class CommandLineArgumentsData:
verbose_mode: bool = False
suite_file: str = None
style: str = None
html_template: str = "v2"
output_file: str = None
colors: dict = None

Expand All @@ -37,9 +38,7 @@ def __new__(cls):
### Load configuration file
###
def load_from_config_file(self, file_path: str):
with open(file_path, "rb") as f:
config = tomli.load(f)

config = TOMLReader()._read_toml(file_path)
_is_pyproject = self._is_pyproject_config(file_path)
if _is_pyproject:
self._handle_pyproject_config(config)
Expand Down
11 changes: 11 additions & 0 deletions src/testdoc/helper/toml_reader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import tomli

class TOMLReader():

def _read_toml(self, file_path:str):
try:
with open(file_path, "rb") as f:
config = tomli.load(f)
return config
except Exception as e:
raise ImportError(f"Cannot read toml file in: {file_path} with error: \n{e}")
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ <h2 class="accordion-header" id="headingTest{{ index }}-{{ loop.index }}">
<tr>
<td style="width: 10%; font-weight: bold;">🏷 Tags:</td>
<td style="text-align: left;">
{% if test.tags %}
{% if test.tags and test.tags is string %}
{{ test.tags }}
{% else %}
{{ test.tags | join(', ') }}
{% endif %}
</td>
Expand All @@ -132,7 +134,7 @@ <h2 class="accordion-header" id="headingTest{{ index }}-{{ loop.index }}">
<td style="width: 10%; font-weight: bold; vertical-align: top;">🔑 Keywords:</td>
<td style="text-align: left;">
{% if test.keywords %}
- {{ test.keywords | join('<br>- ') }}
<pre>- {{ test.keywords | join('\n- ') }}</pre>
{% endif %}
</td>
</tr>
Expand Down
116 changes: 116 additions & 0 deletions src/testdoc/html/templates/v1/jinja_template_02.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Robot Framework - Test Documentation</title>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<style>
html, body, .container-fluid {
background-color: {{ colors.background }};
color: {{ colors.text_color }};
font-size: 14px;
}
a {
color: {{ colors.text_color }};
}
a:hover {
color: {{ colors.robot_icon }};
}
.sidebar {
min-width: 250px;
max-width: 250px;
background-color: {{ colors.inner_color }};
border-right: 1px solid {{ colors.border_color }};
height: 100vh;
overflow-y: auto;
}
.content {
padding: 20px;
flex-grow: 1;
}
.suite-item {
padding: 8px 16px;
cursor: pointer;
}
.suite-item:hover {
background-color: {{ colors.button_hover_color }};
}
.accordion-item, .accordion-body {
background-color: {{ colors.inner_color }};
border-color: {{ colors.border_color }};
color: {{ colors.text_color }};
}
.accordion-button {
background-color: {{ colors.inner_color }};
color: {{ colors.text_color }};
}
.accordion-button:hover {
background-color: {{ colors.button_hover_color }} !important;
}
.accordion-button:not(.collapsed),
.accordion-button:focus,
.accordion-button:active {
background-color: {{ colors.button_active_color }} !important;
box-shadow: none !important;
color: {{ colors.text_color }};
}
.generated_at {
color: {{ colors.title_color }};
}
</style>
</head>
<body class="d-flex flex-column min-vh-100">
<div class="d-flex flex-grow-1">
<div class="sidebar">
<h5 class="text-center mt-3">📁 Suites</h5>
<ul class="list-unstyled">
{% for suite in suites %}
<li class="suite-item" onclick="showSuite('{{ loop.index0 }}')">{{ suite.name }}</li>
{% endfor %}
</ul>
</div>
<div class="content">
{% for suite in suites %}
<div id="suite-{{ loop.index0 }}" class="suite-view" style="display: {% if loop.first %}block{% else %}none{% endif %};">
<h4>{{ suite.name }}</h4>
{% if suite.doc %}<p><strong>📝 Docs:</strong> {{ suite.doc }}</p>{% endif %}
{% if suite.source %}<p><strong>🔗 Source:</strong> <a href="{{ suite.source }}" target="_blank">{{ suite.source }}</a></p>{% endif %}
<p><strong>📊 Number of Tests:</strong> {{ suite.num_tests }}</p>

{% for test in suite.tests %}
<div class="accordion mb-3">
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#test-{{ loop.index0 }}-{{ loop.index }}">
🔍 {{ test.name }}
</button>
</h2>
<div id="test-{{ loop.index0 }}-{{ loop.index }}" class="accordion-collapse collapse">
<div class="accordion-body">
{% if test.doc %}<p><strong>📝 Docs:</strong><br>{{ test.doc }}</p>{% endif %}
{% if test.source %}<p><strong>🔗 Source:</strong> <a href="{{ test.source }}" target="_blank">{{ test.source }}</a></p>{% endif %}
{% if test.tags %}<p><strong>🏷 Tags:</strong> {{ test.tags | join(', ') }}</p>{% endif %}
{% if test.keywords %}<p><strong>🔑 Keywords:</strong><br>- {{ test.keywords | join('<br>- ') }}</p>{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
</div>
<p class="text-center generated_at py-1 border-top">
Generated at: {{ generated_at }}<br>robotframework-testdoc by Marvin Klerx
</p>
<script>
function showSuite(index) {
const views = document.querySelectorAll('.suite-view');
views.forEach(view => view.style.display = 'none');
document.getElementById('suite-' + index).style.display = 'block';
}
</script>
</body>
</html>
Loading