]> git.aero2k.de Git - tmp/jakarta-migration.git/blob
6bbdb80ff67f5178accfa679eb08118313fa5431
[tmp/jakarta-migration.git] /
1 package org.collectionspace.services.IntegrationTests.xmlreplay;
2
3 import org.collectionspace.services.common.XmlTools;
4 import org.collectionspace.services.common.api.FileTools;
5 import org.collectionspace.services.common.api.Tools;
6 import org.dom4j.Document;
7 import org.dom4j.DocumentHelper;
8
9 import javax.swing.text.Style;
10 import java.io.File;
11 import java.util.ArrayList;
12 import java.util.List;
13
14 /**  Format a report based on XmlReplay ServiceResult object from a test group.
15  * @author  laramie
16  */
17 public class XmlReplayReport {
18     public static final String INCLUDES_DIR =  "_includes";
19
20     protected static final String HTML_PAGE_END = "</body></html>";
21     protected static final String TOPLINKS = "<a class='TOPLINKS' href='javascript:openAll();'>Show All Payloads</a>" + "<a class='TOPLINKS' href='javascript:closeAll();'>Hide All Payloads</a>";
22
23     protected static final String HTML_TEST_START = "<div class='TESTCASE'>";
24     protected static final String HTML_TEST_END = "</div>";
25
26     protected static final String GROUP_START = "<div class='TESTGROUP'>";
27     protected static final String GROUP_END = "</div>";
28
29     protected static final String RUNINFO_START = "<div class='RUNINFO'>";
30     protected static final String RUNINFO_END = "</div>";
31
32
33     protected static final String DIV_END = "</div>";
34
35     protected static final String PRE_START = "<pre class='SUMMARY'>";
36     protected static final String PRE_END = "</pre>";
37     protected static final String BR = "<br />\r\n";
38
39     protected static final String DETAIL_START = "<table border='1' class='DETAIL_TABLE'><tr><td>\r\n";
40     protected static final String DETAIL_LINESEP = "</td></tr>\r\n<tr><td>";
41     protected static final String DETAIL_END = "</td></tr></table>";
42
43     private static final String SP = "&nbsp;&nbsp;&nbsp;";
44
45     public XmlReplayReport(String reportsDir){
46         this.reportsDir = reportsDir;
47     }
48
49     private String reportsDir = "";
50     public String getReportsDir(){
51         return reportsDir;
52     }
53
54     protected static String formatCollapse(String myDivID, String linkText){
55         return  "<a href='javascript:;' onmousedown=\"toggleDiv('"+myDivID+"');\">"+linkText+"</a>"
56                  + BR
57                  + "<div ID='"+myDivID+"' class='PAYLOAD' style='display:none'>";
58     }
59
60
61     private StringBuffer header = new StringBuffer();
62     private StringBuffer buffer = new StringBuffer();
63     private String runInfo = "";
64
65     public String getPage(String basedir){
66         return    formatPageStart(basedir)
67                     +"<div class='REPORTTIME'>XmlReplay run  "+Tools.nowLocale()+"</div>"
68                     +header.toString()
69                     +this.runInfo
70                     +BR
71                     +getTOC("").toString()
72                     +BR
73                     +buffer.toString()
74                     +HTML_PAGE_END;
75     }
76
77     public String getTOC(String reportName){
78         StringBuffer tocBuffer = new StringBuffer();
79
80         if (Tools.notBlank(reportName)){
81             // We are generating a TOC for an index.html file that references other report files.
82             tocBuffer.append(this.header.toString());
83         } else {
84             // We are generating a single report file, so all links are relative to this file, and we should have the TOPLINKS which allow things like showAllPayloads..
85             tocBuffer.append(BR).append(TOPLINKS).append(BR);
86         }
87         for (TOC toc: tocList){
88               tocBuffer.append(BR+"<a href='"+reportName+"#TOC"+toc.tocID+"'>"+toc.testID+"</a> "+ toc.detail);
89         }
90         tocBuffer.append(BR+BR);
91         return tocBuffer.toString();
92     }
93
94     public void addRunInfo(String text){
95          this.runInfo = RUNINFO_START+text+RUNINFO_END;
96          //addText(this.runInfo);
97     }
98
99     /** Call this method to insert arbitrary HTML in your report file, at the point after the last call to addTestResult() or addTestGroup().    */
100     public void addText(String text){
101          buffer.append(text);
102     }
103
104     public void addTestGroup(String groupID, String controlFile){
105         header.append(GROUP_START);
106         header.append(lbl("Test Group")).append(groupID).append(SP).append(lbl("Control File")).append(controlFile);
107         header.append(GROUP_END);
108     }
109
110     private int divID = 0;
111
112     public void addTestResult(ServiceResult serviceResult){
113         buffer.append(HTML_TEST_START);
114         int tocID = ++divID;
115         buffer.append(formatSummary(serviceResult, tocID));
116         buffer.append(formatPayloads(serviceResult, tocID));
117         buffer.append(HTML_TEST_END);
118     }
119
120     public static class TOC {
121         public int tocID;
122         public String testID;
123         public String detail;
124     }
125     private List<TOC> tocList = new ArrayList<TOC>();
126
127     public static String formatPageStart(String xmlReplayBaseDir){
128             String script = FileTools.readFile(xmlReplayBaseDir, INCLUDES_DIR+"/reports-include.js");
129             String style =  FileTools.readFile(xmlReplayBaseDir, INCLUDES_DIR+"/reports-include.css");
130             return "<html><head><script type='text/javascript'>\r\n"
131                      +script
132                      +"\r\n</script>\r\n<style>\r\n"
133                      +style
134                      +"\r\n</style></head><body>";
135     }
136
137     public File saveReport(String xmlReplayBaseDir, String reportsDir, String reportName)  {
138         try {
139             File resultFile = FileTools.saveFile(reportsDir, reportName, this.getPage(xmlReplayBaseDir), true);
140             if (resultFile!=null) {
141                 String resultFileName =  resultFile.getCanonicalPath();
142                 //System.out.println("XmlReplay summary reports saved to directory: "+resultFile.getParent());
143                 System.out.println("XmlReplay summary report: "+resultFileName);
144                 return resultFile;
145             }
146         } catch (Exception e){
147             System.out.println("ERROR saving XmlReplay report in basedir: "+reportsDir+" reportName: "+reportName+" error: "+e);
148         }
149         return null;
150     }
151
152     //public static String getReportsDir(String basename){
153     //    return Tools.glue(basename,"/","TEST-REPORTS");
154     //}
155
156     /** @param localMasterFilename should be a local filename for the index of each xmlReplay master control file, e.g. objectexit.xml
157      *               so what gets written to disk will be something like index.objectexit.xml.html . The actual filename will be available from
158      *               the returned File object if successful.
159      *   @return File if successful, else returns null.
160      */
161     public static File saveIndexForMaster(String xmlReplayBaseDir, String reportsDir, String localMasterFilename, List<String> reportsList){
162         String masterFilename =  "index."+localMasterFilename+".html";
163         try{
164             StringBuffer sb = new StringBuffer(formatPageStart(xmlReplayBaseDir));
165             String dateStr = Tools.nowLocale();
166             sb.append("<div class='REPORTTIME'>XmlReplay run  "+dateStr+" master: "+localMasterFilename+"</div>");
167             for (String oneToc: reportsList){
168                 sb.append(oneToc);
169                 sb.append("<hr />");
170             }
171             sb.append(HTML_PAGE_END);
172
173             return FileTools.saveFile(reportsDir,masterFilename, sb.toString(), false);
174         } catch (Exception e){
175             System.out.println("ERROR saving XmlReplay report index: in  xmlReplayBaseDir: "+reportsDir+"localMasterFilename: "+localMasterFilename+" masterFilename: "+masterFilename+" list: "+reportsList+" error: "+e);
176             return null;
177         }
178     }
179
180     protected String formatSummary(ServiceResult serviceResult, int tocID){
181         TOC toc = new TOC();
182         toc.tocID = tocID;
183         toc.testID = serviceResult.testID;
184         toc.detail =  (serviceResult.gotExpectedResult() ? ok("SUCCESS") : red("FAILURE") );
185         tocList.add(toc);
186
187         StringBuffer fb = new StringBuffer();
188         fb.append("<a name='TOC"+tocID+"'></a>");
189         fb.append(detail(serviceResult, false, false, DETAIL_START, DETAIL_LINESEP, DETAIL_END, tocID));
190         return fb.toString();
191     }
192
193     protected String formatPayloads(ServiceResult serviceResult, int tocID){
194         StringBuffer fb = new StringBuffer();
195         fb.append(BR);
196         appendPayload(fb, serviceResult.requestPayload, "REQUEST", "REQUEST" + tocID);
197         appendPayload(fb, serviceResult.requestPayloadsRaw, "REQUEST (RAW)", "REQUESTRAW" + tocID);
198         appendPayload(fb, serviceResult.result, "RESPONSE", "RESPONSE" + tocID);
199         appendPayload(fb, serviceResult.expectedContentExpanded, "EXPECTED", "EXPECTED" + tocID);
200         fb.append(BR);
201
202         return fb.toString();
203     }
204
205     protected void appendPayload( StringBuffer fb , String payload, String title, String theDivID){
206         if (Tools.notBlank(payload)){
207             //fb.append(BR+title+":"+BR);
208             try {
209                 String pretty = prettyPrint(payload);
210
211
212                 fb.append(formatCollapse(theDivID, title));  //starts a div.
213                 fb.append(PRE_START);
214                 fb.append(escape(pretty));
215                 fb.append(PRE_END);
216                 fb.append(DIV_END);                        //ends that div.
217             } catch (Exception e){
218                 String error = "<font color='red'>ERROR:</font> "+payload;
219                 fb.append(error);
220                 fb.append(BR).append(BR);
221             }
222         }
223     }
224
225     private String escape(String source){
226         try {
227             return Tools.searchAndReplace(source, "<", "&lt;");
228         } catch (Exception e){
229             return "ERROR escaping requestPayload"+e;
230         }
231     }
232
233     private String prettyPrint(String rawXml) throws Exception {
234         Document document = DocumentHelper.parseText(rawXml);
235         return XmlTools.prettyPrint(document, "    ");
236     }
237
238     private static final String LINE = "<hr />\r\n";
239     private static final String CRLF = "<br />\r\n";
240
241     protected String red(String label){
242         return "<span class='ERROR'>"+label+"</span> ";
243     }
244     protected String ok(String label){
245         return "<span class='OK'>"+label+"</span> ";
246     }
247     protected String lbl(String label){
248         return "<span class='LABEL'>"+label+":</span> ";
249     }
250     public String detail(ServiceResult s, boolean includePayloads, boolean includePartSummary, String start, String linesep, String end, int tocID){
251         String partSummary = s.partsSummary(includePartSummary);
252         String res =  start
253                 + ( s.gotExpectedResult() ? lbl("SUCCESS") : "<font color='red'><b>FAILURE</b></font>"  )
254                   + SP + ( Tools.notEmpty(s.testID) ? s.testID : "" )
255                   + SP +linesep
256                 +s.method+ SP +"<a href='"+s.fullURL+"'>"+s.fullURL+"</a>"                                     +linesep
257                 + s.responseCode+ SP +lbl("gotExpected")+s.gotExpectedResult()                                                       +linesep
258                 + (Tools.notBlank(s.failureReason) ? s.failureReason +linesep : "" )
259                 + ( (s.expectedCodes.size()>0) ? lbl("expectedCodes")+s.expectedCodes+linesep : "" )
260                 //+ ( Tools.notEmpty(s.testGroupID) ? "testGroupID:"+s.testGroupID+linesep : "" )
261                 //THIS WORKS, BUT IS VERBOSE: + ( Tools.notEmpty(s.fromTestID) ? "fromTestID:"+s.fromTestID+linesep : "" )
262                 + ( Tools.notEmpty(s.responseMessage) ? lbl("msg")+s.responseMessage+linesep : "" )
263                 +lbl("auth")+s.auth                                                                                        +linesep
264                 + ( Tools.notEmpty(s.deleteURL) ? lbl("deleteURL")+s.deleteURL+linesep : "" )
265                 + ( Tools.notEmpty(s.location) ? lbl("location.CSID")+s.location+linesep : "" )
266                 + ( Tools.notEmpty(s.error) ? "ERROR:"+s.error +linesep : "" )
267                 + ((includePartSummary && Tools.notBlank(partSummary)) ? lbl("part summary")+partSummary +linesep : "")
268                 + ( includePayloads && Tools.notBlank(s.requestPayload) ? LINE+lbl("requestPayload")+LINE+CRLF+s.requestPayload+LINE : "" )
269                 + ( includePayloads && Tools.notBlank(s.result) ? LINE+lbl("result")+LINE+CRLF+s.result : "" )
270                 +end;
271         return res;
272     }
273
274 }