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}