diff --git a/CHANGELOG.md b/CHANGELOG.md index 167b7211..2608d0aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. Back to [Readme](README.md). +## [2.6.0] - 2020-11-27 + +### Fixed +* Fixed HTML encoding for attachments (#263) + +### Added +* Background steps are now displayed in a separate section of the report + +### Changed +* Only hooks with outputs are considered and displayed in the scenario detail pages (#211) +* Various design cleanups + ## [2.5.0] - 2020-05-11 ### Added diff --git a/example-project/pom.xml b/example-project/pom.xml index ceeeecf1..3f20f4cc 100644 --- a/example-project/pom.xml +++ b/example-project/pom.xml @@ -6,7 +6,7 @@ de.benjamin-bischoff cluecumber-test-project - 2.5.0 + 2.6.0 pom @@ -34,7 +34,7 @@ - ${cucumber.report.json.location}/TEST.json + ${cucumber.report.json.location} ${generated.report.location} diff --git a/plugin-code/pom.xml b/plugin-code/pom.xml index 355e469c..bec000ac 100644 --- a/plugin-code/pom.xml +++ b/plugin-code/pom.xml @@ -6,7 +6,7 @@ com.trivago.rta cluecumber-report-plugin - 2.5.0 + 2.6.0 https://github.com/trivago/cluecumber-report-plugin Cluecumber Maven Plugin for Cucumber Reports @@ -80,9 +80,10 @@ 3.6.0 2.4 3.3.0 + 0.8.4 - 3.3.3 - 5.7.0-M1 + 3.6.28 + 5.7.0 0.8.13 2.8.6 @@ -141,7 +142,7 @@ org.jacoco jacoco-maven-plugin - 0.8.4 + ${jacoco.version} diff --git a/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/Element.java b/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/Element.java index 67cc9a09..ac213eb2 100644 --- a/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/Element.java +++ b/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/Element.java @@ -36,6 +36,7 @@ public class Element { private List after = new ArrayList<>(); private String type = ""; private String keyword = ""; + private List backgroundSteps = new ArrayList<>(); private List steps = new ArrayList<>(); private List tags = new ArrayList<>(); @SerializedName("start_timestamp") @@ -98,6 +99,15 @@ public void setBefore(final List before) { this.before = before; } + public boolean anyBeforeHookHasContent() { + for (ResultMatch resultMatch : before) { + if (resultMatch.hasContent()) { + return true; + } + } + return false; + } + public int getLine() { return line; } @@ -138,6 +148,15 @@ public void setAfter(final List after) { this.after = after; } + public boolean anyAfterHookHasContent() { + for (ResultMatch resultMatch : before) { + if (resultMatch.hasContent()) { + return true; + } + } + return false; + } + public String getType() { return type; } @@ -162,6 +181,14 @@ public void setSteps(final List steps) { this.steps = steps; } + public List getBackgroundSteps() { + return backgroundSteps; + } + + public void setBackgroundSteps(final List steps) { + this.backgroundSteps = steps; + } + public boolean isScenario() { return type.equals("scenario"); } @@ -278,6 +305,7 @@ private int getNumberOfStepsWithStatus(final Status status) { public long getTotalDuration() { long totalDurationNanoseconds = before.stream().mapToLong(beforeStep -> beforeStep.getResult().getDuration()).sum(); + totalDurationNanoseconds += backgroundSteps.stream().mapToLong(Step::getTotalDuration).sum(); totalDurationNanoseconds += steps.stream().mapToLong(Step::getTotalDuration).sum(); totalDurationNanoseconds += after.stream().mapToLong(afterStep -> afterStep.getResult().getDuration()).sum(); return totalDurationNanoseconds; @@ -292,6 +320,11 @@ public boolean hasHooks() { } public boolean hasDocStrings() { + for (Step step : backgroundSteps) { + if (step.getDocString() != null) { + return true; + } + } for (Step step : steps) { if (step.getDocString() != null) { return true; @@ -301,6 +334,14 @@ public boolean hasDocStrings() { } public boolean hasStepHooks() { + for (Step step : backgroundSteps) { + if (step.getBefore().size() > 0) { + return true; + } + if (step.getAfter().size() > 0) { + return true; + } + } for (Step step : steps) { if (step.getBefore().size() > 0) { return true; @@ -314,6 +355,7 @@ public boolean hasStepHooks() { public List getAllResultMatches() { List resultMatches = new ArrayList<>(getBefore()); + resultMatches.addAll(getBackgroundSteps()); resultMatches.addAll(getSteps()); resultMatches.addAll(getAfter()); return resultMatches; diff --git a/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/Embedding.java b/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/Embedding.java index 5cdfa58a..ae6848d6 100644 --- a/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/Embedding.java +++ b/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/Embedding.java @@ -50,7 +50,9 @@ public void decodeData(final String data) { decodedData = new String(Base64.decodeBase64(data.getBytes(StandardCharsets.UTF_8)), StandardCharsets.UTF_8); switch (mimeType) { case HTML: - decodedData = decodedData.replaceAll("\"", "'"); + decodedData = decodedData.replaceAll("\"", "'") + .replaceAll("&", "&") + .replaceAll("\"", """); break; case XML: case APPLICATION_XML: @@ -92,12 +94,12 @@ public void setFilename(final String filename) { public boolean isImage() { return mimeType == MimeType.PNG || - mimeType == MimeType.GIF || - mimeType == MimeType.BMP || - mimeType == MimeType.JPEG || - mimeType == MimeType.JPG || - mimeType == MimeType.SVG || - mimeType == MimeType.SVG_XML; + mimeType == MimeType.GIF || + mimeType == MimeType.BMP || + mimeType == MimeType.JPEG || + mimeType == MimeType.JPG || + mimeType == MimeType.SVG || + mimeType == MimeType.SVG_XML; } public boolean isPlainText() { diff --git a/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/ResultMatch.java b/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/ResultMatch.java index c39ec3b0..0793be85 100644 --- a/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/ResultMatch.java +++ b/plugin-code/src/main/java/com/trivago/cluecumber/json/pojo/ResultMatch.java @@ -52,6 +52,10 @@ public void setEmbeddings(final List embeddings) { this.embeddings = embeddings; } + public boolean hasEmbeddings() { + return embeddings.size() > 0; + } + public List getOutput() { return output; } @@ -96,6 +100,10 @@ public boolean isSkipped() { return getConsolidatedStatus() == Status.SKIPPED; } + public boolean hasContent() { + return hasOutputs() || hasEmbeddings(); + } + public Status getConsolidatedStatus() { switch (getStatus()) { case PASSED: diff --git a/plugin-code/src/main/java/com/trivago/cluecumber/json/processors/ReportJsonPostProcessor.java b/plugin-code/src/main/java/com/trivago/cluecumber/json/processors/ReportJsonPostProcessor.java index 6c1ccdcb..f596f1b5 100644 --- a/plugin-code/src/main/java/com/trivago/cluecumber/json/processors/ReportJsonPostProcessor.java +++ b/plugin-code/src/main/java/com/trivago/cluecumber/json/processors/ReportJsonPostProcessor.java @@ -20,6 +20,7 @@ import com.google.gson.JsonElement; import com.trivago.cluecumber.json.pojo.Element; import com.trivago.cluecumber.json.pojo.Report; +import com.trivago.cluecumber.json.pojo.Step; import com.trivago.cluecumber.json.pojo.Tag; import io.gsonfire.PostProcessor; @@ -66,19 +67,19 @@ private void addFeatureInformationToScenarios(final Report report) { } private void mergeBackgroundScenarios(final Report report) { - List cleanedUpElements = new ArrayList<>(); - Element currentBackgroundElement = null; + List updatedElements = new ArrayList<>(); + List currentBackgroundSteps = null; for (Element element : report.getElements()) { if (element.getType().equalsIgnoreCase("background")) { - currentBackgroundElement = element; + currentBackgroundSteps = element.getSteps(); } else { - if (currentBackgroundElement != null) { - element.getSteps().addAll(0, currentBackgroundElement.getSteps()); + if (currentBackgroundSteps != null) { + element.setBackgroundSteps(currentBackgroundSteps); } - cleanedUpElements.add(element); + updatedElements.add(element); } } - report.setElements(cleanedUpElements); + report.setElements(updatedElements); } private void addFeatureIndex(final Report report) { diff --git a/plugin-code/src/main/resources/template/css/cluecumber.css b/plugin-code/src/main/resources/template/css/cluecumber.css index 47bf756c..125c6271 100644 --- a/plugin-code/src/main/resources/template/css/cluecumber.css +++ b/plugin-code/src/main/resources/template/css/cluecumber.css @@ -87,10 +87,18 @@ pre { padding: 1rem; } +.list-group { + margin-bottom: auto; +} + .list-group-item .row:hover { background-color: rgba(0, 0, 0, .075); } +.list-group-flush .list-group-item:last-child { + margin-bottom: 0; +} + div.tooltip-inner { max-width: 100%; white-space: nowrap; @@ -188,15 +196,14 @@ iframe { button.btn { white-space: inherit; -} - -.btn.focus { - outline: none; + border: gainsboro 1px solid; box-shadow: none; } -.btn-outline-secondary, .btn-outline-secondary.focus, .btn-outline-secondary:focus { - border: none; +.btn-outline-secondary.active:focus, +.btn-outline-secondary:focus, +.btn-outline-secondary:active:focus { + outline: 0; box-shadow: none; } diff --git a/plugin-code/src/main/resources/template/macros/scenario.ftl b/plugin-code/src/main/resources/template/macros/scenario.ftl index edff86f5..3e6961cf 100644 --- a/plugin-code/src/main/resources/template/macros/scenario.ftl +++ b/plugin-code/src/main/resources/template/macros/scenario.ftl @@ -180,22 +180,24 @@ limitations under the License. <#macro stepHooks hooks> <#list hooks as hook> -
-
-
-
- ${hook.glueMethodName} -
-
- ${hook.result.returnDurationString()} -
-
- <@common.status status=hook.consolidatedStatusString/> + <#if hook.hasContent()> +
+
+
+
+ ${hook.glueMethodName} +
+
+ ${hook.result.returnDurationString()} +
+
+ <@common.status status=hook.consolidatedStatusString/> +
+ <@scenario.errorMessage step=hook/> + <@scenario.output step=hook/> + <@scenario.attachments step=hook/>
- <@scenario.errorMessage step=hook/> - <@scenario.output step=hook/> - <@scenario.attachments step=hook/>
-
+ diff --git a/plugin-code/src/main/resources/template/scenario-detail.ftl b/plugin-code/src/main/resources/template/scenario-detail.ftl index b38ebc6a..87572b79 100644 --- a/plugin-code/src/main/resources/template/scenario-detail.ftl +++ b/plugin-code/src/main/resources/template/scenario-detail.ftl @@ -59,47 +59,106 @@ preheadlineLink="pages/feature-scenarios/feature_${element.featureIndex?c}.html" ${element.totalNumberOfSkippedSteps} skipped <@common.status status="skipped"/> - <#if element.hasHooks()> + <#if element.hasHooks() && (element.anyBeforeHookHasContent() || element.anyAfterHookHasContent())> <#if element.hasStepHooks()> <#if element.hasDocStrings()>