-
Notifications
You must be signed in to change notification settings - Fork 0
/
testlink_xml_inject.py
124 lines (110 loc) · 4.07 KB
/
testlink_xml_inject.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# Script usage:
# - export ONE testcase from testlink as xml file
# - create excel file (xls, xlsx) where first column is "Actions"
# second column is "Expected Results". File should NOT contains
# any headers or other information, data should be on first sheet
# - run this file with first parameter path to excel and second path
# to xml. Actual command see down below.
# - Export xml file back to the testlink. You have options for already
# existed cases: update latest version (prefered), create new version
# and so on.
#
# Requirements:
# pip install pandas openpyxl
#
# ATTENTION: Next command will change xml file, if you want to preserve
# original file, please copy it manually.
#
# python testlink_xml_inject.py {path to excel file} {path to xml file}
# %%
import pandas as pd
import xml.etree.ElementTree as ET
import sys
import os
# %%
def _tag_text_to_CDATA(element: ET.Element) -> None:
"""Convert tag element text to CDATA xml type
----------
Parameters:
element: tag element
----------
Returns: it is void function
"""
def _escape_cdata(text):
# escape character data
try:
# it's worth avoiding do-nothing calls for strings that are
# shorter than 500 characters, or so. assume that's, by far,
# the most common case in most applications.
if "&" in text:
text = text.replace("&", "&")
if ("<" in text) and (text.startswith("<![CDATA") is False):
text = text.replace("<", "<")
if (">" in text) and (text.startswith("<![CDATA") is False):
text = text.replace(">", ">")
return text
except (TypeError, AttributeError):
_raise_serialization_error(text)
ET._escape_cdata = _escape_cdata
for child in element:
if child.text is not None:
child.text = f"<![CDATA[{child.text}]]>"
def create_steps_from_excel(path_to_excel: str) -> ET.Element:
"""Create xml tag steps from excel file
----------
Parameters:
path_to_excel: path to excel file with steps
----------
Returns: return xml tag steps in ET.Element format
"""
path_to_excel = os.path.abspath(path_to_excel)
steps_xlsx = pd.ExcelFile(path_to_excel)
steps_sheet = pd.read_excel(steps_xlsx, header=None)
steps_sheet.set_index((i + 1 for i in steps_sheet.index), inplace=True)
steps = ET.Element("steps")
for row in steps_sheet.index:
step = ET.Element("step")
step_number = ET.Element("step_number")
step_number.text = str(row)
actions = ET.Element("actions")
actions.text = str(steps_sheet.at[row, 0])
actions.text = actions.text.replace("\n", r"<br>")
expectedresults = ET.Element("expectedresults")
expectedresults.text = str(steps_sheet.at[row, 1])
expectedresults.text = expectedresults.text.replace("\n", r"<br>")
step.append(step_number)
step.append(actions)
step.append(expectedresults)
_tag_text_to_CDATA(step)
steps.append(step)
return steps
def prepare_xml(path_to_xml: str) -> ET.Element:
"""Load testcase xml, and delete steps tag
----------
Parameters:
path_to_xml: path to xml file with testcase
----------
Returns: return whole xml tree in ET.ElementTree and xml tag testcase in ET.Element formats
"""
path_to_xml = os.path.abspath(path_to_xml)
tree = ET.parse(path_to_xml)
root = tree.getroot()
testcase = root.find("./testcase")
original_steps = testcase.find("./steps")
if original_steps is not None:
testcase.remove(original_steps)
_tag_text_to_CDATA(testcase)
return tree, testcase
def main(*args):
path_to_excel = sys.argv[1]
path_to_xml = sys.argv[2]
steps = create_steps_from_excel(path_to_excel)
tree, testcase = prepare_xml(path_to_xml)
# append new tag steps from our excel file
testcase.append(steps)
# write our changes back to the xml file
tree.write(path_to_xml, encoding="utf-8")
# %%
if __name__ == "__main__":
main(*sys.argv)
# %%