ch.vorburger.webdriver.reporting.TestCaseReportWriter.java Source code

Java tutorial

Introduction

Here is the source code for ch.vorburger.webdriver.reporting.TestCaseReportWriter.java

Source

/*
 * Copyright 2011 Michael Vorburger & other contributors.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

package ch.vorburger.webdriver.reporting;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.junit.runners.model.FrameworkMethod;

/**
 * Report Writer.
 *
 * This class should not have any JUnit or WebDriver dependencies/imports, only I/O.
 *
 * @author Nasir Raza
 * @author Michael Vorburger
 */
public class TestCaseReportWriter {
    private static final String START_TEST = "Start";
    private static final String END_TEST = "End";
    private static final String LOG_FLAG = "Logflag";
    private static final String LINE_SEP = System.getProperty("line.separator");
    private static final String APPENDED_JS = "jquery-ui-1.8.5.custom.min.js";
    private final static String SCREENSHOTS_DIR_NAME = "screenshots/";

    private final List<String> packageNamesList = new LinkedList<String>();
    private final File reportDirFile = new File(System.getProperty("user.dir") + "/target/webdriver-reporting/");
    private final File jsFile = new File(reportDirFile, APPENDED_JS);
    private final File screenshotsDirFile = new File(reportDirFile, SCREENSHOTS_DIR_NAME);

    private StringBuffer infoString = new StringBuffer("");
    private File logFile;

    private StringBuffer getInfoString() {
        return infoString;
    }

    private void setInfoString(StringBuffer infoString) {
        this.infoString = infoString;
    }

    /* package local */
    void clearInfoString() {
        setInfoString(new StringBuffer(""));
    }

    public File getLogFile() {
        return logFile;
    }

    public void setLogFile(File logFile) {
        this.logFile = logFile;
    }

    public void createNewTestReportFile(FrameworkMethod method, String reportFileName) {
        BufferedWriter bufferedWriter = null;
        try {
            File file = new File(reportDirFile, reportFileName);
            if (!file.getParentFile().exists()) {
                file.getParentFile().mkdirs();
            }
            bufferedWriter = new BufferedWriter(new FileWriter(file));
            bufferedWriter.write(getHeader());
            setLogFile(file);

        } catch (IOException e) {
            throw new RuntimeException("Oups, could't create WebDriver Report Log files?!", e);
        } finally {
            try {
                if (bufferedWriter != null) {
                    bufferedWriter.flush();
                    bufferedWriter.close();
                }
            } catch (IOException ex) {
                // Zucchero says "Nothing To Loose" if this happens - ignore.
            }
        }
    }

    /**
     * Returns appropriate HTML headers.
     */
    protected String getHeader() {
        // TODO Should copy this out from a HTML fragment (!) on classpath... just need to deal with Date below
        StringBuffer sbuf = new StringBuffer();
        sbuf.append(
                "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">"
                        + LINE_SEP);
        sbuf.append("<html>" + LINE_SEP);
        sbuf.append("<head>" + LINE_SEP);
        sbuf.append("<title>WebDriver Report</title>" + LINE_SEP);
        sbuf.append(" <LINK href=\"../jquery-ui-1.8.5.custom.css\" rel=\"stylesheet\" type=\"text/css\">");
        sbuf.append(" <LINK href=\"../style.css\" rel=\"stylesheet\" type=\"text/css\">");
        sbuf.append("<script type=\"text/javascript\" src=\"../jquery-1.4.2.min.js\"></script>");
        sbuf.append("<script type=\"text/javascript\" src=\"../jquery-ui-1.8.5.custom.min.js\"></script>");
        sbuf.append("<script type=\"text/javascript\" src=\"../util.js\"></script>");
        sbuf.append("<style type=\"text/css\">" + LINE_SEP);
        sbuf.append("<!--" + LINE_SEP);
        sbuf.append(
                "body, table {font-family: arial,sans-serif; font-size: x-small;}.buttonStyle { color: #900; border: 1px solid #900; font-weight: bold;  float: right;}"
                        + LINE_SEP);
        sbuf.append(
                "table{table-layout: fixed;}td{text-align: left;padding-top: 4px;padding-bottom: 4px;padding-left: 8px;padding-right: 0px;}th {background: #336699; color: #FFFFFF; text-align: left;}.timeClass{width:5%;}"
                        + LINE_SEP);
        sbuf.append("-->" + LINE_SEP);
        sbuf.append("</style>" + LINE_SEP);

        sbuf.append("</head>" + LINE_SEP);
        sbuf.append("<body onload=\"init();\" bgcolor=\"#D8D8D8\" topmargin=\"0\" leftmargin=\"0\">" + LINE_SEP);
        sbuf.append("<font size=\"2\">Log session start time " + new java.util.Date() + "</font><br>" + LINE_SEP);
        sbuf.append("<hr size=\"1\" noshade>" + LINE_SEP);
        sbuf.append("<div id=\"status\" width=\"100%\"> </div>" + LINE_SEP);

        return sbuf.toString();
    }

    public void infoWithFlag(String message) {
        info(LOG_FLAG + message);
    }

    public void info(String message) {
        // Create all the required files to run this log HTML file.
        createAdditionalFiles();
        String rowClass = "row";
        boolean isBizLog = false;
        boolean stackTraceFlag = false;
        String methodName = "";
        String temp = "";
        infoString = getInfoString();
        if (isBizLog) {
            rowClass = "rowBiz";
        }
        if (message.contains(".png")) {
            rowClass = "rowImg";
        }

        boolean startTestFlag = message.trim().startsWith(START_TEST);
        boolean endTestFlag = message.trim().startsWith(END_TEST);
        long tableId = System.currentTimeMillis();
        double randomId = Math.random();

        // Check if there is stack trace
        if (message.contains("STACKTRACE")) {
            //rowClass = "rowStackTrace";
            stackTraceFlag = true;
            // Extract the method name
            //int indx1 = message.indexOf("STACKTRACE");
            //message = message.substring(indx1+1,message.length());
            //indx1 = methodName.indexOf(":");
            //methodName = methodName.substring(indx1 + 1, methodName.length());
        }

        if (startTestFlag) {
            int indx2 = message.lastIndexOf(".");
            String methodName1 = message.substring(indx2 + 1, message.length());

            infoString.append(LINE_SEP + "<div class=\"ui-tabs ui-widget ui-widget-content ui-corner-all\" id=\""
                    + tableId + "\" ALIGN=\"left\" border=\"1\" width=\"100%\">" + LINE_SEP);
            infoString.append(LINE_SEP + "<div class=\"container\" id=\"" + tableId + "container\" name=\""
                    + methodName1 + "\">");
            infoString.append("<div class=\"row\">" + LINE_SEP);
        } else {
            if (stackTraceFlag) {
                infoString.append("<div class=\"" + rowClass + "\" style=\"display:none;\" id=\"" + methodName
                        + "\">" + LINE_SEP);
            } else {
                infoString.append("<div class=\"" + rowClass + "\" style=\"display:none;\">" + LINE_SEP);
            }
        }

        infoString.append("<div class=\"cell1\">");

        // sbuf.append(event.timeStamp - LoggingEvent.getStartTime());
        //infoString.append(tableId);
        // ts = event.timeStamp;
        infoString.append("</div>" + LINE_SEP);

        // String escapedLogger = event.getLoggerName();

        // Check if the message has images's name as well.
        int indx = message.indexOf("^");

        // if (event.getLevel().equals(Level.TRACE)) {
        if (indx > 0) {
            //if(message.contains(""))
            temp = message.substring(indx + 1, message.length());
        } else {
            temp = message;
        }

        // }

        if (message.indexOf(LOG_FLAG) < 0) {
            if (startTestFlag) {
                infoString.append("<div class=\"cell2\">");
                infoString.append(
                        "<input class=\"ui-button ui-widget ui-state-default ui-corner-all buttonStyle\" id=\""
                                + tableId
                                + "showId\" type=\"button\" align=\"right\" value=\"Show Technical Logs\" onclick=\"showLog("
                                + tableId + ")\" />");

                infoString.append(
                        "<input class=\"ui-button ui-widget ui-state-default ui-corner-all buttonStyle\" style=\"display:none;\" id=\""
                                + tableId
                                + "hideId\" type=\"button\" align=\"right\" value=\"Hide Technical Logs\" onclick=\"hideLog("
                                + tableId + ")\" />");

                infoString.append(
                        "<input class=\"ui-button ui-widget ui-state-default ui-corner-all buttonStyle\" id=\""
                                + tableId
                                + "showIdBiz\" type=\"button\" align=\"right\" value=\"Show Business Logs\" onclick=\"showLogBiz("
                                + tableId + ")\" />");

                infoString.append(
                        "<input class=\"ui-button ui-widget ui-state-default ui-corner-all buttonStyle\" style=\"display:none;\" id=\""
                                + tableId
                                + "hideIdBiz\" type=\"button\" align=\"right\" value=\"Hide Business Logs\" onclick=\"hideLogBiz("
                                + tableId + ")\" />");

            } else if (!stackTraceFlag) {
                infoString.append("<div class=\"cell2\">");
                infoString.append("Class: " + message);
            } else if (stackTraceFlag) {
                infoString.append("<div class=\"cell2\">");
                infoString.append(message);
            } else {
                infoString.append("<div class=\"cell2\">");
                infoString.append("<span>Test Method: " + methodName
                        + "<input class=\"ui-button ui-widget ui-state-default ui-corner-all buttonStyle\" id=\""
                        + (tableId + randomId)
                        + "showId\" type=\"button\" align=\"right\" value=\"Show Stacktrace\" onclick=\"showST('"
                        + (tableId + randomId) + "')\" />"
                        + "<input class=\"ui-button ui-widget ui-state-default ui-corner-all buttonStyle\" style=\"display:none;\" id=\""
                        + (tableId + randomId)
                        + "hideId\" type=\"button\" align=\"right\" value=\"Hide Stacktrace\" onclick=\"hideST('"
                        + (tableId + randomId) + "')\" /></span>");
            }
        } else {
            infoString.append("<div class=\"cell2\">");
        }

        if (message.contains(LOG_FLAG)) {
            int flagIndex = message.indexOf(LOG_FLAG);
            message = message.substring(flagIndex + 7, message.length());
        }

        if (indx > 0) {
            infoString.append("<span class=\"spanClass\">Action taken: " + message.substring(0, indx) + "</span>");
        } else {
            if (startTestFlag) {
                infoString.append("<span class=\"spanClass\">Test Name: " + message + "</span>");
            } else if (stackTraceFlag) {
                int tempIndx = message.indexOf("$");
                infoString.append(
                        "<span class=\"spanClassST\" id=\"" + (tableId + randomId) + "ST\">Exception Message: "
                                + message.substring(tempIndx + 1, message.length()) + "</span>");
            } else {
                infoString.append("<span class=\"spanClass\">Action taken: " + message + "</span>");
            }
        }

        if (temp.length() > 0) {
            if (temp.contains(".png")) {
                infoString.append("<img src='../" + SCREENSHOTS_DIR_NAME + temp + "' alt='test'></img>");
            }
        } else {
            infoString.append(temp);
        }
        infoString.append("</div>" + LINE_SEP);
        infoString.append("</div>" + LINE_SEP);

        if (endTestFlag) {
            infoString.append(LINE_SEP + "</div></div>" + LINE_SEP);
            infoString.append("<br>" + LINE_SEP);
            infoString.append("</div></body></html>");
            setInfoString(infoString);
            writeToFile(infoString.toString());
        }
    }

    public void writeToFile(String message) {
        // TODO Use something in org.apache.commons.io.FileUtils which does this..
        if (message.indexOf(END_TEST) > 0) {
            BufferedWriter bufferedWriter = null;
            try {
                bufferedWriter = new BufferedWriter(new FileWriter(getLogFile().getPath(), true));
                bufferedWriter.newLine();
                bufferedWriter.append(message);
            } catch (IOException e) {
                // e.printStackTrace();
            } finally {
                try {
                    if (bufferedWriter != null) {
                        bufferedWriter.flush();
                        bufferedWriter.close();
                    }
                } catch (IOException ex) {
                    // ex.printStackTrace();
                }
            }
        }
    }

    /**
     * This file will create all all the required JavaScript file and CSS file
     * used for the HTML file. These files already exists in the workspace, but
     * we need them in the artifacts of the target build, hence we will have to
     * copy them out.
     */
    private void createAdditionalFiles() {
        String[] files = { "index.html", "jquery-1.4.2.min.js", APPENDED_JS, "jquery-ui-1.8.5.custom.css",
                "style.css", "util.js" };
        for (String fileName : files) {
            File targetFile = new File(reportDirFile, fileName);
            if (!targetFile.exists()) {
                URL sourceFileURL = TestCaseReportWriter.class.getResource(fileName);
                if (sourceFileURL == null) {
                    throw new RuntimeException("Could not find resource on classpath: " + fileName);
                }
                try {
                    FileUtils.copyURLToFile(sourceFileURL, targetFile);
                } catch (IOException e) {
                    throw new RuntimeException("Failed to copy resource from classpath to file: " + fileName, e);
                }
            }
        }
    }

    // ---

    private void addPakageNameToJS(String packageName) throws IOException {
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter(jsFile, true));
            bw.write("packageArray.push(\"" + packageName.toUpperCase() + "\");");
            bw.newLine();
            bw.flush();
        } catch (IOException ioe) {
            // DO Nothing
        } finally { // always close the file
            if (bw != null)
                try {
                    bw.close();
                } catch (IOException ioe2) {
                    // just ignore it
                }
        } // end try/catch/finally
    }

    // package local
    void addTestClassNameToJS(String className) {
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter(jsFile, true));
            bw.write("testClassArray.push(\"" + className + "\");");
            bw.newLine();
            bw.flush();
        } catch (IOException ioe) {
            // DO Nothing
        } finally { // always close the file
            if (bw != null)
                try {
                    bw.close();
                } catch (IOException ioe2) {
                    // just ignore it
                }
        } // end try/catch/finally
    }

    // package local
    String getPackageName(String arg0) {
        int indx = arg0.indexOf("Package Name");
        arg0 = arg0.substring(indx, arg0.length());
        indx = arg0.lastIndexOf(".");

        try {
            addPakageNameToJS(arg0.substring(indx + 1, arg0.length()));
            if (!packageNamesList.contains(arg0.substring(indx + 1, arg0.length()))) {
                packageNamesList.add(arg0.substring(indx + 1, arg0.length()));
            }
        } catch (IOException e) {
            // Ignore (?!)
        }

        return arg0.substring(indx + 1, arg0.length());
    }

    // package local
    void addFailedTestClassNameToJS(String className) {
        BufferedWriter bw = null;
        try {
            bw = new BufferedWriter(new FileWriter(jsFile, true));
            bw.write("failedTestClassArray.push(\"" + className + "\");");
            bw.newLine();
            bw.flush();
        } catch (IOException ioe) {
            // DO Nothing
        } finally { // always close the file
            if (bw != null)
                try {
                    bw.close();
                } catch (IOException ioe2) {
                    // just ignore it
                }
        } // end try/catch/finally
    }

    public void infoWithFlagAndScreenshot(String message, File screenshot) {
        if (screenshot != null) {
            try {
                FileUtils.copyFileToDirectory(screenshot, screenshotsDirFile, true);
            } catch (IOException e) {
                throw new RuntimeException("Oups, WebDriver Report could't copy screenshot file?!", e);
            }

            message = message + "^" + screenshot.getName();
        }
        infoWithFlag(message);
    }
}