CSIT-170 Parse output of robot framework into HTML table
[csit.git] / resources / tools / robot_output_parser_publish.py
1 #!/usr/bin/python
2
3 # Copyright (c) 2016 Cisco and/or its affiliates.
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 """Script extracts intersted data (name, documentation, message, status) from
17 robot framework output file (output.xml) and print in specified format (wiki,
18 html) to stdout or, if specified by parameter, redirect to file."""
19
20 import argparse
21 import sys
22
23 from robot.api import ExecutionResult, ResultVisitor
24
25
26 class ExecutionChecker(ResultVisitor):
27     """Abstract class to traverse through the test suite structure."""
28
29     def __init__(self, args):
30         self.formatting = args.formatting
31
32     def visit_suite(self, suite):
33         """Implements traversing through the suite and its direct children.
34
35         :param suite: Suite to process.
36         :type suite: Suite
37         :return: Nothing.
38         """
39
40         if self.start_suite(suite) is not False:
41             if suite.tests:
42                 if self.formatting == 'html':
43                     sys.stdout.write('<table border=1>'+'\n')
44                     sys.stdout.write('<tr><th width=32%>Name</th>'+\
45                                      '<th width=40%>Documentation</th>'+\
46                                      '<th width=24%>Message</th>'+\
47                                      '<th width=4%>Status</th><tr/>'+'\n')
48                 elif self.formatting == 'wiki':
49                     sys.stdout.write('{| class="wikitable"'+'\n')
50                     sys.stdout.write('!Name!!Documentation!!Message!!Status'+'\n')
51                 else:
52                     pass
53
54             suite.suites.visit(self)
55             suite.tests.visit(self)
56
57             if suite.tests:
58                 if self.formatting == 'html':
59                     sys.stdout.write('</table>'+'\n')
60                 elif self.formatting == 'wiki':
61                     sys.stdout.write('|}'+'\n')
62                 else:
63                     pass
64
65             self.end_suite(suite)
66
67     def start_suite(self, suite):
68         """Called when suite starts.
69
70         :param suite: Suite to process.
71         :type suite: Suite
72         :return: Nothing.
73         """
74
75         level = len(suite.longname.split("."))
76
77         if self.formatting == 'html':
78             mark_l = '<h'+str(level)+'>'
79             mark_r = '</h'+str(level)+'>'
80             sys.stdout.write(mark_l+suite.name+mark_r+'\n')
81         elif self.formatting == 'wiki':
82             mark = "=" * (level+2)
83             sys.stdout.write(mark+suite.name+mark+'\n')
84         else:
85             pass
86
87     def end_suite(self, suite):
88         """Called when suite ends.
89
90         :param suite: Suite to process.
91         :type suite: Suite
92         :return: Nothing.
93         """
94
95         pass
96
97     def visit_test(self, test):
98         """Implements traversing through the test.
99
100         :param test: Test to process.
101         :type test: Test
102         :return: Nothing.
103         """
104
105         if self.start_test(test) is not False:
106             self.end_test(test)
107
108     def start_test(self, test):
109         """Called when test starts.
110
111         :param test: Test to process.
112         :type test: Test
113         :return: Nothing.
114         """
115
116         if self.formatting == 'html':
117             sys.stdout.write('<tr>'+'\n')
118             sys.stdout.write('<td>'+test.name+'</td>'+'\n')
119             sys.stdout.write('<td>'+test.doc+'</td>'+'\n')
120             sys.stdout.write('<td>'+test.message+'</td>'+'\n')
121             sys.stdout.write('<td>'+test.status+'</td>'+'\n')
122         elif self.formatting == 'wiki':
123             sys.stdout.write('|-'+'\n')
124             sys.stdout.write('|'+test.name+'\n')
125             sys.stdout.write('|'+test.doc+'\n')
126             sys.stdout.write('|'+test.message+'\n')
127             sys.stdout.write('|'+test.status+'\n')
128         else:
129             pass
130
131     def end_test(self, test):
132         """Called when test ends.
133
134         :param test: Test to process.
135         :type test: Test
136         :return: Nothing.
137         """
138
139         if self.formatting == 'html':
140             sys.stdout.write('</tr>'+'\n')
141         elif self.formatting == 'wiki':
142             pass
143         else:
144             pass
145
146
147 def process_robot_file(args):
148     """Process data from robot output.xml file and return raw data.
149
150     :param args: Parsed arguments.
151     :type args: ArgumentParser
152     :return: Nothing.
153     """
154
155     result = ExecutionResult(args.input)
156     checker = ExecutionChecker(args)
157     result.visit(checker)
158
159
160 def print_error(msg):
161     """Print error message on stderr.
162
163     :param msg: Error message to print.
164     :type msg: str
165     :return: nothing
166     """
167
168     sys.stderr.write(msg+'\n')
169
170
171 def parse_args():
172     """Parse arguments from cmd line.
173
174     :return: Parsed arguments.
175     :rtype ArgumentParser
176     """
177
178     parser = argparse.ArgumentParser()
179     parser.add_argument("-i", "--input", required=True,
180                         type=argparse.FileType('r'),
181                         help="Robot XML log file")
182     parser.add_argument("-o", "--output",
183                         type=argparse.FileType('w'),
184                         help="Output file")
185     parser.add_argument("-f", "--formatting", required=True,
186                         choices=['html', 'wiki'],
187                         help="Output file format")
188
189     return parser.parse_args()
190
191
192 def main():
193     """Main function."""
194
195     args = parse_args()
196
197     if args.output:
198         sys.stdout = args.output
199
200     process_robot_file(args)
201
202
203 if __name__ == "__main__":
204     sys.exit(main())