testbench2robotframework 2.0.0__tar.gz → 2.1.0rc1__tar.gz
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.
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/.gitignore +0 -1
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/PKG-INFO +6 -4
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/README.md +3 -3
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/configuration/overview.md +115 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/usage/fetch_results.md +39 -2
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/usage/generate_tests.md +35 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/pyproject.toml +6 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/__init__.py +1 -1
- testbench2robotframework-2.1.0rc1/testbench2robotframework/attachments.py +66 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/cli.py +20 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/config.py +10 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/execution_artifacts.py +10 -2
- testbench2robotframework-2.1.0rc1/testbench2robotframework/json_codec.py +55 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/json_reader.py +2 -4
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/json_writer.py +6 -25
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/model_utils.py +14 -2
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/result_writer.py +89 -24
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/robotframework2testbench.py +4 -2
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/testbench2rf.py +130 -7
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/testbench2robotframework.py +7 -29
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/testsuite_write.py +26 -14
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/utils.py +68 -22
- testbench2robotframework-2.1.0rc1/tests/test_attachment_parameters.py +159 -0
- testbench2robotframework-2.1.0rc1/tests/test_attachments_export.py +247 -0
- testbench2robotframework-2.1.0rc1/tests/test_blocked_filter.py +177 -0
- testbench2robotframework-2.1.0rc1/tests/test_clean.py +122 -0
- testbench2robotframework-2.1.0rc1/tests/test_config_optional_options.py +96 -0
- testbench2robotframework-2.1.0rc1/tests/test_execution_artifacts.py +96 -0
- testbench2robotframework-2.1.0rc1/tests/test_fetch_results_output.py +160 -0
- testbench2robotframework-2.1.0rc1/tests/test_json_codec.py +29 -0
- testbench2robotframework-2.1.0rc1/tests/test_json_writer_tree_order.py +96 -0
- testbench2robotframework-2.1.0rc1/tests/test_keyword_comment.py +207 -0
- testbench2robotframework-2.1.0rc1/tests/test_main_protocol_reader.py +51 -0
- testbench2robotframework-2.1.0rc1/tests/test_open_report.py +67 -0
- testbench2robotframework-2.1.0rc1/tests/test_protocol_merge.py +196 -0
- testbench2robotframework-2.1.0rc1/tests/test_protocol_references.py +109 -0
- testbench2robotframework-2.1.0rc1/tests/test_protocol_rows.py +136 -0
- testbench2robotframework-2.1.0rc1/tests/test_report_creator_tester.py +234 -0
- testbench2robotframework-2.1.0rc1/tests/test_subdivision_patterns.py +284 -0
- testbench2robotframework-2.1.0rc1/tests/test_tree_verdicts.py +172 -0
- testbench2robotframework-2.0.0/README_old.md +0 -284
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/.github/dependabot.yml +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/.github/workflows/release-binaries.yml +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/.github/workflows/trigger-docs-release.yml +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/DEVELOPMENT.md +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/ExampleConfiguration/json_config.json +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/ExampleConfiguration/pyproject_example.toml +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/ExampleConfiguration/toml_config.toml +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/LICENSE +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/MANIFEST.in +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/atest/json_config_tests/1_tfs.robot +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/atest/robot/libs/json_config.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/atest/robot/libs/pyproject_config.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/atest/robot/resources/file_management.resource +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/atest/robot/resources/testbench2robotframework_cli.resource +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/atest/robot/rf_tests/cli_interface/write/json_config.robot +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/atest/robot/rf_tests/cli_interface/write/no_config_argument.robot +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/atest/robot/rf_tests/cli_interface/write/toml_config.robot +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/create_json_schema.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/configuration/_category_.json +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/configuration/cli_options.md +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/configuration/pyproject_config.md +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/getting_started/_category_.json +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/getting_started/installation.md +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/getting_started/quick_start.md +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/intro.md +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/func_kw.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/itorx-exec-overview.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/itorx-exec.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/robot-setup-teardown.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/robot-suite-code.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/robot-suite-log.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/tc-table.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/tcs-browser.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/tcs-exec-comment.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/tcs-exec-in-TB.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/tcs-sequence.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/media/te-tree.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/usage/_category_.json +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/LibrarySubdivision.PNG +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/Unbenannt.PNG +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/generated.png +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/libraries.PNG +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/resources.PNG +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/rfLibraryRootsTestBench.PNG +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/testbench_rfLibraryRegex.PNG +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/testbench_rfResourceRegex.PNG +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/images/testthemen.PNG +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/pyinstaller/imbusTB.ico +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/pyinstaller/run.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/requirements.txt +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/robot.toml +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/tasks.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench-tools.zip +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/__main__.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/blocked_filter.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/execution_comment.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/html_parser.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/keyword_comment.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/log.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/model.py +0 -0
- {testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/protocol_merge.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: testbench2robotframework
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.1.0rc1
|
|
4
4
|
Summary: Robot Framework Code Generator from Keyword-Driven Tests in imbus TestBench 3.0 and newer
|
|
5
5
|
Author-email: imbus AG <support@imbus.de>
|
|
6
6
|
Requires-Python: >= 3.10
|
|
@@ -22,8 +22,10 @@ Requires-Dist: robotframework-tidy ; extra == "dev"
|
|
|
22
22
|
Requires-Dist: datamodel-code-generator ; extra == "dev"
|
|
23
23
|
Requires-Dist: ruff ; extra == "dev"
|
|
24
24
|
Requires-Dist: twine ; extra == "dev"
|
|
25
|
+
Requires-Dist: orjson ; extra == "fast"
|
|
25
26
|
Project-URL: Repository, https://github.com/imbus/testbench2robotframework
|
|
26
27
|
Provides-Extra: dev
|
|
28
|
+
Provides-Extra: fast
|
|
27
29
|
|
|
28
30
|
# TestBench2RobotFramework
|
|
29
31
|
|
|
@@ -33,14 +35,14 @@ This can be used for automated test execution with Robot Framework, triggered by
|
|
|
33
35
|
|
|
34
36
|
## Documentation
|
|
35
37
|
|
|
36
|
-
The documentation is available in the [
|
|
38
|
+
The documentation is available in the [TestBench Ecosystem Documentation](https://imbus.github.io/testbench-ecosystem-documentation/testbench2robotframework/intro).
|
|
37
39
|
|
|
38
40
|
## Releases
|
|
39
41
|
|
|
40
|
-
Releases are published on GitHub and available via [PyPI](https://pypi.org/project/testbench2robotframework/).
|
|
42
|
+
Releases are published on [GitHub](https://github.com/imbus/testbench2robotframework/releases) and available via [PyPI](https://pypi.org/project/testbench2robotframework/).
|
|
41
43
|
|
|
42
44
|
## Requirements
|
|
43
45
|
|
|
44
46
|
- Python 3.10 or higher
|
|
45
|
-
- TestBench version >= 4
|
|
47
|
+
- TestBench version >= 4.1
|
|
46
48
|
|
|
@@ -6,13 +6,13 @@ This can be used for automated test execution with Robot Framework, triggered by
|
|
|
6
6
|
|
|
7
7
|
## Documentation
|
|
8
8
|
|
|
9
|
-
The documentation is available in the [
|
|
9
|
+
The documentation is available in the [TestBench Ecosystem Documentation](https://imbus.github.io/testbench-ecosystem-documentation/testbench2robotframework/intro).
|
|
10
10
|
|
|
11
11
|
## Releases
|
|
12
12
|
|
|
13
|
-
Releases are published on GitHub and available via [PyPI](https://pypi.org/project/testbench2robotframework/).
|
|
13
|
+
Releases are published on [GitHub](https://github.com/imbus/testbench2robotframework/releases) and available via [PyPI](https://pypi.org/project/testbench2robotframework/).
|
|
14
14
|
|
|
15
15
|
## Requirements
|
|
16
16
|
|
|
17
17
|
- Python 3.10 or higher
|
|
18
|
-
- TestBench version >= 4
|
|
18
|
+
- TestBench version >= 4.1
|
{testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/configuration/overview.md
RENAMED
|
@@ -85,7 +85,11 @@ file. This is noted per option below.
|
|
|
85
85
|
| [`resource-mapping`](#library-mapping--resource-mapping) | `--resource-mapping` | ✅ | G | mapping (`{}`) |
|
|
86
86
|
| [`forced-import`](#forced-import) | — | ✅ | G | table of lists (`{}`) |
|
|
87
87
|
| [`metadata`](#metadata) | `--metadata` | ✅ | G | mapping (`{}`) |
|
|
88
|
+
| [`attachments-directory`](#attachments-directory) | `--attachments-directory` | ✅ | G | path (empty) |
|
|
89
|
+
| [`attachments-variable`](#attachments-variable) | — | ✅ | G | variable name (`ITB_ATTACHMENTS_DIR`) |
|
|
90
|
+
| [`keep-extracted-report`](#keep-extracted-report) | — | ✅ | G · F | bool (`false`) |
|
|
88
91
|
| [`merge-protocol`](#merge-protocol) | `--no-merge-protocol` | ✅ | F | bool (`true`) |
|
|
92
|
+
| [`set-tester-from-report-creator`](#set-tester-from-report-creator) | `--set-tester-from-report-creator` | ✅ | F | bool (`false`) |
|
|
89
93
|
| [`keyword-comment-style`](#keyword-comment-style) | — | ✅ | F | `STRUCTURED` \| `FLAT` (`STRUCTURED`) |
|
|
90
94
|
| [`keyword-comment-max-depth`](#keyword-comment-max-depth) | — | ✅ | F | int (`5`) |
|
|
91
95
|
| [`keyword-comment-max-rows`](#keyword-comment-max-rows) | — | ✅ | F | int, `0` = no limit (`300`) |
|
|
@@ -117,6 +121,94 @@ testbench2robotframework generate-tests -d ./suites.zip my_report.zip
|
|
|
117
121
|
output-directory = "{root}/Generated"
|
|
118
122
|
```
|
|
119
123
|
|
|
124
|
+
#### `output-directory` with `fetch-results`
|
|
125
|
+
|
|
126
|
+
For `fetch-results` the option names the updated report. The input report is only
|
|
127
|
+
read when `-d` is given; **without `-d` the input report itself is updated** and
|
|
128
|
+
the original, unexecuted report is gone afterwards.
|
|
129
|
+
|
|
130
|
+
| Input report | `-d` | Result |
|
|
131
|
+
|---|---|---|
|
|
132
|
+
| `report.zip` | `result.zip` | `result.zip` is created; `report.zip` is unchanged. |
|
|
133
|
+
| `report.zip` | `result/` | `result/` is created (or merged into) as a directory; `report.zip` is unchanged. |
|
|
134
|
+
| `report/` | `result.zip` | `result.zip` is created; `report/` is unchanged. |
|
|
135
|
+
| `report/` | `result/` | `result/` is created (or merged into); `report/` is unchanged. |
|
|
136
|
+
| `report.zip` | *none* | `report.zip` is **overwritten** with the updated report. |
|
|
137
|
+
| `report/` | *none* | The files in `report/` are **updated in place**; no ZIP is created. |
|
|
138
|
+
|
|
139
|
+
Keep the original report if you need it for a second run — for example to merge
|
|
140
|
+
another execution with [`merge-protocol`](#merge-protocol) — or always pass `-d`.
|
|
141
|
+
|
|
142
|
+
### `keep-extracted-report`
|
|
143
|
+
|
|
144
|
+
Where a `.zip` report is extracted to while a command reads it. By default that is
|
|
145
|
+
a temporary directory in the working directory, removed when the command is done.
|
|
146
|
+
With `true` the report is extracted to a directory of the same name next to the
|
|
147
|
+
ZIP (`report.zip` → `report/`), replacing that directory if it exists, and left
|
|
148
|
+
there afterwards — for example to look at the report's attachments. Has no effect
|
|
149
|
+
when the report is given as a directory. **Configuration file only.**
|
|
150
|
+
|
|
151
|
+
- **Values:** `true` / `false`. Default: `false`.
|
|
152
|
+
|
|
153
|
+
```toml
|
|
154
|
+
keep-extracted-report = true
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
:::note
|
|
158
|
+
Up to version 2.0 `fetch-results` always left the extracted report next to the
|
|
159
|
+
ZIP. Set `keep-extracted-report = true` to keep that behaviour.
|
|
160
|
+
:::
|
|
161
|
+
|
|
162
|
+
### `attachments-directory`
|
|
163
|
+
|
|
164
|
+
Where `generate-tests` copies the report's `attachments/` folder to — every
|
|
165
|
+
attachment: representatives of reference data types (`representatives/DT-<key>/`),
|
|
166
|
+
files attached to test case sets and test cases, and whatever else is in there.
|
|
167
|
+
Empty (the default) exports nothing. The target is emptied before copying.
|
|
168
|
+
|
|
169
|
+
- **Values:** a path, empty, or a path starting with `{root}`. Default: empty.
|
|
170
|
+
- **CLI:** `--attachments-directory`.
|
|
171
|
+
|
|
172
|
+
How the path is given decides how the generated suites refer to it:
|
|
173
|
+
|
|
174
|
+
| Value | Copied to | Value of the [attachments variable](#attachments-variable) in every suite |
|
|
175
|
+
|---|---|---|
|
|
176
|
+
| relative, e.g. `attachments` | `<output-directory>/attachments` | `${CURDIR}/../attachments` — relative to the suite (`..` per directory level), so the output directory can be moved as a whole |
|
|
177
|
+
| absolute, e.g. `/data/run1/attachments` | exactly there | `/data/run1/attachments` |
|
|
178
|
+
| `{root}/…` | the absolute path it resolves to | that absolute path |
|
|
179
|
+
|
|
180
|
+
With a `.zip` `output-directory`, a relative attachments directory ends up inside
|
|
181
|
+
the archive.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
testbench2robotframework generate-tests --attachments-directory attachments my_report.zip
|
|
185
|
+
robot ./Generated # finds the attachments by itself
|
|
186
|
+
```
|
|
187
|
+
```toml
|
|
188
|
+
attachments-directory = "attachments"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### `attachments-variable`
|
|
192
|
+
|
|
193
|
+
The Robot Framework variable through which generated keyword calls address
|
|
194
|
+
attachments, for example
|
|
195
|
+
`${ITB_ATTACHMENTS_DIR}/representatives/DT-6917529030000126275/Vorlage.xml`.
|
|
196
|
+
When [`attachments-directory`](#attachments-directory) is set, every suite whose
|
|
197
|
+
keyword calls refer to the variable gets a `*** Variables ***` section defining it
|
|
198
|
+
(see the table above) — suites without attachments and `__init__.robot` files stay
|
|
199
|
+
as they are. A `--variable` on the `robot` command line still overrides that
|
|
200
|
+
default. Without `attachments-directory` no section is written and the variable
|
|
201
|
+
has to be passed to `robot`. **Configuration file only.**
|
|
202
|
+
|
|
203
|
+
- **Values:** a variable name without `${}`, or empty. Default: `ITB_ATTACHMENTS_DIR`.
|
|
204
|
+
- **Empty:** attachments are written as paths relative to the report's
|
|
205
|
+
`attachments` folder (`representatives/DT-…/Vorlage.xml`) and no section is
|
|
206
|
+
generated — for runs started from inside that folder.
|
|
207
|
+
|
|
208
|
+
```toml
|
|
209
|
+
attachments-variable = "ITB_ATTACHMENTS_DIR"
|
|
210
|
+
```
|
|
211
|
+
|
|
120
212
|
### `create-output-zip`
|
|
121
213
|
|
|
122
214
|
For `generate-tests` only: in addition to the normal directory output, also
|
|
@@ -444,6 +536,29 @@ testbench2robotframework fetch-results --no-merge-protocol output.xml my_report.
|
|
|
444
536
|
merge-protocol = true
|
|
445
537
|
```
|
|
446
538
|
|
|
539
|
+
### `set-tester-from-report-creator`
|
|
540
|
+
|
|
541
|
+
Sets the user who created the TestBench report as **tester** of the test cases the
|
|
542
|
+
current Robot run executed. The user is read from `reportCreation.creator` in the
|
|
543
|
+
report's `manifest.json`: its `userKey` becomes the `testerKey` of the test case in
|
|
544
|
+
`protocol.json`, and its `userKey` and `userName` become `exec.tester` in the test
|
|
545
|
+
case's JSON file. An existing tester is overwritten.
|
|
546
|
+
|
|
547
|
+
Only test cases with the verdict `Pass` or `Fail` get a tester. Skipped and not run
|
|
548
|
+
tests, and executions kept from the input protocol when merging, stay unchanged. If
|
|
549
|
+
`manifest.json` is missing or names no creator, a warning is logged and no tester is
|
|
550
|
+
set.
|
|
551
|
+
|
|
552
|
+
- **Values:** `true` / `false`. Default: `false`.
|
|
553
|
+
- **CLI:** `--set-tester-from-report-creator` (turns it on).
|
|
554
|
+
|
|
555
|
+
```bash
|
|
556
|
+
testbench2robotframework fetch-results --set-tester-from-report-creator output.xml my_report.zip
|
|
557
|
+
```
|
|
558
|
+
```toml
|
|
559
|
+
set-tester-from-report-creator = true
|
|
560
|
+
```
|
|
561
|
+
|
|
447
562
|
### `keyword-comment-style`
|
|
448
563
|
|
|
449
564
|
How the execution comment of a keyword is rendered. `STRUCTURED` shows the whole
|
{testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/usage/fetch_results.md
RENAMED
|
@@ -36,8 +36,10 @@ TestBench report the suites were generated from.
|
|
|
36
36
|
- **In:** the original TestBench report (the same directory or ZIP file the suites
|
|
37
37
|
were generated from) **and** the Robot Framework `output.xml` of the run.
|
|
38
38
|
- **Out:** an updated TestBench JSON report you can import back into TestBench.
|
|
39
|
-
With `-d` it is written to a new location
|
|
40
|
-
|
|
39
|
+
With `-d` it is written to a new location and the input report stays untouched;
|
|
40
|
+
**without `-d` the input report is overwritten**. All six input/output
|
|
41
|
+
combinations are listed under
|
|
42
|
+
[`output-directory` with `fetch-results`](../configuration/overview.md#output-directory-with-fetch-results).
|
|
41
43
|
|
|
42
44
|
<br />
|
|
43
45
|
**Img-1:** Robot Framework `log.html` of a test run
|
|
@@ -112,6 +114,13 @@ second run starts over. To combine several Robot runs, merge the output XMLs fir
|
|
|
112
114
|
(`rebot --merge output1.xml output2.xml`) and call `fetch-results` once.
|
|
113
115
|
:::
|
|
114
116
|
|
|
117
|
+
## Tester
|
|
118
|
+
|
|
119
|
+
The results do not name a tester by default. With
|
|
120
|
+
[`set-tester-from-report-creator` / `--set-tester-from-report-creator`](../configuration/overview.md#set-tester-from-report-creator)
|
|
121
|
+
the user who created the TestBench report becomes the tester of every test case the
|
|
122
|
+
run executed with the verdict `Pass` or `Fail`.
|
|
123
|
+
|
|
115
124
|
---
|
|
116
125
|
|
|
117
126
|
## Execution comments
|
|
@@ -146,6 +155,34 @@ is controlled by
|
|
|
146
155
|
decides what happens when an attachment of the same name already exists. Files
|
|
147
156
|
larger than 10 MB are skipped with an error message.
|
|
148
157
|
|
|
158
|
+
### The `itb-reference:` marker
|
|
159
|
+
|
|
160
|
+
A marker is the word `itb-reference:` followed by one value without whitespace.
|
|
161
|
+
The marker is removed from the message before it becomes the execution comment;
|
|
162
|
+
a message may carry several markers.
|
|
163
|
+
|
|
164
|
+
```robotframework
|
|
165
|
+
Set Test Message Screenshot taken.\n\nitb-reference: screenshot.png append=True
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The value is resolved like a URI reference:
|
|
169
|
+
|
|
170
|
+
| Value | Meaning |
|
|
171
|
+
|---|---|
|
|
172
|
+
| `screenshot.png`, `results/run.zip` | **Relative** to the directory of the `output.xml` — the Robot output directory. |
|
|
173
|
+
| `file:///var/log/run.zip`, `file:///C:/log/run.zip` | **Absolute** path. A `file:` URI is always absolute ([RFC 8089](https://www.rfc-editor.org/rfc/rfc8089)); `file:///run.zip` is the file `run.zip` in the file system root, *not* in the output directory. |
|
|
174
|
+
| `my%20file.png` | Percent-encoding is decoded. |
|
|
175
|
+
|
|
176
|
+
A relative value is the right choice for files Robot wrote into its output
|
|
177
|
+
directory, and the only form that resolves to the same file both here and in a
|
|
178
|
+
browser showing `log.html`. Use an absolute `file:` URI for files outside the
|
|
179
|
+
output directory. Both are looked up first as given (relative to the current
|
|
180
|
+
working directory), then relative to the `output.xml`.
|
|
181
|
+
|
|
182
|
+
A file that cannot be found is skipped with a warning; with
|
|
183
|
+
`reference-behaviour = "REFERENCE"` an absolute path is stored even if it does
|
|
184
|
+
not exist on the machine running `fetch-results`.
|
|
185
|
+
|
|
149
186
|
---
|
|
150
187
|
|
|
151
188
|
## The full round trip
|
{testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/docs/usage/generate_tests.md
RENAMED
|
@@ -260,3 +260,38 @@ Higher-level (compound) TestBench keywords can be rendered as a Robot Framework
|
|
|
260
260
|
Extra `Metadata` entries — including values pulled from the test case set model
|
|
261
261
|
via `{$tcs...}` placeholders — can be added to every suite with
|
|
262
262
|
[`metadata`](../configuration/overview.md#metadata).
|
|
263
|
+
|
|
264
|
+
### Use attachments as parameter values
|
|
265
|
+
|
|
266
|
+
A parameter whose representative is a file attached in TestBench arrives in the
|
|
267
|
+
generated keyword call as a path into the report's attachments:
|
|
268
|
+
|
|
269
|
+
```robotframework
|
|
270
|
+
${message} Get File ${ITB_ATTACHMENTS_DIR}/representatives/DT-6917529030000126275/file.xml
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
TestBench exports such files to `attachments/representatives/DT-<data type key>/`
|
|
274
|
+
inside the report. Two ways to make them available at execution time:
|
|
275
|
+
|
|
276
|
+
- Let `generate-tests` copy them next to the suites with
|
|
277
|
+
[`attachments-directory`](../configuration/overview.md#attachments-directory).
|
|
278
|
+
Every suite that uses attachments then defines `${ITB_ATTACHMENTS_DIR}`
|
|
279
|
+
relative to itself and the output directory runs as it is:
|
|
280
|
+
|
|
281
|
+
```bash
|
|
282
|
+
testbench2robotframework generate-tests --attachments-directory attachments my_report.zip
|
|
283
|
+
robot ./Generated
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
- Or keep the report where it is and point the variable to its `attachments`
|
|
287
|
+
directory when running:
|
|
288
|
+
|
|
289
|
+
```bash
|
|
290
|
+
robot --variable ITB_ATTACHMENTS_DIR:/path/to/my_report/attachments ./Generated
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
The variable's name is set by
|
|
294
|
+
[`attachments-variable`](../configuration/overview.md#attachments-variable).
|
|
295
|
+
Inside compound keywords the data type is taken from the outermost call the value
|
|
296
|
+
was passed down from. If no data type can be found, the file name is written as is
|
|
297
|
+
and a warning is logged.
|
|
@@ -24,6 +24,8 @@ dependencies = [
|
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
[project.optional-dependencies]
|
|
27
|
+
# Faster reading and writing of large reports; used automatically when installed.
|
|
28
|
+
fast = ["orjson"]
|
|
27
29
|
dev = [
|
|
28
30
|
"build",
|
|
29
31
|
"check-manifest",
|
|
@@ -112,6 +114,10 @@ exclude = [
|
|
|
112
114
|
[tool.pytest.ini_options]
|
|
113
115
|
minversion = "6.0"
|
|
114
116
|
addopts = "-ra --spec"
|
|
117
|
+
# Test classes end in 'Tests'. The default 'Test*' would also match the TestBench
|
|
118
|
+
# model classes (TestCaseSet, TestStructureTree, ...) imported into test modules
|
|
119
|
+
# and flood the run with PytestCollectionWarnings.
|
|
120
|
+
python_classes = "*Tests"
|
|
115
121
|
testpaths = [
|
|
116
122
|
"tests",
|
|
117
123
|
]
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Exporting the attachments of a TestBench report next to the generated suites.
|
|
2
|
+
|
|
3
|
+
The report keeps every attached file below 'attachments/': representatives of
|
|
4
|
+
reference data types under 'representatives/DT-<key>/', files of test case sets
|
|
5
|
+
and test cases directly in the folder, and whatever else a TestBench extension
|
|
6
|
+
put there. The whole folder is copied - the library does not know all consumers.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
import posixpath
|
|
12
|
+
import shutil
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
from pathlib import Path, PurePath
|
|
15
|
+
|
|
16
|
+
from .config import Configuration
|
|
17
|
+
from .log import logger
|
|
18
|
+
from .utils import get_generation_directory, resolve_root_placeholder
|
|
19
|
+
|
|
20
|
+
REPORT_ATTACHMENTS_DIR = "attachments"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class AttachmentsExport:
|
|
25
|
+
"""Where the attachments go, and how the suites refer to that place."""
|
|
26
|
+
|
|
27
|
+
target: Path
|
|
28
|
+
# Set when 'attachments-directory' is a relative path: the target lies inside the
|
|
29
|
+
# output directory and suites address it relative to themselves, so the whole
|
|
30
|
+
# output directory stays movable. None for an absolute target.
|
|
31
|
+
relative_to_output: PurePath | None
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def attachments_export(config: Configuration) -> AttachmentsExport | None:
|
|
35
|
+
if not config.attachments_directory:
|
|
36
|
+
return None
|
|
37
|
+
given = Path(resolve_root_placeholder(config.attachments_directory))
|
|
38
|
+
if given.is_absolute():
|
|
39
|
+
return AttachmentsExport(given, None)
|
|
40
|
+
output_directory = get_generation_directory(config.output_directory)
|
|
41
|
+
return AttachmentsExport(output_directory.with_suffix("") / given, PurePath(given))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def variable_value(export: AttachmentsExport, suite_directory: PurePath) -> str:
|
|
45
|
+
"""The value the attachments variable gets in a suite lying in 'suite_directory'.
|
|
46
|
+
|
|
47
|
+
'suite_directory' is relative to the output directory. Forward slashes
|
|
48
|
+
throughout; Robot Framework and Python accept them on every platform.
|
|
49
|
+
"""
|
|
50
|
+
if export.relative_to_output is None:
|
|
51
|
+
return export.target.as_posix()
|
|
52
|
+
relative = posixpath.relpath(export.relative_to_output.as_posix(), suite_directory.as_posix())
|
|
53
|
+
return f"${{CURDIR}}/{relative}"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def copy_attachments(report_directory: Path, target: Path) -> None:
|
|
57
|
+
"""Copies the report's attachments folder to 'target', replacing what is there."""
|
|
58
|
+
if target.exists():
|
|
59
|
+
shutil.rmtree(target)
|
|
60
|
+
source = report_directory / REPORT_ATTACHMENTS_DIR
|
|
61
|
+
if not source.is_dir():
|
|
62
|
+
logger.debug(f"The report has no '{REPORT_ATTACHMENTS_DIR}' folder.")
|
|
63
|
+
target.mkdir(parents=True)
|
|
64
|
+
return
|
|
65
|
+
shutil.copytree(source, target)
|
|
66
|
+
logger.info(f"Attachments copied to {target}.")
|
{testbench2robotframework-2.0.0 → testbench2robotframework-2.1.0rc1}/testbench2robotframework/cli.py
RENAMED
|
@@ -100,6 +100,13 @@ def testbench2robotframework_cli():
|
|
|
100
100
|
type=click.Path(path_type=Path),
|
|
101
101
|
help="Directory or ZIP archive containing the generated test suites.",
|
|
102
102
|
)
|
|
103
|
+
@click.option(
|
|
104
|
+
"--attachments-directory",
|
|
105
|
+
type=str,
|
|
106
|
+
help="""Copies the report's attachments there. A relative path lies inside the
|
|
107
|
+
output directory and the suites address it relative to themselves; an absolute
|
|
108
|
+
path is used as given. Without it, attachments are not exported.""",
|
|
109
|
+
)
|
|
103
110
|
@click.option(
|
|
104
111
|
"--compound-keyword-logging",
|
|
105
112
|
type=click.Choice(["GROUP", "COMMENT", "NONE"], case_sensitive=False),
|
|
@@ -173,6 +180,7 @@ def testbench2robotframework_cli():
|
|
|
173
180
|
)
|
|
174
181
|
@click.argument("testbench-report", type=click.Path(path_type=Path))
|
|
175
182
|
def generate_tests( # noqa: PLR0913
|
|
183
|
+
attachments_directory: str | None,
|
|
176
184
|
clean: bool | None,
|
|
177
185
|
compound_keyword_logging: str,
|
|
178
186
|
config: Path,
|
|
@@ -244,6 +252,9 @@ def generate_tests( # noqa: PLR0913
|
|
|
244
252
|
configuration["resource-root"] = list(resource_root) or configuration.get(
|
|
245
253
|
"resource-root", DEFAULT_RESOURCE_ROOTS
|
|
246
254
|
)
|
|
255
|
+
configuration["attachments-directory"] = attachments_directory or configuration.get(
|
|
256
|
+
"attachments-directory", ""
|
|
257
|
+
)
|
|
247
258
|
testbench2robotframework(testbench_report, configuration)
|
|
248
259
|
|
|
249
260
|
|
|
@@ -256,6 +267,12 @@ def generate_tests( # noqa: PLR0913
|
|
|
256
267
|
help="""Overwrite the main protocol instead of merging the Robot Framework results
|
|
257
268
|
into the protocol.json that is already part of the TestBench report.""",
|
|
258
269
|
)
|
|
270
|
+
@click.option(
|
|
271
|
+
"--set-tester-from-report-creator",
|
|
272
|
+
is_flag=True,
|
|
273
|
+
help="""Set the user who created the TestBench report (manifest.json) as tester of
|
|
274
|
+
every test case that this run executed with the verdict Pass or Fail.""",
|
|
275
|
+
)
|
|
259
276
|
@click.argument("robot-result", type=click.Path(path_type=Path))
|
|
260
277
|
@click.argument("testbench-report", type=click.Path(path_type=Path))
|
|
261
278
|
def fetch_results(
|
|
@@ -264,6 +281,7 @@ def fetch_results(
|
|
|
264
281
|
output_directory: Path,
|
|
265
282
|
testbench_report: Path,
|
|
266
283
|
no_merge_protocol: bool,
|
|
284
|
+
set_tester_from_report_creator: bool,
|
|
267
285
|
):
|
|
268
286
|
"""
|
|
269
287
|
Fetch Robot Framework execution results from <output XML> and save to a <TestBench Report>.
|
|
@@ -273,6 +291,8 @@ def fetch_results(
|
|
|
273
291
|
configuration["merge-protocol"] = False
|
|
274
292
|
else:
|
|
275
293
|
configuration["merge-protocol"] = configuration.get("merge-protocol", True)
|
|
294
|
+
if set_tester_from_report_creator:
|
|
295
|
+
configuration["set-tester-from-report-creator"] = True
|
|
276
296
|
robot2testbench(testbench_report, robot_result, output_directory, configuration)
|
|
277
297
|
|
|
278
298
|
|
|
@@ -237,6 +237,10 @@ class Configuration:
|
|
|
237
237
|
_: KW_ONLY
|
|
238
238
|
include_blocked: bool = False
|
|
239
239
|
merge_protocol: bool = True
|
|
240
|
+
set_tester_from_report_creator: bool = False
|
|
241
|
+
keep_extracted_report: bool = False
|
|
242
|
+
attachments_directory: str = ""
|
|
243
|
+
attachments_variable: str = "ITB_ATTACHMENTS_DIR"
|
|
240
244
|
clean_mode: CleanMode = CleanMode.GENERATED
|
|
241
245
|
keyword_comment_style: KeywordCommentStyle = KeywordCommentStyle.STRUCTURED
|
|
242
246
|
keyword_comment_max_depth: int = 5
|
|
@@ -271,6 +275,12 @@ class Configuration:
|
|
|
271
275
|
}
|
|
272
276
|
),
|
|
273
277
|
merge_protocol=dictionary.get("merge-protocol", True),
|
|
278
|
+
set_tester_from_report_creator=dictionary.get(
|
|
279
|
+
"set-tester-from-report-creator", False
|
|
280
|
+
),
|
|
281
|
+
keep_extracted_report=dictionary.get("keep-extracted-report", False),
|
|
282
|
+
attachments_directory=dictionary.get("attachments-directory", "").replace("\\", "/"),
|
|
283
|
+
attachments_variable=dictionary.get("attachments-variable", "ITB_ATTACHMENTS_DIR"),
|
|
274
284
|
keyword_comment_style=KeywordCommentStyle(
|
|
275
285
|
dictionary.get("keyword-comment-style", "STRUCTURED").upper()
|
|
276
286
|
),
|
|
@@ -9,6 +9,10 @@ from .config import AttachmentConflictBehaviour, ReferenceBehaviour
|
|
|
9
9
|
from .log import logger
|
|
10
10
|
from .model import ReferenceAssignment, ReferenceKind
|
|
11
11
|
|
|
12
|
+
# A 'file:' URI is always absolute (RFC 8089): 'file:///x.zip' is '/x.zip', the
|
|
13
|
+
# file system root. Files in the Robot output directory are referenced by a
|
|
14
|
+
# relative value without scheme, which 'ExecutionArtifactInfo' resolves against
|
|
15
|
+
# the directory of the output.xml. See docs/usage/fetch_results.md.
|
|
12
16
|
FILE_URI_SCHEME = "file://"
|
|
13
17
|
MEGABYTE = 1000 * 1000
|
|
14
18
|
|
|
@@ -137,8 +141,12 @@ class ExecutionArtifactStorage:
|
|
|
137
141
|
if not attachment_folder_path.exists():
|
|
138
142
|
attachment_folder_path.mkdir(parents=True, exist_ok=True)
|
|
139
143
|
if not (attachment_folder_path / filename).exists():
|
|
140
|
-
|
|
141
|
-
|
|
144
|
+
stored_file = self._use_new_attachment(filename, artifact_value, attachment_folder_path)
|
|
145
|
+
else:
|
|
146
|
+
stored_file = self._dispatch_attachment_copy(
|
|
147
|
+
filename, artifact_value, attachment_folder_path
|
|
148
|
+
)
|
|
149
|
+
return f"{attachment_folder_path.name}/{stored_file}"
|
|
142
150
|
|
|
143
151
|
def _process_artifact(self, artifact: str) -> str | None:
|
|
144
152
|
artifact_info = ExecutionArtifactInfo(artifact, self.output_xml)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"""JSON encoding and decoding of report files - with orjson when it is installed.
|
|
2
|
+
|
|
3
|
+
orjson (Rust) parses and serializes several times faster than the standard
|
|
4
|
+
library, which matters for reports whose test case files reach megabytes.
|
|
5
|
+
It is optional: ``pip install testbench2robotframework[fast]``. Without it the
|
|
6
|
+
standard library is used; the files are identical apart from key order and
|
|
7
|
+
whitespace details neither TestBench nor this package depend on.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import json
|
|
13
|
+
from enum import Enum
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from typing import Any
|
|
16
|
+
|
|
17
|
+
try:
|
|
18
|
+
import orjson
|
|
19
|
+
except ImportError: # pragma: no cover - depends on the environment
|
|
20
|
+
orjson = None
|
|
21
|
+
|
|
22
|
+
JSONDecodeError = json.JSONDecodeError
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _default(value: Any) -> Any:
|
|
26
|
+
return value.value if isinstance(value, Enum) else str(value)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def dumps(content: Any) -> str:
|
|
30
|
+
"""Compact JSON, the way TestBench exports it."""
|
|
31
|
+
if orjson is not None:
|
|
32
|
+
return orjson.dumps(content, default=_default).decode("utf-8")
|
|
33
|
+
return json.dumps(content, default=_default)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def loads(text: str | bytes) -> Any:
|
|
37
|
+
"""Raises 'JSONDecodeError' (the standard library's) for invalid input."""
|
|
38
|
+
if orjson is not None:
|
|
39
|
+
try:
|
|
40
|
+
return orjson.loads(text)
|
|
41
|
+
except orjson.JSONDecodeError as error:
|
|
42
|
+
raise JSONDecodeError(str(error), "", 0) from error
|
|
43
|
+
return json.loads(text)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def write_json(filepath: str | Path, content: Any) -> None:
|
|
47
|
+
Path(filepath).write_text(dumps(content), encoding="utf-8")
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def read_json_file(filepath: str | Path) -> Any:
|
|
51
|
+
return loads(Path(filepath).read_bytes())
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def using_orjson() -> bool:
|
|
55
|
+
return orjson is not None
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import json
|
|
2
1
|
import sys
|
|
3
2
|
from dataclasses import dataclass
|
|
4
|
-
from json import JSONDecodeError
|
|
5
3
|
from pathlib import Path
|
|
6
4
|
|
|
5
|
+
from .json_codec import JSONDecodeError, read_json_file
|
|
7
6
|
from .log import logger
|
|
8
7
|
from .model import (
|
|
9
8
|
ReferenceAssignment,
|
|
@@ -162,8 +161,7 @@ class TestBenchJsonReader:
|
|
|
162
161
|
|
|
163
162
|
def read_json(filepath: str | Path, silent=True):
|
|
164
163
|
try:
|
|
165
|
-
|
|
166
|
-
return json.load(json_file)
|
|
164
|
+
return read_json_file(filepath)
|
|
167
165
|
except FileNotFoundError:
|
|
168
166
|
if not silent:
|
|
169
167
|
logger.error(f"File '{filepath}' does not exist.")
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from dataclasses import asdict
|
|
3
|
-
from enum import Enum
|
|
4
3
|
from pathlib import Path
|
|
5
4
|
|
|
6
5
|
from .config import Configuration
|
|
6
|
+
from .json_codec import write_json
|
|
7
7
|
from .log import logger
|
|
8
8
|
from .model import (
|
|
9
9
|
ReferenceAssignment,
|
|
@@ -41,36 +41,17 @@ def write_test_structure_element(
|
|
|
41
41
|
else:
|
|
42
42
|
filepath = Path(json_dir) / Path(f"{test_structure_element.uniqueID}.json")
|
|
43
43
|
content = asdict(test_structure_element)
|
|
44
|
-
|
|
45
|
-
json.dump(
|
|
46
|
-
content,
|
|
47
|
-
output_file,
|
|
48
|
-
indent=2,
|
|
49
|
-
default=lambda o: o.value if isinstance(o, Enum) else str(o),
|
|
50
|
-
)
|
|
44
|
+
write_json(filepath, content)
|
|
51
45
|
|
|
52
46
|
|
|
53
47
|
def write_main_protocol(json_dir: str, main_protocol: list[TestCaseSetExecutionForImport]) -> None:
|
|
54
|
-
protocol
|
|
55
|
-
filepath = Path(json_dir) / Path("protocol.json")
|
|
56
|
-
with Path(filepath).open("w+", encoding="utf8") as output_file:
|
|
57
|
-
json.dump(
|
|
58
|
-
protocol,
|
|
59
|
-
output_file,
|
|
60
|
-
indent=2,
|
|
61
|
-
default=lambda o: o.value if isinstance(o, Enum) else str(o),
|
|
62
|
-
)
|
|
48
|
+
write_json(Path(json_dir) / "protocol.json", [asdict(tcs) for tcs in main_protocol])
|
|
63
49
|
|
|
64
50
|
|
|
65
51
|
def write_references(json_dir: str, references: list[ReferenceAssignment]) -> None:
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
[asdict(ref) for ref in references],
|
|
70
|
-
output_file,
|
|
71
|
-
indent=2,
|
|
72
|
-
default=lambda o: o.value if isinstance(o, Enum) else str(o),
|
|
73
|
-
)
|
|
52
|
+
write_json(Path(json_dir) / "references.json", [asdict(ref) for ref in references])
|
|
53
|
+
|
|
54
|
+
|
|
74
55
|
|
|
75
56
|
|
|
76
57
|
def write_default_config(config_file):
|