package com.aventstack.extentreports.reporter;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.InvalidFileException;
import com.aventstack.extentreports.Status;
import com.aventstack.extentreports.configuration.Config;
import com.aventstack.extentreports.configuration.ConfigMap;
import com.aventstack.extentreports.model.ScreenCapture;
import com.aventstack.extentreports.model.Test;
import com.aventstack.extentreports.reporter.configuration.ExtentHtmlReporterConfiguration;
import com.aventstack.extentreports.reporter.converters.ExtentHtmlReporterConverter;
import com.aventstack.extentreports.utils.Writer;
import com.aventstack.extentreports.viewdefs.Icon;
import freemarker.ext.beans.BeansWrapper;
import freemarker.ext.beans.BeansWrapperBuilder;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModelException;
/**
* The ExtentHtmlReporter creates a rich standalone HTML file. It allows several configuration options
* via the <code>config()</code> method.
*/
public class ExtentHtmlReporter extends BasicFileReporter implements ReportAppendable {
private static final Logger logger = Logger.getLogger(ExtentHtmlReporter.class.getName());
private static final String TEMPLATE_LOCATION = "view/html-report";
private static final String TEMPLATE_NAME = "index.ftl";
private static final String DEFAULT_CONFIG_FILE = "html-config.properties";
private static String ENCODING = "UTF-8";
private Boolean appendExisting = false;
private List<Test> parsedTestCollection;
private ExtentHtmlReporterConfiguration userConfig;
ExtentHtmlReporter() {
// Required to parse the start and end times in the HTML report.
Locale.setDefault(Locale.ENGLISH);
loadDefaultConfig();
}
public ExtentHtmlReporter(String filePath) {
this();
this.filePath = filePath;
config().setFilePath(filePath);
}
public ExtentHtmlReporter(File file) {
this(file.getAbsolutePath());
}
private void loadDefaultConfig() {
configContext = new ConfigMap();
userConfig = new ExtentHtmlReporterConfiguration();
ClassLoader loader = getClass().getClassLoader();
InputStream is = loader.getResourceAsStream(DEFAULT_CONFIG_FILE);
loadConfig(is);
}
public ExtentHtmlReporterConfiguration config() {
return userConfig;
}
@Override
public void start() {
if (templateMap != null) {
return;
}
templateMap = new HashMap<String, Object>();
templateMap.put("report", this);
templateMap.put("Icon", new Icon());
BeansWrapperBuilder builder = new BeansWrapperBuilder(Configuration.VERSION_2_3_23);
BeansWrapper beansWrapper = builder.build();
try {
TemplateHashModel fieldTypeModel = (TemplateHashModel)beansWrapper.getEnumModels().get(Status.class.getName());
templateMap.put("Status", fieldTypeModel);
}
catch (TemplateModelException e) {
logger.log(Level.SEVERE, "", e);
}
if (appendExisting && filePath != null)
parseReportBuildTestCollection();
}
private void parseReportBuildTestCollection() {
File f = new File(filePath);
if (!f.exists())
return;
ExtentHtmlReporterConverter converter = new ExtentHtmlReporterConverter(filePath);
parsedTestCollection = converter.parseAndGetModelCollection();
}
@Override
public synchronized void flush() {
if (testList == null || testList.size() == 0)
return;
try {
loadUserConfig();
} catch (InvalidFileException e) {
logger.log(Level.SEVERE, "", e);
return;
}
if (parsedTestCollection != null && parsedTestCollection.size() > 0)
for (int ix = 0; ix < parsedTestCollection.size(); ix++)
testList.add(ix, parsedTestCollection.get(ix));
parsedTestCollection = null;
String extentSource = null;
try {
Template template = getConfig().getTemplate(TEMPLATE_NAME);
StringWriter out = new StringWriter();
template.process(templateMap, out);
extentSource = out.toString();
out.close();
}
catch (IOException | TemplateException e) {
logger.log(Level.SEVERE, "Template not found", e);
}
Writer.getInstance().write(new File(filePath), extentSource);
}
private void loadUserConfig() throws InvalidFileException {
String filePath = userConfig.getConfigMap().get("filePath");
if (filePath == null && this.filePath == null)
throw new InvalidFileException("No file specified.");
userConfig.setFilePath(this.filePath);
userConfig.getConfigMap().forEach(
(k, v) -> {
if (v != null) {
Config c = new Config();
c.setKey(k);
c.setValue(v);
configContext.setConfig(c);
}
}
);
}
private Configuration getConfig() {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_22);
cfg.setClassForTemplateLoading(ExtentReports.class, TEMPLATE_LOCATION);
cfg.setDefaultEncoding(ENCODING);
return cfg;
}
@Override
public void onScreenCaptureAdded(Test test, ScreenCapture screenCapture) throws IOException { }
@Override
public void setTestList(List<Test> reportTestList) {
testList = reportTestList;
}
public List<Test> getTestList() {
if (testList == null)
testList = new ArrayList<>();
return testList;
}
public boolean containsStatus(Status status) {
boolean b = statusCollection == null || statusCollection.isEmpty() ? false : statusCollection.contains(status);
return b;
}
public ConfigMap getConfigContext() {
return configContext;
}
@Override
public void setAppendExisting(Boolean b) {
this.appendExisting = b;
}
}