001package com.thed.zblast.parser;
002
003import com.thed.zblast.parser.model.TestCase;
004import com.thed.zblast.parser.model.TestSuite;
005import com.thed.zblast.parser.util.*;
006import org.w3c.dom.Document;
007import org.w3c.dom.Node;
008import org.w3c.dom.NodeList;
009
010import java.io.File;
011import java.util.ArrayList;
012import java.util.List;
013import java.util.Vector;
014
015public class QTPResultParserImpl implements ZConstantsResults{
016        
017        private short shortDefaultResult;
018        short result = RESULT_SUCCESS;
019        Vector<ZExecutionStep> executionSteps = new Vector<ZExecutionStep>();
020        List<TestSuite> testSuites = new ArrayList<TestSuite>();
021        List<TestCase> tests = new ArrayList<TestCase>();
022        
023        private String resultPrefix = "Res";  // Default result folder created by QTP
024
025        public ZReturnStatus parseResultFile(File testFolder) {
026
027                System.out.println("""
028                                parsing result folder %s...""".formatted(testFolder));
029
030            int nbWarning = 0;
031                int nbFails   = 0;
032                int nbSuccess = 0;
033                
034                if (testFolder == null || !testFolder.exists() || !testFolder.isDirectory()) {
035                        executionSteps.add(new ZExecutionStep(ZCalendarUtils.getCurrentTime(), RESULT_FAILURE, "couldn't find the folder"));
036                        return new ZReturnStatus(RESULT_FAILURE, executionSteps,testSuites);
037                }
038                
039                File[] childFolders = testFolder.listFiles();
040                if (childFolders == null) {
041                        executionSteps.add(new ZExecutionStep(ZCalendarUtils.getCurrentTime(), RESULT_FAILURE, "empty test folder"));
042                        return new ZReturnStatus(RESULT_FAILURE, executionSteps,testSuites);                    
043                }
044                int index = -1;
045                File resultsFile = null;
046                boolean missingReport = false;
047                for (File folder: childFolders) {
048                        System.out.println("-> " + folder);
049                        String folderName = folder.getName();
050                        if (folder.isDirectory() && folderName.startsWith(resultPrefix)) {
051                                try {
052                                        int currentIndex = Integer.parseInt(folderName.substring(resultPrefix.length()));
053                                        System.out.println("""
054                                                        current index: %s  --->  %s""".formatted(folderName.substring(resultPrefix.length()), currentIndex));
055                                        if (currentIndex > index) { // only keeps the latest one
056                                                index = currentIndex;
057                                                
058                                                // old naming
059                                                resultsFile = new File("""
060                                                                %s/%s%d/Report/Results.xml""".formatted(testFolder.getAbsolutePath(), resultPrefix, currentIndex));
061                                                if (resultsFile.exists()) {
062                                                        System.out.println("        > old naming report exists: " + index);
063                                                        missingReport = false; // we ensure the last report we found exists (if some previous reports does not exist we don't care about it)
064                                                } else {
065                                                        
066                                                        // new naming
067                                                        resultsFile = new File("""
068                                                                        %s/%s%d/Report/run_results.xml""".formatted(testFolder.getAbsolutePath(), resultPrefix, currentIndex));
069                                                        if (resultsFile.exists()) {
070                                                                System.out.println("        > new naming report exists: " + index);
071                                                                missingReport = false; // we ensure the last report we found exists (if some previous reports does not exist we don't care about it)
072                                                        } else {
073                                                                System.out.println("        > report does NOT exists: " + index);
074                                                                missingReport = true;
075                                                        }
076                                                }
077                                        }
078                                } catch (NumberFormatException e) {
079                                        System.out.println( "the rest of the name is not an integer: " + folderName);
080                                }
081                        }
082                }
083                if (index == -1) {
084                        System.out.println( "couldn't find appropriate result folder");
085                        executionSteps.add(new ZExecutionStep(ZCalendarUtils.getCurrentTime(), RESULT_FAILURE, "couldn't find appropriate result folder"));
086                        return new ZReturnStatus(RESULT_FAILURE, executionSteps,testSuites);                            
087                }
088                
089                File latestResultsFolder = new File(testFolder.getAbsolutePath() + "/" + resultPrefix + index);
090                System.out.println( "latest results folder found: " + latestResultsFolder);
091                
092                if (missingReport) {
093                        System.out.println( "report missing for this result folder");
094                        executionSteps.add(new ZExecutionStep(ZCalendarUtils.getCurrentTime(), RESULT_FAILURE, "report missing for this result folder"));
095                        return new ZReturnStatus(RESULT_FAILURE, executionSteps,testSuites);    
096                }
097                
098                // search potential HTML reports in resx
099                File[] htmlFiles = latestResultsFolder.listFiles();
100                if (htmlFiles != null) {
101                        for (File htmlFile: htmlFiles) {
102                                String extension = null;
103                            String str2 = htmlFile.getName();
104                            int i = str2.lastIndexOf('.');
105                            if ((i > 0) && (i < str2.length() - 1))
106                            extension = str2.substring(i + 1).toLowerCase();
107                            
108                                if (extension != null && extension.equalsIgnoreCase("html")) {
109                                        System.out.println("""
110                                                        attaching html report %s...""".formatted(htmlFile));
111                                ZXMLDocumentFactory.addTestcaseMessageAttachment(htmlFile);
112                                }
113                        }
114                }
115                
116
117                // parse the result file to get the result and the execution steps
118                ZXMLDocumentFactory.addTestcaseMessageAttachment(resultsFile);
119                System.out.println("""
120                                reading %s...""".formatted(resultsFile));
121            Document xmlDocument = ZXMLDocumentFactory.createXMLDoc(resultsFile);
122            
123            // +-----------------------------------------+
124            // |                OLD FORMAT               |
125            // +-----------------------------------------+
126            if (resultsFile.getName().equalsIgnoreCase("Results.xml")) {
127
128                    // attach all the excel sheets used for this test
129                    NodeList tableNodeList = ZXMLDocumentFactory.getNodeObjListFromXPath(xmlDocument, "//NodeArgs[@eType='Table']/BtmPane[@vType='Table']/Path");
130                    if (tableNodeList != null) {
131                            for (int i=0; i<tableNodeList.getLength(); i++) {
132                                Node resultNode = tableNodeList.item(i);
133                                String tableName = resultNode.getFirstChild().getNodeValue();
134                                        File tableFile = new File("""
135                                                        %s/%s%d/Report/%s""".formatted(testFolder.getAbsolutePath(), resultPrefix, index, tableName));
136                                        System.out.println("""
137                                                        attaching excel sheet %s...""".formatted(tableFile));
138                                ZXMLDocumentFactory.addTestcaseMessageAttachment(tableFile);
139                            }
140                    }
141        
142                    NodeList iterationNodeList = ZXMLDocumentFactory.getNodeObjListFromXPath(xmlDocument, "//DIter");
143                    if (iterationNodeList != null) {
144                            if (iterationNodeList.getLength() > 0) {
145                                    for (int j=0; j<iterationNodeList.getLength(); j++) {
146                                        Node iterationNode = iterationNodeList.item(j);
147                                        
148                                        String iterationIndex = iterationNode.getAttributes().getNamedItem("iterID").getNodeValue();
149                                                System.err.println("""
150                                                                ============ Iteration %s ============""".formatted(iterationIndex));
151                                        
152                                                NodeList resultNodeList = ZXMLDocumentFactory.getNodeObjListFromXPath(iterationNode, "Action//Step/NodeArgs[@eType='Replay' or @eType='Context' or @eType='User']");
153                                            for (int k=0; k<resultNodeList.getLength(); k++) {
154                                                String type   = "";
155                                                String status = "";
156                                                String time   = "";
157                                                String desc   = "";
158                                                
159                                                Node resultNode = resultNodeList.item(k);
160                                                
161                                                try {type = ZXMLDocumentFactory.getNodeStringValueFromXPath(resultNode, "@eType");} catch (Exception e) {}
162                                                
163                                                try {status = ZXMLDocumentFactory.getNodeStringValueFromXPath(resultNode, "@status");} catch (Exception e) {}
164                                                
165                                                Node timeNode = ZXMLDocumentFactory.getNodeFromXPath(resultNode, "preceding-sibling::Time[1]");
166                                                try {time   = timeNode.getFirstChild().getNodeValue();} catch (Exception e) {}
167                                                        
168                                                Node descNode = ZXMLDocumentFactory.getNodeFromXPath(resultNode, "Disp");
169                                                try {desc   = descNode.getFirstChild().getNodeValue();} catch (Exception e) {}
170
171                                                        System.err.println("""
172                                                                        - Result: %s : %s : %s""".formatted(status, type, desc));
173                                                
174                                                if (status.equals("Passed")) {
175                                                        if (!desc.startsWith("LoadFunctionLibrary")) { // hide the possibly very numerous successfull LoadFunctionLibrary
176                                                                        System.err.println("""
177                                                                                        %d SUCCESS: %s %s %s""".formatted(k, iterationIndex, type, desc));
178                                                                        executionSteps.add(new ZExecutionStep(time, RESULT_SUCCESS, """
179                                                                                        #%s %s %s""".formatted(iterationIndex, type, desc)));
180                                                                nbSuccess++;
181                                                        }
182                        
183                                                } else if (status.equals("Failed")) {
184                                                                System.err.println("""
185                                                                                %d FAILURE: %s %s %s""".formatted(k, iterationIndex, type, desc));
186                                                                executionSteps.add(new ZExecutionStep(time, RESULT_FAILURE, """
187                                                                                #%s %s %s""".formatted(iterationIndex, type, desc)));
188                                                        nbFails++;
189                        
190                                                } else if (status.equals("Warning")) {
191                                                                System.err.println("""
192                                                                                %d RELATIVE: %s %s %s""".formatted(k, iterationIndex, type, desc));
193                                                                executionSteps.add(new ZExecutionStep(time, RESULT_RELATIVE, """
194                                                                                #%s %s %s""".formatted(iterationIndex, type, desc)));
195                                                        nbWarning++;
196        
197                                                } else if (status.equals("Done")) {
198                                                        // ignore
199                        
200                                                } else { // something else
201                                                                System.err.println("""
202                                                                                %d UNKNOWN: %s : %s : %s : %s""".formatted(k, status, iterationIndex, type, desc));
203                                                                executionSteps.add(new ZExecutionStep(time, RESULT_NOT_EXECUTED, """
204                                                                                #%s %s %s""".formatted(iterationIndex, type, desc)));
205                                                }
206                                            }           
207                                    }
208                            } else {
209                                        NodeList resultNodeList = ZXMLDocumentFactory.getNodeObjListFromXPath(xmlDocument, "//Action//Step/NodeArgs[@eType='Replay' or @eType='Context' or @eType='User']");
210                                    for (int k=0; k<resultNodeList.getLength(); k++) {
211                                        String type   = "";
212                                        String status = "";
213                                        String time   = "";
214                                        String desc   = "";
215                                        
216                                        Node resultNode = resultNodeList.item(k);
217                                        
218                                        try {type = ZXMLDocumentFactory.getNodeStringValueFromXPath(resultNode, "@eType");} catch (Exception e) {}
219                                        
220                                        try {status = ZXMLDocumentFactory.getNodeStringValueFromXPath(resultNode, "@status");} catch (Exception e) {}
221                                        
222                                        Node timeNode = ZXMLDocumentFactory.getNodeFromXPath(resultNode, "preceding-sibling::Time[1]");
223                                        try {time   = timeNode.getFirstChild().getNodeValue();} catch (Exception e) {}
224                                                
225                                        Node descNode = ZXMLDocumentFactory.getNodeFromXPath(resultNode, "Disp");
226                                        try {desc   = descNode.getFirstChild().getNodeValue();} catch (Exception e) {}
227                                        
228                                        if (status.equals("Passed")) {
229                                                if (!desc.startsWith("LoadFunctionLibrary")) { // hide the possibly very numerous successfull LoadFunctionLibrary
230                                                                System.err.println("""
231                                                                                %d SUCCESS: %s %s""".formatted(k, type, desc));
232                                                                executionSteps.add(new ZExecutionStep(time, RESULT_SUCCESS, """
233                                                                                #%s %s""".formatted("0", type, desc)));
234                                                        nbSuccess++;
235                                                }
236                
237                                        } else if (status.equals("Failed")) {
238                                                        System.err.println("""
239                                                                        %d FAILURE: %s %s""".formatted(k, type, desc));
240                                                        executionSteps.add(new ZExecutionStep(time, RESULT_FAILURE, """
241                                                                        #%s %s""".formatted("0", type, desc)));
242                                                nbFails++;
243                
244                                        } else if (status.equals("Warning")) {
245                                                        System.err.println("""
246                                                                        %d RELATIVE: %s %s""".formatted(k, type, desc));
247                                                        executionSteps.add(new ZExecutionStep(time, RESULT_RELATIVE, """
248                                                                        #%s %s""".formatted("0", type, desc)));
249                                                nbWarning++;
250                
251                                        } else if (status.equals("Done")) {
252                                                // ignore
253                
254                                        } else { // something else
255                                                        System.err.println("""
256                                                                        %d UNKNOWN: %s %s""".formatted(k, type, desc));
257                                                        executionSteps.add(new ZExecutionStep(time, RESULT_NOT_EXECUTED, """
258                                                                        #%s %s""".formatted("0", type, desc)));
259                                        }
260                                    }                           
261                            }
262                    } else {
263                        nbFails++;
264                        executionSteps.add(new ZExecutionStep(ZCalendarUtils.getCurrentTime(), RESULT_NOT_EXECUTED, "No DIter nodes in the report!"));
265                    }
266                    
267                    result = shortDefaultResult;
268                    System.err.println("===> nbSuccess = " + nbSuccess);
269                    System.err.println("===> nbFails   = " + nbFails);
270                    System.err.println("===> nbWarning = " + nbWarning);
271                    if (nbFails == 0 && nbWarning == 0 && nbSuccess > 0) {
272                        System.err.println("===> SUCCESS");
273                        result = RESULT_SUCCESS;
274                    } else if (nbFails > 0) {
275                        System.err.println("===> FAILURE");
276                        result = RESULT_FAILURE;
277                    } else {
278                        System.err.println("===> DEFAULT");
279                    }
280            
281            // +-----------------------------------------+
282            // |                NEW FORMAT               |
283            // +-----------------------------------------+
284                } else if (resultsFile.getName().equalsIgnoreCase("run_results.xml")) {
285                        NodeList resultNodeList = ZXMLDocumentFactory.getNodeObjListFromXPath(xmlDocument, "//ReportNode");
286                        System.out.println(resultNodeList.getLength());
287                        
288                        List<TestCase> testcases = new ArrayList<TestCase>();
289                        TestSuite midTestSuite = new TestSuite();
290                        for (int k=0; k<resultNodeList.getLength(); k++) {                      
291                                TestCase tempTestcase = new TestCase();         
292                                TestSuite tempTestSuite = new TestSuite();
293                                tests.clear();
294                        String name   = "";
295                        String status = "";
296                        String time   = "";
297                        String desc   = "";
298                        
299                        Node resultNode = resultNodeList.item(k);
300                        String suiteName = resultNode.getAttributes().getNamedItem("type").getNodeValue();
301                                System.out.println("""
302                                                    =========   %s =========""".formatted(resultNode.getAttributes().getNamedItem("type").getNodeValue()));
303                        try {name   = ZXMLDocumentFactory.getNodeStringValueFromXPath(resultNode, "Data/Name");} catch (Exception e) {}
304                        try {status = ZXMLDocumentFactory.getNodeStringValueFromXPath(resultNode, "Data/Result");} catch (Exception e) {}
305                        try {time   = ZXMLDocumentFactory.getNodeStringValueFromXPath(resultNode, "Data/StartTime");} catch (Exception e) {}
306                        try {desc   = ZXMLDocumentFactory.getNodeStringValueFromXPath(resultNode, "Data/Description");
307                        if(desc == null){
308                                desc = "No description";
309                        }
310                        
311                        } catch (Exception e) {}
312
313                                System.out.println("""
314                                                    - Result: %s : %s : %s %s""".formatted(status, name, desc, suiteName));
315                        tempTestcase.setName(name);
316                        tempTestcase.setDescription(desc);
317                        tempTestcase.setStatus(status);
318                        
319                        if (status.equals("Passed")||status.equals("Done")) {
320                                if (!desc.startsWith("LoadFunctionLibrary")) { // hide the possibly very numerous successfull LoadFunctionLibrary
321                                                System.err.println("""
322                                                                %d SUCCESS: %s %s""".formatted(k, name, desc));
323                                        executionSteps.add(new ZExecutionStep(time, RESULT_SUCCESS, name + " " + desc));
324                                        nbSuccess++;
325                                }
326
327                        } else if (status.equals("Failed")) {
328                                        System.err.println("""
329                                                        %d FAILURE: %s %s""".formatted(k, name, desc));
330                                executionSteps.add(new ZExecutionStep(time, RESULT_FAILURE, name + " " + desc));
331                                nbFails++;
332
333                        } else if (status.equals("Warning")) {
334                                        System.err.println("""
335                                                        %d RELATIVE: %s %s""".formatted(k, name, desc));
336                                executionSteps.add(new ZExecutionStep(time, RESULT_RELATIVE, name + " " + desc));
337                                nbWarning++;
338
339                        } else if (status.equals("Done")) {
340                                // ignore
341
342                        } else { // something else
343                                        System.err.println("""
344                                                        %d UNKNOWN: %s : %s : %s""".formatted(k, status, name, desc));
345                                executionSteps.add(new ZExecutionStep(time, RESULT_NOT_EXECUTED, name + " " + desc));
346                        }               
347                        tests.add(tempTestcase);
348                        tests.add(tempTestcase);
349                        tempTestSuite.setName(suiteName);                       
350                        tempTestSuite.setSuiteTestCaseMap(suiteName, tests);
351                        testSuites.add(tempTestSuite);          
352                        
353                    }
354                        
355                        System.out.println(testSuites.size());
356
357                    
358                    result = shortDefaultResult;
359                    System.err.println("===> nbSuccess = " + nbSuccess);
360                    System.err.println("===> nbFails   = " + nbFails);
361                    System.err.println("===> nbWarning = " + nbWarning);
362                    if (nbFails == 0 && nbWarning == 0 && nbSuccess > 0) {
363                        System.err.println("===> SUCCESS");
364                        result = RESULT_SUCCESS;
365                    } else if (nbFails > 0) {
366                        System.err.println("===> FAILURE");
367                        result = RESULT_FAILURE;
368                    } else {
369                        System.err.println("===> DEFAULT");
370                    }
371                }
372
373                return new ZReturnStatus(result, executionSteps, testSuites);
374        }
375        
376}