diff --git a/cucumber-reports.iml b/cucumber-reports.iml index 0280fb4..7c8f31f 100644 --- a/cucumber-reports.iml +++ b/cucumber-reports.iml @@ -1,10 +1,5 @@ - - - - - @@ -20,6 +15,7 @@ + @@ -87,7 +83,6 @@ - @@ -102,6 +97,7 @@ + diff --git a/src/main/java/net/masterthought/jenkins/ConfigurationOptions.java b/src/main/java/net/masterthought/jenkins/ConfigurationOptions.java new file mode 100644 index 0000000..fcc50bd --- /dev/null +++ b/src/main/java/net/masterthought/jenkins/ConfigurationOptions.java @@ -0,0 +1,28 @@ +package net.masterthought.jenkins; + +public class ConfigurationOptions { + + public static boolean skippedFailsBuildValue; + public static boolean undefinedFailsBuildValue; + + private ConfigurationOptions() { + throw new AssertionError(); + } + + public static void setSkippedFailsBuild(boolean skippedFailsBuild) { + skippedFailsBuildValue = skippedFailsBuild; + } + + public static void setUndefinedFailsBuild(boolean undefinedFailsBuild) { + undefinedFailsBuildValue = undefinedFailsBuild; + } + + public static boolean skippedFailsBuild() { + return skippedFailsBuildValue; + } + + public static boolean undefinedFailsBuild() { + return undefinedFailsBuildValue; + } + +} diff --git a/src/main/java/net/masterthought/jenkins/CucumberReportPublisher.java b/src/main/java/net/masterthought/jenkins/CucumberReportPublisher.java index a316bc2..c02365c 100644 --- a/src/main/java/net/masterthought/jenkins/CucumberReportPublisher.java +++ b/src/main/java/net/masterthought/jenkins/CucumberReportPublisher.java @@ -27,11 +27,15 @@ public class CucumberReportPublisher extends Recorder { public final String jsonReportDirectory; public final String pluginUrlPath; + public final boolean skippedFails; + public final boolean undefinedFails; @DataBoundConstructor - public CucumberReportPublisher(String jsonReportDirectory, String pluginUrlPath) { + public CucumberReportPublisher(String jsonReportDirectory, String pluginUrlPath, boolean skippedFails, boolean undefinedFails) { this.jsonReportDirectory = jsonReportDirectory; this.pluginUrlPath = pluginUrlPath; + this.skippedFails = skippedFails; + this.undefinedFails = undefinedFails; } private String[] findJsonFiles(File targetDirectory) { @@ -60,6 +64,8 @@ public class CucumberReportPublisher extends Recorder { String[] files = findJsonFiles(workspaceJsonReportDirectory); + boolean buildResult = true; + if (files.length != 0) { listener.getLogger().println("[CucumberReportPublisher] copying json to reports directory: " + targetBuildDirectory); for (String file : files) { @@ -68,9 +74,10 @@ public class CucumberReportPublisher extends Recorder { String[] jsonReportFiles = findJsonFiles(targetBuildDirectory); listener.getLogger().println("[CucumberReportPublisher] Generating HTML reports"); - FeatureReportGenerator featureReportGenerator = new FeatureReportGenerator(fullPathToJsonFiles(jsonReportFiles, targetBuildDirectory), targetBuildDirectory, pluginUrlPath, buildNumber, buildProject); + FeatureReportGenerator featureReportGenerator = new FeatureReportGenerator(fullPathToJsonFiles(jsonReportFiles, targetBuildDirectory), targetBuildDirectory, pluginUrlPath, buildNumber, buildProject, skippedFails, undefinedFails); try { featureReportGenerator.generateReports(); + buildResult = featureReportGenerator.getBuildStatus(); } catch (Exception e) { e.printStackTrace(); } @@ -80,7 +87,7 @@ public class CucumberReportPublisher extends Recorder { } build.addAction(new CucumberReportBuildAction(build)); - return true; + return buildResult; } private List fullPathToJsonFiles(String[] jsonFiles, File targetBuildDirectory){ diff --git a/src/main/java/net/masterthought/jenkins/FeatureReportGenerator.java b/src/main/java/net/masterthought/jenkins/FeatureReportGenerator.java index fc197c1..d769a6e 100644 --- a/src/main/java/net/masterthought/jenkins/FeatureReportGenerator.java +++ b/src/main/java/net/masterthought/jenkins/FeatureReportGenerator.java @@ -30,7 +30,9 @@ public class FeatureReportGenerator { private List allTags; private static final String charEncoding = "UTF-8"; - public FeatureReportGenerator(List jsonResultFiles, File reportDirectory, String pluginUrlPath, String buildNumber, String buildProject) throws IOException { + public FeatureReportGenerator(List jsonResultFiles, File reportDirectory, String pluginUrlPath, String buildNumber, String buildProject, boolean skippedFails, boolean undefinedFails) throws IOException { + ConfigurationOptions.setSkippedFailsBuild(skippedFails); + ConfigurationOptions.setUndefinedFailsBuild(undefinedFails); this.jsonResultFiles = parseJsonResults(jsonResultFiles); this.allFeatures = listAllFeatures(); this.totalSteps = getAllStepStatuses(); @@ -41,6 +43,10 @@ public class FeatureReportGenerator { this.allTags = findTagsInFeatures(); } + public boolean getBuildStatus() { + return !(getTotalFails() > 0); + } + private Map> parseJsonResults(List jsonResultFiles) throws IOException { Map> featureResults = new HashMap>(); for (String jsonFile : jsonResultFiles) { @@ -103,7 +109,7 @@ public class FeatureReportGenerator { } public void generateTagReports() throws Exception { - for(TagObject tagObject : allTags) { + for (TagObject tagObject : allTags) { VelocityEngine ve = new VelocityEngine(); ve.init(getProperties()); Template featureResult = ve.getTemplate("templates/tagReport.vm"); @@ -140,7 +146,7 @@ public class FeatureReportGenerator { generateReport("tag-overview.html", featureOverview, context); } - private List findTagsInFeatures() { + private List findTagsInFeatures() { List tagMap = new ArrayList(); for (Feature feature : allFeatures) { List scenarioList = new ArrayList(); @@ -159,18 +165,18 @@ public class FeatureReportGenerator { } } return tagMap; - } - + } + private List addScenarioUnlessExists(List scenarioList, ScenarioTag scenarioTag) { boolean exists = false; - for(ScenarioTag scenario : scenarioList){ - if(scenario.getParentFeatureUri().equalsIgnoreCase(scenarioTag.getParentFeatureUri()) - && scenario.getScenario().getName().equalsIgnoreCase(scenarioTag.getScenario().getName())){ - exists = true; - break; - } + for (ScenarioTag scenario : scenarioList) { + if (scenario.getParentFeatureUri().equalsIgnoreCase(scenarioTag.getParentFeatureUri()) + && scenario.getScenario().getName().equalsIgnoreCase(scenarioTag.getScenario().getName())) { + exists = true; + break; + } } - + if (!exists) { scenarioList.add(scenarioTag); } @@ -181,8 +187,8 @@ public class FeatureReportGenerator { for (String tag : tagList) { boolean exists = false; TagObject tagObj = null; - for(TagObject tagObject : tagMap){ - if(tagObject.getTagName().equalsIgnoreCase(tag)){ + for (TagObject tagObject : tagMap) { + if (tagObject.getTagName().equalsIgnoreCase(tag)) { exists = true; tagObj = tagObject; break; @@ -190,8 +196,8 @@ public class FeatureReportGenerator { } if (exists) { List existingTagList = tagObj.getScenarios(); - for(ScenarioTag scenarioTag : scenarioList){ - existingTagList = addScenarioUnlessExists(existingTagList, scenarioTag); + for (ScenarioTag scenarioTag : scenarioList) { + existingTagList = addScenarioUnlessExists(existingTagList, scenarioTag); } tagMap.remove(tagObj); tagObj.setScenarios(existingTagList); @@ -236,12 +242,12 @@ public class FeatureReportGenerator { } private int getTotalTagSteps() { - int steps = 0; - for(TagObject tag : allTags){ - for(ScenarioTag scenarioTag : tag.getScenarios()){ - steps += scenarioTag.getScenario().getSteps().length; - } - } + int steps = 0; + for (TagObject tag : allTags) { + for (ScenarioTag scenarioTag : tag.getScenarios()) { + steps += scenarioTag.getScenario().getSteps().length; + } + } return steps; } @@ -283,15 +289,15 @@ public class FeatureReportGenerator { private int getTotalTagPasses() { int passes = 0; - for(TagObject tag : allTags){ - passes += tag.getNumberOfPasses(); - } + for (TagObject tag : allTags) { + passes += tag.getNumberOfPasses(); + } return passes; } private int getTotalTagFails() { int failed = 0; - for(TagObject tag : allTags){ + for (TagObject tag : allTags) { failed += tag.getNumberOfFailures(); } return failed; @@ -299,7 +305,7 @@ public class FeatureReportGenerator { private int getTotalTagSkipped() { int skipped = 0; - for(TagObject tag : allTags){ + for (TagObject tag : allTags) { skipped += tag.getNumberOfSkipped(); } return skipped; @@ -320,8 +326,8 @@ public class FeatureReportGenerator { private int getTotalFeatures() { return allFeatures.size(); } - - private int getTotalTags(){ + + private int getTotalTags() { return allTags.size(); } @@ -332,13 +338,13 @@ public class FeatureReportGenerator { } return scenarios; } - - private int getTotalTagScenarios(){ + + private int getTotalTagScenarios() { int scenarios = 0; for (TagObject tag : allTags) { scenarios = scenarios + tag.getScenarios().size(); } - return scenarios; + return scenarios; } private void generateReport(String fileName, Template featureResult, VelocityContext context) throws Exception { diff --git a/src/main/java/net/masterthought/jenkins/Runner.java b/src/main/java/net/masterthought/jenkins/Runner.java index 41368a0..ddcb1d9 100644 --- a/src/main/java/net/masterthought/jenkins/Runner.java +++ b/src/main/java/net/masterthought/jenkins/Runner.java @@ -8,16 +8,18 @@ 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/15/cucumber-html-reports"); + File rd = new File("/Users/kings/.jenkins/jobs/cucumber-jvm/builds/7/cucumber-html-reports"); List list = new ArrayList(); // list.add("/Users/kings/.jenkins/jobs/aaaaa/builds/15/cucumber-html-reports/french.json"); // list.add("/Users/kings/.jenkins/jobs/aaaaa/builds/15/cucumber-html-reports/co_cucumber.json"); // list.add("/Users/kings/.jenkins/jobs/aaaaa/builds/15/cucumber-html-reports/ccp_cucumber.json"); // list.add("/Users/kings/.jenkins/jobs/aaaaa/builds/15/cucumber-html-reports/ss_cucumber.json"); - list.add("/Users/kings/.jenkins/jobs/aaaaa/builds/15/cucumber-html-reports/local.json"); + list.add("/Users/kings/.jenkins/jobs/cucumber-jvm/builds/7/cucumber-html-reports/cucumber.json"); - FeatureReportGenerator featureReportGenerator = new FeatureReportGenerator(list,rd,"","15","aaaaa"); + FeatureReportGenerator featureReportGenerator = new FeatureReportGenerator(list,rd,"","7","cucumber-jvm",true,true); featureReportGenerator.generateReports(); + boolean result = featureReportGenerator.getBuildStatus(); + System.out.println("status: " + result); } } diff --git a/src/main/java/net/masterthought/jenkins/json/Element.java b/src/main/java/net/masterthought/jenkins/json/Element.java index 751753b..b61f85c 100644 --- a/src/main/java/net/masterthought/jenkins/json/Element.java +++ b/src/main/java/net/masterthought/jenkins/json/Element.java @@ -1,5 +1,6 @@ package net.masterthought.jenkins.json; +import net.masterthought.jenkins.ConfigurationOptions; import org.apache.commons.lang.StringUtils; import java.util.ArrayList; @@ -47,15 +48,15 @@ public class Element { return Util.itemExists(contentString) ? Util.result(getStatus()) + StringUtils.join(contentString.toArray(), " ") + Util.closeDiv() : ""; } - public List getTagList(){ + public List getTagList() { return processTags(); } - - public boolean hasTags(){ + + public boolean hasTags() { return Util.itemExists(tags); } - - private List processTags(){ + + private List processTags() { List results = new ArrayList(); if (Util.itemExists(tags)) { StringClosure scenarioTags = new StringClosure() { @@ -63,11 +64,11 @@ public class Element { return tag.getName(); } }; - results = Util.collectTags(tags, scenarioTags); - } + results = Util.collectTags(tags, scenarioTags); + } return results; } - + public String getTags() { String result = "
"; if (Util.itemExists(tags)) { diff --git a/src/main/java/net/masterthought/jenkins/json/Feature.java b/src/main/java/net/masterthought/jenkins/json/Feature.java index 954269c..292cb3f 100644 --- a/src/main/java/net/masterthought/jenkins/json/Feature.java +++ b/src/main/java/net/masterthought/jenkins/json/Feature.java @@ -93,12 +93,12 @@ public class Feature { public String getFileName() { List matches = new ArrayList(); for (String line : Splitter.onPattern("/|\\\\").split(uri)) { - String modified = line.replaceAll("\\)|\\(",""); + String modified = line.replaceAll("\\)|\\(", ""); modified = StringUtils.deleteWhitespace(modified).trim(); matches.add(modified); } - matches = matches.subList(1,matches.size()); + matches = matches.subList(1, matches.size()); String fileName = Joiner.on("-").join(matches) + ".html"; return fileName; } diff --git a/src/main/java/net/masterthought/jenkins/json/Step.java b/src/main/java/net/masterthought/jenkins/json/Step.java index e8ffc77..df96701 100644 --- a/src/main/java/net/masterthought/jenkins/json/Step.java +++ b/src/main/java/net/masterthought/jenkins/json/Step.java @@ -1,5 +1,7 @@ package net.masterthought.jenkins.json; +import net.masterthought.jenkins.ConfigurationOptions; + import java.util.Arrays; import java.util.List; @@ -15,48 +17,80 @@ public class Step { this.keyword = keyword; } - - public Row[] getRows(){ + + public Row[] getRows() { return rows; } - public boolean hasRows(){ - boolean result = false; - if(rows != null){ - if(rows.length > 0){ - result = true; - } - } + public boolean hasRows() { + boolean result = false; + if (rows != null) { + if (rows.length > 0) { + result = true; + } + } return result; } - - public Long getDuration(){ + + public Long getDuration() { return result.getDuration(); } - - public Util.Status getStatus() { + + private Util.Status getInternalStatus() { 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 = ""; + + public Util.Status getStatus() { +// return Util.resultMap.get(result.getStatus()); + + Util.Status status = getInternalStatus(); + Util.Status result = status; + + if (ConfigurationOptions.skippedFailsBuild()) { + if (status == Util.Status.SKIPPED || status == Util.Status.FAILED) { + result = Util.Status.FAILED; + } } - return content; + + if (ConfigurationOptions.undefinedFailsBuild()) { + if (status == Util.Status.UNDEFINED || status == Util.Status.FAILED) { + result = Util.Status.FAILED; + } + } + + if (status == Util.Status.FAILED) { + result = Util.Status.FAILED; + } + return result; + } - public String getName(){ + public String getDataTableClass() { String content = ""; - if(getStatus() == Util.Status.FAILED){ - content = Util.result(getStatus()) + "" + keyword + " " + name + "" + "
" + result.getErrorMessage() + "
" + Util.closeDiv(); + 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 = ""; + if (getStatus() == Util.Status.FAILED) { + String errorMessage = result.getErrorMessage(); + if (getInternalStatus() == Util.Status.SKIPPED) { + errorMessage = "Mode: Skipped causes Failure
This step was skipped"; + } + if (getInternalStatus() == Util.Status.UNDEFINED) { + errorMessage = "Mode: Not Implemented causes Failure
This step is not yet implemented"; + } + content = Util.result(getStatus()) + "" + keyword + " " + name + "" + "
" + errorMessage + "
" + Util.closeDiv(); } else { content = Util.result(getStatus()) + "" + keyword + " " + name + "" + Util.closeDiv(); } diff --git a/src/main/resources/net/masterthought/jenkins/CucumberReportPublisher/config.jelly b/src/main/resources/net/masterthought/jenkins/CucumberReportPublisher/config.jelly index a581f06..b32a662 100644 --- a/src/main/resources/net/masterthought/jenkins/CucumberReportPublisher/config.jelly +++ b/src/main/resources/net/masterthought/jenkins/CucumberReportPublisher/config.jelly @@ -12,8 +12,17 @@ + + + + + + + + + diff --git a/velocity.log b/velocity.log index fc41171..2c8ccdf 100644 --- a/velocity.log +++ b/velocity.log @@ -1,28 +1,28 @@ -Fri May 25 15:35:24 BST 2012 [debug] AvalonLogChute initialized using file 'velocity.log' -Fri May 25 15:35:24 BST 2012 [trace] ******************************************************************* -Fri May 25 15:35:24 BST 2012 [debug] Starting Jakarta Velocity v1.5-SNAPSHOT (compiled: 2006-07-21 06:25:35) -Fri May 25 15:35:24 BST 2012 [trace] RuntimeInstance initializing. -Fri May 25 15:35:24 BST 2012 [debug] Default Properties File: org/apache/velocity/runtime/defaults/velocity.properties -Fri May 25 15:35:24 BST 2012 [debug] Trying to use logger class org.apache.velocity.runtime.log.AvalonLogChute -Fri May 25 15:35:24 BST 2012 [debug] Using logger class org.apache.velocity.runtime.log.AvalonLogChute -Fri May 25 15:35:24 BST 2012 [debug] Default ResourceManager initializing. (class org.apache.velocity.runtime.resource.ResourceManagerImpl) -Fri May 25 15:35:24 BST 2012 [debug] ResourceLoader instantiated: org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader -Fri May 25 15:35:24 BST 2012 [trace] ClasspathResourceLoader : initialization complete. -Fri May 25 15:35:24 BST 2012 [debug] ResourceCache: initialized (class org.apache.velocity.runtime.resource.ResourceCacheImpl) -Fri May 25 15:35:24 BST 2012 [trace] Default ResourceManager initialization complete. -Fri May 25 15:35:24 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Literal -Fri May 25 15:35:24 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Macro -Fri May 25 15:35:24 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Parse -Fri May 25 15:35:24 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Include -Fri May 25 15:35:24 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Foreach -Fri May 25 15:35:24 BST 2012 [debug] Created '20' parsers. -Fri May 25 15:35:24 BST 2012 [trace] Velocimacro : initialization starting. -Fri May 25 15:35:24 BST 2012 [debug] Velocimacro : "velocimacro.library" is not set. Trying default library: VM_global_library.vm -Fri May 25 15:35:24 BST 2012 [debug] Velocimacro : Default library not found. -Fri May 25 15:35:24 BST 2012 [debug] Velocimacro : allowInline = true : VMs can be defined inline in templates -Fri May 25 15:35:24 BST 2012 [debug] Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions -Fri May 25 15:35:24 BST 2012 [debug] Velocimacro : allowInlineLocal = false : VMs defined inline will be global in scope if allowed. -Fri May 25 15:35:24 BST 2012 [debug] Velocimacro : autoload off : VM system will not automatically reload global library macros -Fri May 25 15:35:24 BST 2012 [trace] Velocimacro : initialization complete. -Fri May 25 15:35:24 BST 2012 [trace] RuntimeInstance successfully initialized. -Fri May 25 15:35:24 BST 2012 [debug] ResourceManager : found templates/tagOverview.vm with loader org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader +Fri May 25 22:39:04 BST 2012 [debug] AvalonLogChute initialized using file 'velocity.log' +Fri May 25 22:39:04 BST 2012 [trace] ******************************************************************* +Fri May 25 22:39:04 BST 2012 [debug] Starting Jakarta Velocity v1.5-SNAPSHOT (compiled: 2006-07-21 06:25:35) +Fri May 25 22:39:04 BST 2012 [trace] RuntimeInstance initializing. +Fri May 25 22:39:04 BST 2012 [debug] Default Properties File: org/apache/velocity/runtime/defaults/velocity.properties +Fri May 25 22:39:04 BST 2012 [debug] Trying to use logger class org.apache.velocity.runtime.log.AvalonLogChute +Fri May 25 22:39:04 BST 2012 [debug] Using logger class org.apache.velocity.runtime.log.AvalonLogChute +Fri May 25 22:39:04 BST 2012 [debug] Default ResourceManager initializing. (class org.apache.velocity.runtime.resource.ResourceManagerImpl) +Fri May 25 22:39:04 BST 2012 [debug] ResourceLoader instantiated: org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader +Fri May 25 22:39:04 BST 2012 [trace] ClasspathResourceLoader : initialization complete. +Fri May 25 22:39:04 BST 2012 [debug] ResourceCache: initialized (class org.apache.velocity.runtime.resource.ResourceCacheImpl) +Fri May 25 22:39:04 BST 2012 [trace] Default ResourceManager initialization complete. +Fri May 25 22:39:04 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Literal +Fri May 25 22:39:04 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Macro +Fri May 25 22:39:04 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Parse +Fri May 25 22:39:04 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Include +Fri May 25 22:39:04 BST 2012 [debug] Loaded System Directive: org.apache.velocity.runtime.directive.Foreach +Fri May 25 22:39:04 BST 2012 [debug] Created '20' parsers. +Fri May 25 22:39:04 BST 2012 [trace] Velocimacro : initialization starting. +Fri May 25 22:39:04 BST 2012 [debug] Velocimacro : "velocimacro.library" is not set. Trying default library: VM_global_library.vm +Fri May 25 22:39:04 BST 2012 [debug] Velocimacro : Default library not found. +Fri May 25 22:39:04 BST 2012 [debug] Velocimacro : allowInline = true : VMs can be defined inline in templates +Fri May 25 22:39:04 BST 2012 [debug] Velocimacro : allowInlineToOverride = false : VMs defined inline may NOT replace previous VM definitions +Fri May 25 22:39:04 BST 2012 [debug] Velocimacro : allowInlineLocal = false : VMs defined inline will be global in scope if allowed. +Fri May 25 22:39:04 BST 2012 [debug] Velocimacro : autoload off : VM system will not automatically reload global library macros +Fri May 25 22:39:04 BST 2012 [trace] Velocimacro : initialization complete. +Fri May 25 22:39:04 BST 2012 [trace] RuntimeInstance successfully initialized. +Fri May 25 22:39:04 BST 2012 [debug] ResourceManager : found templates/tagOverview.vm with loader org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader