diff --git a/pom.xml b/pom.xml index cbf3e5d..78ea751 100644 --- a/pom.xml +++ b/pom.xml @@ -10,7 +10,7 @@ net.masterthought.jenkins cucumber-reports - 0.0.1 + 0.0.2 hpi diff --git a/src/main/java/net/masterthought/jenkins/CucumberReportPublisher.java b/src/main/java/net/masterthought/jenkins/CucumberReportPublisher.java index 0d5cbb4..a316bc2 100644 --- a/src/main/java/net/masterthought/jenkins/CucumberReportPublisher.java +++ b/src/main/java/net/masterthought/jenkins/CucumberReportPublisher.java @@ -20,6 +20,8 @@ import org.kohsuke.stapler.QueryParameter; import javax.servlet.ServletException; import java.io.File; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; public class CucumberReportPublisher extends Recorder { @@ -65,14 +67,12 @@ public class CucumberReportPublisher extends Recorder { } String[] jsonReportFiles = findJsonFiles(targetBuildDirectory); - for (String file : jsonReportFiles) { - listener.getLogger().println("[CucumberReportPublisher] Generating HTML reports based on: " + file); - SingleResultParser singleResultParser = new SingleResultParser(new File(targetBuildDirectory, file).getAbsolutePath(), targetBuildDirectory, pluginUrlPath, buildNumber, buildProject); - try { - singleResultParser.generateReports(); - } catch (Exception e) { - e.printStackTrace(); - } + listener.getLogger().println("[CucumberReportPublisher] Generating HTML reports"); + FeatureReportGenerator featureReportGenerator = new FeatureReportGenerator(fullPathToJsonFiles(jsonReportFiles, targetBuildDirectory), targetBuildDirectory, pluginUrlPath, buildNumber, buildProject); + try { + featureReportGenerator.generateReports(); + } catch (Exception e) { + e.printStackTrace(); } } else { @@ -82,6 +82,14 @@ public class CucumberReportPublisher extends Recorder { build.addAction(new CucumberReportBuildAction(build)); return true; } + + private List fullPathToJsonFiles(String[] jsonFiles, File targetBuildDirectory){ + List fullPathList = new ArrayList(); + for(String file : jsonFiles){ + fullPathList.add(new File(targetBuildDirectory, file).getAbsolutePath()); + } + return fullPathList; + } @Extension public static class DescriptorImpl extends BuildStepDescriptor { diff --git a/src/main/java/net/masterthought/jenkins/SingleResultParser.java b/src/main/java/net/masterthought/jenkins/FeatureReportGenerator.java similarity index 58% rename from src/main/java/net/masterthought/jenkins/SingleResultParser.java rename to src/main/java/net/masterthought/jenkins/FeatureReportGenerator.java index 5a97ccb..0e2e0fe 100644 --- a/src/main/java/net/masterthought/jenkins/SingleResultParser.java +++ b/src/main/java/net/masterthought/jenkins/FeatureReportGenerator.java @@ -13,17 +13,19 @@ import java.io.*; import java.text.SimpleDateFormat; import java.util.*; -public class SingleResultParser { +public class FeatureReportGenerator { - private List featureList; + private Map> jsonResultFiles; private File reportDirectory; private String buildNumber; private String buildProject; private List totalSteps; private String pluginUrlPath; + private List allFeatures; - public SingleResultParser(String jsonResultFile, File reportDirectory, String pluginUrlPath, String buildNumber, String buildProject) throws IOException { - this.featureList = parseJson(jsonResultFile); + public FeatureReportGenerator(List jsonResultFiles, File reportDirectory, String pluginUrlPath, String buildNumber, String buildProject) throws IOException { + this.jsonResultFiles = parseJsonResults(jsonResultFiles); + this.allFeatures = listAllFeatures(); this.totalSteps = getAllStepStatuses(); this.reportDirectory = reportDirectory; this.buildNumber = buildNumber; @@ -31,6 +33,15 @@ public class SingleResultParser { this.pluginUrlPath = getPluginUrlPath(pluginUrlPath); } + private Map> parseJsonResults(List jsonResultFiles) throws FileNotFoundException { + Map> featureResults = new HashMap>(); + for (String jsonFile : jsonResultFiles) { + FileReader reader = new FileReader(jsonFile); + featureResults.put(jsonFile, Arrays.asList(new Gson().fromJson(reader, Feature[].class))); + } + return featureResults; + } + public void generateReports() throws Exception { generateFeatureReports(); generateFeatureOverview(); @@ -43,7 +54,7 @@ public class SingleResultParser { VelocityContext context = new VelocityContext(); context.put("build_project", buildProject); context.put("build_number", buildNumber); - context.put("features", featureList); + context.put("features", allFeatures); context.put("total_features", getTotalFeatures()); context.put("total_scenarios", getTotalScenarios()); context.put("total_steps", getTotalSteps()); @@ -56,28 +67,48 @@ public class SingleResultParser { generateReport("feature-overview.html", featureOverview, context); } - public void generateFeatureReports() throws Exception { - for (Feature feature : featureList) { - VelocityEngine ve = new VelocityEngine(); - ve.init(getProperties()); - Template featureResult = ve.getTemplate("templates/featureReport.vm"); - VelocityContext context = new VelocityContext(); - context.put("feature", feature); - context.put("report_status_colour", getReportStatusColour(feature)); - context.put("build_project", buildProject); - context.put("build_number", buildNumber); - context.put("scenarios", feature.getElements()); - context.put("time_stamp", timeStamp()); - context.put("jenkins_base", pluginUrlPath); - generateReport(feature.getFileName(), featureResult, context); + private List listAllFeatures(){ + List allFeatures = new ArrayList(); + Iterator it = jsonResultFiles.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pairs = (Map.Entry) it.next(); + List featureList = (List) pairs.getValue(); + allFeatures.addAll(featureList); } + return allFeatures; } - - private String getPluginUrlPath(String path){ - return path.isEmpty() ? "/" : path; + public void generateFeatureReports() throws Exception { + + Iterator it = jsonResultFiles.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pairs = (Map.Entry) it.next(); + List featureList = (List) pairs.getValue(); + + for (Feature feature : featureList) { + VelocityEngine ve = new VelocityEngine(); + ve.init(getProperties()); + Template featureResult = ve.getTemplate("templates/featureReport.vm"); + VelocityContext context = new VelocityContext(); + context.put("feature", feature); + context.put("report_status_colour", getReportStatusColour(feature)); + context.put("build_project", buildProject); + context.put("build_number", buildNumber); + context.put("scenarios", feature.getElements()); + context.put("time_stamp", timeStamp()); + context.put("jenkins_base", pluginUrlPath); + generateReport(feature.getFileName(), featureResult, context); + } + } + + } - + + + private String getPluginUrlPath(String path) { + return path.isEmpty() ? "/" : path; + } + private int getTotalSteps() { return totalSteps.size(); } @@ -96,7 +127,7 @@ public class SingleResultParser { private List getAllStepStatuses() { List steps = new ArrayList(); - for (Feature feature : featureList) { + for (Feature feature : allFeatures) { for (Element scenario : feature.getElements()) { for (Step step : scenario.getSteps()) { steps.add(step.getStatus()); @@ -107,12 +138,12 @@ public class SingleResultParser { } private int getTotalFeatures() { - return featureList.size(); + return allFeatures.size(); } private int getTotalScenarios() { int scenarios = 0; - for (Feature feature : featureList) { + for (Feature feature : allFeatures) { scenarios = scenarios + feature.getNumberOfScenarios(); } return scenarios; @@ -136,10 +167,10 @@ public class SingleResultParser { return feature.getStatus() == Util.Status.PASSED ? "#C5D88A" : "#D88A8A"; } - private List parseJson(String jsonResultFile) throws FileNotFoundException { - FileReader reader = new FileReader(jsonResultFile); - return Arrays.asList(new Gson().fromJson(reader, Feature[].class)); - } +// private List parseJson(String jsonResultFile) throws FileNotFoundException { +// FileReader reader = new FileReader(jsonResultFile); +// return Arrays.asList(new Gson().fromJson(reader, Feature[].class)); +// } private String timeStamp() { return new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date()); diff --git a/src/main/java/net/masterthought/jenkins/Runner.java b/src/main/java/net/masterthought/jenkins/Runner.java index a04d108..ff856a7 100644 --- a/src/main/java/net/masterthought/jenkins/Runner.java +++ b/src/main/java/net/masterthought/jenkins/Runner.java @@ -1,15 +1,20 @@ -package net.masterthought.jenkins; - - -import java.io.File; -import java.io.IOException; - -public class Runner { - - public static void main(String[] args) throws Exception { - File rd = new File("/Users/kings/visa/jenkins-plugin-development/jenkins-java-plugin/cucumber-reports/work/jobs/ssss/builds/10/cucumber-html-reports"); - SingleResultParser singleResultParser = new SingleResultParser("/Users/kings/visa/jenkins-plugin-development/jenkins-java-plugin/cucumber-reports/work/jobs/ssss/builds/10/cucumber-html-reports/cucumber.json",rd,"10","ssss"); - singleResultParser.generateReports(); - - } -} +//package net.masterthought.jenkins; +// +// +//import java.io.File; +//import java.util.ArrayList; +//import java.util.List; +// +//public class Runner { +// +// public static void main(String[] args) throws Exception { +// File rd = new File("/Users/kings/.jenkins/jobs/aaaaa/builds/3/cucumber-html-reports"); +// List list = new ArrayList(); +// list.add("/Users/kings/.jenkins/jobs/aaaaa/builds/3/cucumber-html-reports/ss_cucumber.json"); +// list.add("/Users/kings/.jenkins/jobs/aaaaa/builds/3/cucumber-html-reports/co_cucumber.json"); +// +// FeatureReportGenerator featureReportGenerator = new FeatureReportGenerator(list,rd,"","3","aaaa"); +// featureReportGenerator.generateReports(); +// +// } +//} diff --git a/src/main/java/net/masterthought/jenkins/json/Step.java b/src/main/java/net/masterthought/jenkins/json/Step.java index cc3df85..725d3ac 100644 --- a/src/main/java/net/masterthought/jenkins/json/Step.java +++ b/src/main/java/net/masterthought/jenkins/json/Step.java @@ -1,10 +1,14 @@ package net.masterthought.jenkins.json; +import java.util.Arrays; +import java.util.List; + public class Step { private String name; private String keyword; private Result result; + private Row[] rows; public Step(String name, String keyword) { this.name = name; @@ -12,9 +16,46 @@ public class Step { } +// public Row getTitleRow(){ +// return rows[0]; +// } + +// public List getRows(){ +// return Arrays.asList(rows).subList(1, -1); +// } + + public Row[] getRows(){ + return rows; + } + + public boolean hasRows(){ + boolean result = false; + if(rows != null){ + if(rows.length > 0){ + result = true; + } + } + return result; + } + public Util.Status getStatus() { return Util.resultMap.get(result.getStatus()); } + + public String getDataTableClass(){ + String content = ""; + Util.Status status = getStatus(); + if(status == Util.Status.FAILED){ + content = "failed"; + } else if(status == Util.Status.PASSED){ + content = "passed"; + } else if(status == Util.Status.SKIPPED){ + content = "skipped"; + } else { + content = ""; + } + return content; + } public String getName(){ String content = ""; diff --git a/src/main/resources/index.jelly b/src/main/resources/index.jelly index 538998f..c257edd 100644 --- a/src/main/resources/index.jelly +++ b/src/main/resources/index.jelly @@ -2,5 +2,5 @@ This view is used to render the installed plugins page. -->
- This plugin is a sample to explain how to write a Jenkins plugin. + This plugin creates pretty cucumber-jvm html reports on jenkins
diff --git a/src/main/resources/templates/featureReport.vm b/src/main/resources/templates/featureReport.vm index 1cc3f0a..92f2318 100644 --- a/src/main/resources/templates/featureReport.vm +++ b/src/main/resources/templates/featureReport.vm @@ -52,6 +52,39 @@ border-color: gray; background-color: white; -moz-border-radius: ; } + +table.data-table { + color: black; + border-width: 1px; + border-spacing: 2px; + border-style: outset; + border-color: #d6d6d6; + border-collapse: collapse; + background-color: beige; +} +table.data-table th { + color:black; + border-width: 1px; + padding: 5px; + border-style: inset; + border-color: #d6d6d6; + background-color: #66CCEE; +} +table.data-table td { + color:black; + text-align: center; + border-width: 1px; + padding: 5px; + border-style: inset; + border-color: #d6d6d6; + background-color: beige; +} + +.data { + padding-left:50px; + padding-bottom: 10px; + padding-top: 10px; +} @@ -88,6 +121,19 @@ background-color: white; $scenario.getName() #foreach($step in $scenario.getSteps()) $step.getName() + #if($step.hasRows()) +
+ + #foreach($row in $step.getRows()) + + #foreach($cell in $row.getCells()) + + #end + + #end +
$cell
+
+ #end #end #end