diff --git a/README.md b/README.md
index d1149ea..a1ec526 100644
--- a/README.md
+++ b/README.md
@@ -30,8 +30,8 @@ trcli
```
You should get something like this:
```
-TestRail CLI v1.8.0
-Copyright 2023 Gurock Software GmbH - www.gurock.com
+TestRail CLI v1.9.0
+Copyright 2024 Gurock Software GmbH - www.gurock.com
Supported and loaded modules:
- parse_junit: JUnit XML Files (& Similar)
- parse_robot: Robot Framework XML Files
@@ -41,11 +41,9 @@ Supported and loaded modules:
CLI general reference
--------
```shell
-trcli --help
-```
-```shell
-TestRail CLI v1.8.0
-Copyright 2023 Gurock Software GmbH - www.gurock.com
+$ trcli --help
+TestRail CLI v1.9.0
+Copyright 2024 Gurock Software GmbH - www.gurock.com
Usage: trcli [OPTIONS] COMMAND [ARGS]...
TestRail CLI
@@ -255,11 +253,9 @@ providing you with a solid base of test cases, which you can further expand on T
### Reference
```shell
-trcli parse_openapi --help
-```
-```shell
-TestRail CLI v1.5.0
-Copyright 2021 Gurock Software GmbH - www.gurock.com
+$ trcli parse_openapi --help
+TestRail CLI v1.9.0
+Copyright 2024 Gurock Software GmbH - www.gurock.com
Usage: trcli parse_openapi [OPTIONS]
Parse OpenAPI spec and create cases in TestRail
diff --git a/tests/test_data/XML/robotframework_id_in_name.xml b/tests/test_data/XML/robotframework_id_in_name_RF50.xml
similarity index 100%
rename from tests/test_data/XML/robotframework_id_in_name.xml
rename to tests/test_data/XML/robotframework_id_in_name_RF50.xml
diff --git a/tests/test_data/XML/robotframework_id_in_name_RF70.xml b/tests/test_data/XML/robotframework_id_in_name_RF70.xml
new file mode 100644
index 0000000..000f3e1
--- /dev/null
+++ b/tests/test_data/XML/robotframework_id_in_name_RF70.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+SETUP
+SETUP
+Logs the given message with the given level.
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+
+Set test message to:
+ Custom test message
+
+Custom test message
+Sets message for the current test case.
+
+
+Some documentation about my test Cases
+ Nothing to see here
+
+ - testrail_case_id: C123
+ - testrail_case_field: refs:TR-1
+ - testrail_case_field: priority_id:2
+ - testrail_result_field: custom_environment:qa
+ - testrail_result_field: custom_dropdown_1:3
+ - testrail_result_comment: Notes for the result
+ - testrail_attachment: /reports/screenshot.png
+
+Custom test message
+
+
+
+
+NOK
+NOK
+Fails the test with the given message and optionally alters its tags.
+
+
+NOK
+
+
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+
+
+Simple homepage links tests
+
+
+
+
+
+
+All Tests
+
+
+
+
+Sub-Tests
+Sub-Tests.Subtests 1
+Sub-Tests.Subtests 2
+
+
+
+
+
diff --git a/tests/test_data/XML/robotframework_id_in_property.xml b/tests/test_data/XML/robotframework_id_in_property_RF50.xml
similarity index 100%
rename from tests/test_data/XML/robotframework_id_in_property.xml
rename to tests/test_data/XML/robotframework_id_in_property_RF50.xml
diff --git a/tests/test_data/XML/robotframework_id_in_property_RF70.xml b/tests/test_data/XML/robotframework_id_in_property_RF70.xml
new file mode 100644
index 0000000..53de3c6
--- /dev/null
+++ b/tests/test_data/XML/robotframework_id_in_property_RF70.xml
@@ -0,0 +1,92 @@
+
+
+
+
+
+SETUP
+SETUP
+Logs the given message with the given level.
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+
+Set test message to:
+ Custom test message
+
+Custom test message
+Sets message for the current test case.
+
+
+Some documentation about my test Cases
+ Nothing to see here
+
+ - testrail_case_id: C1
+ - testrail_case_field: refs:TR-1
+ - testrail_case_field: priority_id:2
+ - testrail_result_field: custom_environment:qa
+ - testrail_result_field: custom_dropdown_1:3
+ - testrail_result_comment: Notes for the result
+ - testrail_attachment: /reports/screenshot.png
+
+Custom test message
+
+
+
+
+NOK
+NOK
+Fails the test with the given message and optionally alters its tags.
+
+
+- testrail_case_id: c2
+NOK
+
+
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+- testrail_case_id: 3
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+- testrail_case_id: 4
+
+
+Simple homepage links tests
+
+
+
+
+
+
+All Tests
+
+
+
+
+Sub-Tests
+Sub-Tests.Subtests 1
+Sub-Tests.Subtests 2
+
+
+
+
+
diff --git a/tests/test_data/XML/robotframework_simple.xml b/tests/test_data/XML/robotframework_simple_RF50.xml
similarity index 100%
rename from tests/test_data/XML/robotframework_simple.xml
rename to tests/test_data/XML/robotframework_simple_RF50.xml
diff --git a/tests/test_data/XML/robotframework_simple_RF70.xml b/tests/test_data/XML/robotframework_simple_RF70.xml
new file mode 100644
index 0000000..b88a95a
--- /dev/null
+++ b/tests/test_data/XML/robotframework_simple_RF70.xml
@@ -0,0 +1,89 @@
+
+
+
+
+
+SETUP
+SETUP
+Logs the given message with the given level.
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+
+Set test message to:
+ Custom test message
+
+Custom test message
+Sets message for the current test case.
+
+
+Some documentation about my test Cases
+ Nothing to see here
+
+ - testrail_case_id: C123
+ - testrail_case_field: refs:TR-1
+ - testrail_case_field: priority_id:2
+ - testrail_result_field: custom_environment:qa
+ - testrail_result_field: custom_dropdown_1:3
+ - testrail_result_comment: Notes for the result
+ - testrail_attachment: /reports/screenshot.png
+
+Custom test message
+
+
+
+
+NOK
+NOK
+Fails the test with the given message and optionally alters its tags.
+
+
+NOK
+
+
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+
+
+
+
+OK
+OK
+Logs the given message with the given level.
+
+
+
+
+Simple homepage links tests
+
+
+
+
+
+
+All Tests
+
+
+
+
+Sub-Tests
+Sub-Tests.Subtests 1
+Sub-Tests.Subtests 2
+
+
+
+
+
diff --git a/tests/test_data/json/robotframework_id_in_name.json b/tests/test_data/json/robotframework_id_in_name_RF50.json
similarity index 98%
rename from tests/test_data/json/robotframework_id_in_name.json
rename to tests/test_data/json/robotframework_id_in_name_RF50.json
index 3575cf0..65741be 100644
--- a/tests/test_data/json/robotframework_id_in_name.json
+++ b/tests/test_data/json/robotframework_id_in_name_RF50.json
@@ -1,5 +1,5 @@
{
- "name": "robotframework_id_in_name",
+ "name": "robotframework_id_in_name_RF50",
"suite_id": null,
"description": null,
"testsections": [
@@ -156,5 +156,5 @@
"properties": []
}
],
- "source": "robotframework_id_in_name.xml"
+ "source": "robotframework_id_in_name_RF50.xml"
}
\ No newline at end of file
diff --git a/tests/test_data/json/robotframework_id_in_property.json b/tests/test_data/json/robotframework_id_in_name_RF70.json
similarity index 98%
rename from tests/test_data/json/robotframework_id_in_property.json
rename to tests/test_data/json/robotframework_id_in_name_RF70.json
index ce42a90..6f58df7 100644
--- a/tests/test_data/json/robotframework_id_in_property.json
+++ b/tests/test_data/json/robotframework_id_in_name_RF70.json
@@ -1,5 +1,5 @@
{
- "name": "robotframework_id_in_property",
+ "name": "robotframework_id_in_name_RF70",
"suite_id": null,
"description": null,
"testsections": [
@@ -156,5 +156,5 @@
"properties": []
}
],
- "source": "robotframework_id_in_property.xml"
+ "source": "robotframework_id_in_name_RF70.xml"
}
\ No newline at end of file
diff --git a/tests/test_data/json/robotframework_id_in_property_RF50.json b/tests/test_data/json/robotframework_id_in_property_RF50.json
new file mode 100644
index 0000000..ca314b4
--- /dev/null
+++ b/tests/test_data/json/robotframework_id_in_property_RF50.json
@@ -0,0 +1,160 @@
+{
+ "name": "robotframework_id_in_property_RF50",
+ "suite_id": null,
+ "description": null,
+ "testsections": [
+ {
+ "name": "Sub-Tests.Subtests 1",
+ "suite_id": null,
+ "parent_id": null,
+ "description": null,
+ "section_id": null,
+ "testcases": [
+ {
+ "title": "Subtest 1a",
+ "section_id": null,
+ "case_id": 1,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {
+ "refs": "TR-1",
+ "priority_id": "2"
+ },
+ "result": {
+ "case_id": 1,
+ "status_id": 1,
+ "comment": "Notes for the result\n\nCustom test message\n ",
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [
+ "/reports/screenshot.png"
+ ],
+ "result_fields": {
+ "custom_environment": "qa",
+ "custom_dropdown_1": "3"
+ },
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ },
+ {
+ "content": "Set Test Message",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 1.Subtest 1a"
+ },
+ {
+ "title": "Subtest 1b",
+ "section_id": null,
+ "case_id": 2,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": 2,
+ "status_id": 5,
+ "comment": "NOK",
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Fail",
+ "status_id": 5
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 1.Subtest 1b"
+ }
+ ],
+ "properties": []
+ },
+ {
+ "name": "Sub-Tests.Subtests 2",
+ "suite_id": null,
+ "parent_id": null,
+ "description": null,
+ "section_id": null,
+ "testcases": [
+ {
+ "title": "Subtest 2a",
+ "section_id": null,
+ "case_id": 3,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": 3,
+ "status_id": 1,
+ "comment": null,
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 2.Subtest 2a"
+ },
+ {
+ "title": "Subtest 2b",
+ "section_id": null,
+ "case_id": 4,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": 4,
+ "status_id": 1,
+ "comment": null,
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 2.Subtest 2b"
+ }
+ ],
+ "properties": []
+ }
+ ],
+ "source": "robotframework_id_in_property_RF50.xml"
+}
\ No newline at end of file
diff --git a/tests/test_data/json/robotframework_id_in_property_RF70.json b/tests/test_data/json/robotframework_id_in_property_RF70.json
new file mode 100644
index 0000000..e214961
--- /dev/null
+++ b/tests/test_data/json/robotframework_id_in_property_RF70.json
@@ -0,0 +1,160 @@
+{
+ "name": "robotframework_id_in_property_RF70",
+ "suite_id": null,
+ "description": null,
+ "testsections": [
+ {
+ "name": "Sub-Tests.Subtests 1",
+ "suite_id": null,
+ "parent_id": null,
+ "description": null,
+ "section_id": null,
+ "testcases": [
+ {
+ "title": "Subtest 1a",
+ "section_id": null,
+ "case_id": 1,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {
+ "refs": "TR-1",
+ "priority_id": "2"
+ },
+ "result": {
+ "case_id": 1,
+ "status_id": 1,
+ "comment": "Notes for the result\n\nCustom test message\n ",
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [
+ "/reports/screenshot.png"
+ ],
+ "result_fields": {
+ "custom_environment": "qa",
+ "custom_dropdown_1": "3"
+ },
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ },
+ {
+ "content": "Set Test Message",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 1.Subtest 1a"
+ },
+ {
+ "title": "Subtest 1b",
+ "section_id": null,
+ "case_id": 2,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": 2,
+ "status_id": 5,
+ "comment": "NOK",
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Fail",
+ "status_id": 5
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 1.Subtest 1b"
+ }
+ ],
+ "properties": []
+ },
+ {
+ "name": "Sub-Tests.Subtests 2",
+ "suite_id": null,
+ "parent_id": null,
+ "description": null,
+ "section_id": null,
+ "testcases": [
+ {
+ "title": "Subtest 2a",
+ "section_id": null,
+ "case_id": 3,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": 3,
+ "status_id": 1,
+ "comment": null,
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 2.Subtest 2a"
+ },
+ {
+ "title": "Subtest 2b",
+ "section_id": null,
+ "case_id": 4,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": 4,
+ "status_id": 1,
+ "comment": null,
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 2.Subtest 2b"
+ }
+ ],
+ "properties": []
+ }
+ ],
+ "source": "robotframework_id_in_property_RF70.xml"
+}
\ No newline at end of file
diff --git a/tests/test_data/json/robotframework_simple.json b/tests/test_data/json/robotframework_simple_RF50.json
similarity index 98%
rename from tests/test_data/json/robotframework_simple.json
rename to tests/test_data/json/robotframework_simple_RF50.json
index af0593a..1cb94fb 100644
--- a/tests/test_data/json/robotframework_simple.json
+++ b/tests/test_data/json/robotframework_simple_RF50.json
@@ -1,5 +1,5 @@
{
- "name": "robotframework_simple",
+ "name": "robotframework_simple_RF50",
"suite_id": null,
"description": null,
"testsections": [
@@ -156,5 +156,5 @@
"properties": []
}
],
- "source": "robotframework_simple.xml"
+ "source": "robotframework_simple_RF50.xml"
}
\ No newline at end of file
diff --git a/tests/test_data/json/robotframework_simple_RF70.json b/tests/test_data/json/robotframework_simple_RF70.json
new file mode 100644
index 0000000..94fd19b
--- /dev/null
+++ b/tests/test_data/json/robotframework_simple_RF70.json
@@ -0,0 +1,160 @@
+{
+ "name": "robotframework_simple_RF70",
+ "suite_id": null,
+ "description": null,
+ "testsections": [
+ {
+ "name": "Sub-Tests.Subtests 1",
+ "suite_id": null,
+ "parent_id": null,
+ "description": null,
+ "section_id": null,
+ "testcases": [
+ {
+ "title": "Subtest 1a",
+ "section_id": null,
+ "case_id": null,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {
+ "refs": "TR-1",
+ "priority_id": "2"
+ },
+ "result": {
+ "case_id": null,
+ "status_id": 1,
+ "comment": "Notes for the result\n\nCustom test message\n ",
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [
+ "/reports/screenshot.png"
+ ],
+ "result_fields": {
+ "custom_environment": "qa",
+ "custom_dropdown_1": "3"
+ },
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ },
+ {
+ "content": "Set Test Message",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 1.Subtest 1a"
+ },
+ {
+ "title": "Subtest 1b",
+ "section_id": null,
+ "case_id": null,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": null,
+ "status_id": 5,
+ "comment": "NOK",
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Fail",
+ "status_id": 5
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 1.Subtest 1b"
+ }
+ ],
+ "properties": []
+ },
+ {
+ "name": "Sub-Tests.Subtests 2",
+ "suite_id": null,
+ "parent_id": null,
+ "description": null,
+ "section_id": null,
+ "testcases": [
+ {
+ "title": "Subtest 2a",
+ "section_id": null,
+ "case_id": null,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": null,
+ "status_id": 1,
+ "comment": null,
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 2.Subtest 2a"
+ },
+ {
+ "title": "Subtest 2b",
+ "section_id": null,
+ "case_id": null,
+ "estimate": null,
+ "template_id": null,
+ "type_id": null,
+ "milestone_id": null,
+ "refs": null,
+ "case_fields": {},
+ "result": {
+ "case_id": null,
+ "status_id": 1,
+ "comment": null,
+ "version": null,
+ "elapsed": null,
+ "defects": null,
+ "assignedto_id": null,
+ "attachments": [],
+ "result_fields": {},
+ "junit_result_unparsed": null,
+ "custom_step_results": [
+ {
+ "content": "Log",
+ "status_id": 1
+ }
+ ]
+ },
+ "custom_automation_id": "Sub-Tests.Subtests 2.Subtest 2b"
+ }
+ ],
+ "properties": []
+ }
+ ],
+ "source": "robotframework_simple_RF70.xml"
+}
\ No newline at end of file
diff --git a/tests/test_robot_parser.py b/tests/test_robot_parser.py
index 033cd92..617a624 100644
--- a/tests/test_robot_parser.py
+++ b/tests/test_robot_parser.py
@@ -18,23 +18,41 @@ class TestRobotParser:
@pytest.mark.parametrize(
"matcher, input_xml_path, expected_path",
[
+ # RF 5.0 format
(
MatchersParser.AUTO,
- Path(__file__).parent / "test_data/XML/robotframework_simple.xml",
- Path(__file__).parent / "test_data/json/robotframework_simple.json",
+ Path(__file__).parent / "test_data/XML/robotframework_simple_RF50.xml",
+ Path(__file__).parent / "test_data/json/robotframework_simple_RF50.json",
),
(
MatchersParser.NAME,
- Path(__file__).parent / "test_data/XML/robotframework_id_in_name.xml",
- Path(__file__).parent / "test_data/json/robotframework_id_in_name.json",
+ Path(__file__).parent / "test_data/XML/robotframework_id_in_name_RF50.xml",
+ Path(__file__).parent / "test_data/json/robotframework_id_in_name_RF50.json",
),
(
MatchersParser.PROPERTY,
- Path(__file__).parent / "test_data/XML/robotframework_id_in_property.xml",
- Path(__file__).parent / "test_data/json/robotframework_id_in_property.json",
+ Path(__file__).parent / "test_data/XML/robotframework_id_in_property_RF50.xml",
+ Path(__file__).parent / "test_data/json/robotframework_id_in_property_RF50.json",
+ ),
+
+ # RF 7.0 format
+ (
+ MatchersParser.AUTO,
+ Path(__file__).parent / "test_data/XML/robotframework_simple_RF70.xml",
+ Path(__file__).parent / "test_data/json/robotframework_simple_RF70.json",
+ ),
+ (
+ MatchersParser.NAME,
+ Path(__file__).parent / "test_data/XML/robotframework_id_in_name_RF70.xml",
+ Path(__file__).parent / "test_data/json/robotframework_id_in_name_RF70.json",
+ ),
+ (
+ MatchersParser.PROPERTY,
+ Path(__file__).parent / "test_data/XML/robotframework_id_in_property_RF70.xml",
+ Path(__file__).parent / "test_data/json/robotframework_id_in_property_RF70.json",
)
],
- ids=["Case Matcher Auto", "Case Matcher Name", "Case Matcher Property"],
+ ids=["Case Matcher Auto", "Case Matcher Name", "Case Matcher Property", "Case Matcher Auto", "Case Matcher Name", "Case Matcher Property"],
)
@pytest.mark.parse_robot
def test_junit_xml_parser_id_matcher_name(
diff --git a/tests_e2e/reports_robot/simple_report.xml b/tests_e2e/reports_robot/simple_report.xml
deleted file mode 100644
index 46cec84..0000000
--- a/tests_e2e/reports_robot/simple_report.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-
-
-
-
-
- SETUP
- Logs the given message with the given level.
- SETUP
-
-
-
-
- OK
- Logs the given message with the given level.
- OK
-
-
-
- Test message 123
- Sets message for the current test case.
- Set test message to:
- Test message 123
-
-
-
- Some documentation about my test Cases
- Nothing to see here
-
- - testrail_case_id: C123
- - testrail_case_field: refs:TR-1
- - testrail_case_field: priority_id:2
- - testrail_attachment: attachments/testrail.jpg
-
- Test message
- 123
-
-
-
-
- NOK
- Fails the test with the given message and optionally alters its tags.
- NOK
-
-
- LOL
- NOK
-
-
-
-
-
-
- OK
- Logs the given message with the given level.
- OK
-
-
-
-
-
-
- OK
- Logs the given message with the given level.
- OK
-
-
-
-
-
-
- OK
- Logs the given message with the given level.
- OK
-
-
-
-
- Simple homepage links tests
-
-
-
-
-
-
- All Tests
-
-
-
-
- Sub-Tests
- Sub-Tests.Subtests 1
- Sub-Tests.Subtests 2
-
-
-
-
-
diff --git a/tests_e2e/test_end2end.py b/tests_e2e/test_end2end.py
index f0701d6..5db8a9f 100644
--- a/tests_e2e/test_end2end.py
+++ b/tests_e2e/test_end2end.py
@@ -46,14 +46,33 @@ class TestsEndToEnd:
def install_trcli(self):
_run_cmd("cd .. && pip install .")
- def test_cli_robot_report(self):
+ def test_cli_robot_report_RF50(self):
output = _run_cmd(f"""
trcli -y \\
-h {self.TR_INSTANCE} \\
--project "SA - (DO NOT DELETE) TRCLI-E2E-Tests" \\
parse_robot \\
--title "[CLI-E2E-Tests] ROBOT FRAMEWORK PARSER" \\
- -f "reports_robot/simple_report.xml"
+ -f "reports_robot/simple_report_RF50.xml"
+ """)
+ _assert_contains(
+ output,
+ [
+ "Processed 5 test cases in 2 sections.",
+ f"Creating test run. Test run: {self.TR_INSTANCE}index.php?/runs/view",
+ "Uploading 1 attachments for 1 test results.",
+ "Submitted 5 test results in"
+ ]
+ )
+
+ def test_cli_robot_report_RF70(self):
+ output = _run_cmd(f"""
+trcli -y \\
+ -h {self.TR_INSTANCE} \\
+ --project "SA - (DO NOT DELETE) TRCLI-E2E-Tests" \\
+ parse_robot \\
+ --title "[CLI-E2E-Tests] ROBOT FRAMEWORK PARSER" \\
+ -f "reports_robot/simple_report_RF70.xml"
""")
_assert_contains(
output,
diff --git a/trcli/__init__.py b/trcli/__init__.py
index 29654ee..0a0a43a 100644
--- a/trcli/__init__.py
+++ b/trcli/__init__.py
@@ -1 +1 @@
-__version__ = "1.8.0"
+__version__ = "1.9.0"
diff --git a/trcli/constants.py b/trcli/constants.py
index 854407f..cd12561 100644
--- a/trcli/constants.py
+++ b/trcli/constants.py
@@ -65,7 +65,7 @@
)
TOOL_VERSION = f"""TestRail CLI v{trcli.__version__}
-Copyright 2023 Gurock Software GmbH - www.gurock.com"""
+Copyright 2024 Gurock Software GmbH - www.gurock.com"""
TOOL_USAGE = f"""Supported and loaded modules:
- parse_junit: JUnit XML Files (& Similar)
- parse_robot: Robot Framework XML Files
diff --git a/trcli/readers/robot_xml.py b/trcli/readers/robot_xml.py
index 0c9d098..c8218c7 100644
--- a/trcli/readers/robot_xml.py
+++ b/trcli/readers/robot_xml.py
@@ -1,4 +1,4 @@
-from datetime import datetime
+from datetime import datetime, timedelta
from typing import List
from xml.etree import ElementTree
@@ -79,7 +79,13 @@ def _find_suites(self, suite_element, sections_list: List, namespace=""):
"fail": 5
}
status_id = status_dict[status.get("status").lower()]
- elapsed_time = self._parse_rf_time(status.get("endtime")) - self._parse_rf_time(status.get("starttime"))
+
+ # if status contains "elapsed" then obtain it, otherwise calculate it from starttime and endtime
+ if "elapsed" in status.attrib:
+ elapsed_time = self._parse_rf70_elapsed_time(status.get("elapsed"))
+ else:
+ elapsed_time = self._parse_rf50_time(status.get("endtime")) - self._parse_rf50_time(status.get("starttime"))
+
error_msg = status.text
keywords = test.findall("kw")
step_keywords = []
@@ -121,8 +127,19 @@ def _find_suites(self, suite_element, sections_list: List, namespace=""):
self._find_suites(sub_suite_element, sections_list, namespace=namespace)
@staticmethod
- def _parse_rf_time(time_str: str) -> datetime:
+ def _parse_rf50_time(time_str: str) -> datetime:
+ # "20230712 22:32:12.951"
return datetime.strptime(time_str, '%Y%m%d %H:%M:%S.%f')
+
+ @staticmethod
+ def _parse_rf70_time(time_str: str) -> datetime:
+ # "2023-07-12T22:32:12.951000"
+ return datetime.strptime(time_str, '%Y-%m-%dT%H:%M:%S.%f')
+
+ @staticmethod
+ def _parse_rf70_elapsed_time(timedelta_str: str) -> timedelta:
+ # "0.001000"
+ return timedelta(seconds=float(timedelta_str))
@staticmethod
def _remove_tr_prefix(text: str, tr_prefix: str) -> str: