Skip to content

Commit

Permalink
Merge pull request #322 from trivago/allow-marking-rerun-tests
Browse files Browse the repository at this point in the history
Add information about multiple runs
  • Loading branch information
gdonati78 authored Nov 2, 2023
2 parents 617f12f + c2646d2 commit ca8b1fe
Show file tree
Hide file tree
Showing 26 changed files with 619 additions and 46 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

Back to [Readme](README.md).

## [3.5.0] - 2023-11-02

### Added
* `groupPreviousScenarioRuns` mode for a compact view when there are multiple runs of the same scenario [#245]
* `expandPreviousScenarioRuns` to set default state of expanded or collapsed of the previous runs of the same scenario

## [3.4.0] - 2023-08-10

### Fixed
Expand Down Expand Up @@ -762,6 +768,7 @@ steps with status `pending` or `undefined` (default value is `false`) (#74)

Initial project version on GitHub and Maven Central.

[3.5.0]: https://github.com/trivago/cluecumber-report-plugin/tree/3.5.0
[3.4.0]: https://github.com/trivago/cluecumber-report-plugin/tree/3.4.0
[3.3.1]: https://github.com/trivago/cluecumber-report-plugin/tree/3.3.1
[3.3.0]: https://github.com/trivago/cluecumber-report-plugin/tree/3.3.0
Expand Down
28 changes: 27 additions & 1 deletion core/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ _Clear and concise JVM reporting for the Cucumber BDD JSON format_
<dependency>
<groupId>com.trivago.rta</groupId>
<artifactId>cluecumber-core</artifactId>
<version>3.4.0</version>
<version>3.5.0</version>
</dependency>
```

Expand Down Expand Up @@ -241,6 +241,18 @@ new CluecumberCore.Builder()
.build().generateReports(jsonDirectory, reportDirectory);
```

## Auto-expand Previous Scenario Runs

The `expandPreviousScenarioRuns` option can be set to `true` to expand or collapse previous runs children element of the same scenario
(on all scenarios page only, if `groupPreviousScenarioRuns` mode active).

```java
new CluecumberCore.Builder()
.setGroupPreviousScenarioRuns(true)
.setExpandPreviousScenarioRuns(true)
.build().generateReports(jsonDirectory, reportDirectory);
```

## Auto-expand Attachments

By default, attachments are collapsed and can be toggled individually. If the `expandAttachments` options is set
Expand Down Expand Up @@ -348,6 +360,20 @@ The result of this customization is:
|---|---|
| ![Chart Before](../documentation/img/chart_before.png) | ![Chart After](../documentation/img/chart_after.png) |

## Enabling a compact view of multiple runs of the same scenarios

It is possible to group multiple runs of the same scenario, especially useful for cases like reruns.
Enabling the feature will list the "children" elements (previous runs) on the "All scenarios" page
as nested elements of the last run of that specific scenario.
The grouping is based on scenario `id` + scenario `line`
A button allows to expand/collapse, the default state can be set via `expandPreviousScenarioRuns`.

```java
new CluecumberCore.Builder()
.setGroupPreviousScenarioRuns(true)
.setExpandPreviousScenarioRuns(false)
.build().generateReports(jsonDirectory, reportDirectory);
```

# Appendix

Expand Down
4 changes: 2 additions & 2 deletions core/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
<modelVersion>4.0.0</modelVersion>

<artifactId>cluecumber-core</artifactId>
<version>3.4.0</version>
<version>3.5.0</version>
<packaging>jar</packaging>

<parent>
<artifactId>cluecumber-parent</artifactId>
<groupId>com.trivago.rta</groupId>
<version>3.4.0</version>
<version>3.5.0</version>
</parent>

<name>Cluecumber Core</name>
Expand Down
26 changes: 26 additions & 0 deletions core/src/main/java/com/trivago/cluecumber/core/CluecumberCore.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ private CluecumberCore(Builder builder) throws CluecumberException {
cluecumberEngine.setExpandBeforeAfterHooks(builder.expandBeforeAfterHooks);
cluecumberEngine.setExpandDocStrings(builder.expandDocStrings);
cluecumberEngine.setExpandStepHooks(builder.expandStepHooks);
cluecumberEngine.setGroupPreviousScenarioRuns(builder.groupPreviousScenarioRuns);
cluecumberEngine.setExpandPreviousScenarioRuns(builder.expandPreviousScenarioRuns);
cluecumberEngine.setFailScenariosOnPendingOrUndefinedSteps(builder.failScenariosOnPendingOrUndefinedSteps);
cluecumberEngine.setLogLevel(builder.logLevel);
cluecumberEngine.setStartPage(builder.startPage);
Expand Down Expand Up @@ -78,6 +80,8 @@ public static class Builder {
private boolean expandBeforeAfterHooks;
private boolean expandDocStrings;
private boolean expandStepHooks;
private boolean groupPreviousScenarioRuns;
private boolean expandPreviousScenarioRuns;
private String logLevel;
private String startPage;
private boolean failScenariosOnPendingOrUndefinedSteps;
Expand Down Expand Up @@ -226,6 +230,28 @@ public Builder setExpandStepHooks(final boolean expandStepHooks) {
return this;
}

/**
* Whether to show the scenarios run multiple times should be grouped and the show not last run toggle should be shown.
*
* @param groupPreviousScenarioRuns If true, the scenarios run multiple times should be grouped and the show not last run toggle should be shown.
* @return The {@link Builder}.
*/
public Builder setGroupPreviousScenarioRuns(final boolean groupPreviousScenarioRuns) {
this.groupPreviousScenarioRuns = groupPreviousScenarioRuns;
return this;
}

/**
* Whether to expand elements that are not last run.
*
* @param expandPreviousScenarioRuns If true, elements that are not last run will be expanded.
* @return The {@link Builder}.
*/
public Builder setExpandPreviousScenarioRuns(final boolean expandPreviousScenarioRuns) {
this.expandPreviousScenarioRuns = expandPreviousScenarioRuns;
return this;
}

/**
* Set the log level for Cluecumber logs.
*
Expand Down
4 changes: 2 additions & 2 deletions engine/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
<parent>
<artifactId>cluecumber-parent</artifactId>
<groupId>com.trivago.rta</groupId>
<version>3.4.0</version>
<version>3.5.0</version>
</parent>

<artifactId>cluecumber-engine</artifactId>
<version>3.4.0</version>
<version>3.5.0</version>
<packaging>jar</packaging>

<name>Cluecumber Engine</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import com.trivago.cluecumber.engine.json.JsonPojoConverter;
import com.trivago.cluecumber.engine.json.pojo.Report;
import com.trivago.cluecumber.engine.json.processors.ElementIndexPreProcessor;
import com.trivago.cluecumber.engine.json.processors.ElementMultipleRunsPreProcessor;
import com.trivago.cluecumber.engine.logging.CluecumberLogger;
import com.trivago.cluecumber.engine.properties.PropertyManager;
import com.trivago.cluecumber.engine.rendering.ReportGenerator;
Expand All @@ -50,6 +51,7 @@ public final class CluecumberEngine {
private final FileIO fileIO;
private final JsonPojoConverter jsonPojoConverter;
private final ElementIndexPreProcessor elementIndexPreProcessor;
private final ElementMultipleRunsPreProcessor elementMultipleRunsPreProcessor;
private final ReportGenerator reportGenerator;

/**
Expand All @@ -62,6 +64,7 @@ public final class CluecumberEngine {
* Constructor for dependency injection.
*
* @param elementIndexPreProcessor The {@link ElementIndexPreProcessor} instance.
* @param elementMultipleRunsPreProcessor The {@link ElementMultipleRunsPreProcessor} instance.
* @param fileIO The {@link FileIO} instance.
* @param fileSystemManager The {@link FileSystemManager} instance.
* @param jsonPojoConverter The {@link JsonPojoConverter} instance.
Expand All @@ -77,6 +80,7 @@ public CluecumberEngine(
final FileIO fileIO,
final JsonPojoConverter jsonPojoConverter,
final ElementIndexPreProcessor elementIndexPreProcessor,
final ElementMultipleRunsPreProcessor elementMultipleRunsPreProcessor,
final ReportGenerator reportGenerator
) {
this.propertyManager = propertyManager;
Expand All @@ -85,6 +89,7 @@ public CluecumberEngine(
this.jsonPojoConverter = jsonPojoConverter;
this.logger = logger;
this.elementIndexPreProcessor = elementIndexPreProcessor;
this.elementMultipleRunsPreProcessor = elementMultipleRunsPreProcessor;
this.reportGenerator = reportGenerator;
}

Expand Down Expand Up @@ -129,6 +134,9 @@ public void build(
}
}
elementIndexPreProcessor.addScenarioIndices(allScenariosPageCollection.getReports());
if (propertyManager.isGroupPreviousScenarioRuns()) {
elementMultipleRunsPreProcessor.addMultipleRunsInformationToScenarios(allScenariosPageCollection.getReports());
}
reportGenerator.generateReport(allScenariosPageCollection);
logger.info(
"=> Cluecumber Report: " + propertyManager.getGeneratedHtmlReportDirectory() + "/" +
Expand Down Expand Up @@ -227,6 +235,24 @@ public void setExpandAttachments(final boolean expandAttachments) {
propertyManager.setExpandAttachments(expandAttachments);
}

/**
* Whether to show the scenarios run multiple times should be grouped and the show not last run toggle should be shown.
*
* @param groupPreviousScenarioRuns If true, the scenarios run multiple times should be grouped and the show not last run toggle should be shown.
*/
public void setGroupPreviousScenarioRuns(final boolean groupPreviousScenarioRuns) {
propertyManager.setGroupPreviousScenarioRuns(groupPreviousScenarioRuns);
}

/**
* Whether to expand not last run elements or not.
*
* @param expandPreviousScenarioRuns If true, not last run elements will be expanded.
*/
public void setExpandPreviousScenarioRuns(final boolean expandPreviousScenarioRuns) {
propertyManager.setExpandPreviousScenarioRuns(expandPreviousScenarioRuns);
}

/**
* Custom CSS file to override default styles.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
public class Element {
private List<ResultMatch> before = new ArrayList<>();
private int line;
private boolean isLastOfMultipleScenarioRuns = false;
private boolean isNotLastOfMultipleScenarioRuns = false;
private String featureName = "";
private String featureUri = "";
private String name = "";
Expand All @@ -45,6 +47,7 @@ public class Element {
private List<Tag> tags = new ArrayList<>();
@SerializedName("start_timestamp")
private String startTimestamp = "";
private List<Element> childrenElements = new ArrayList<>();;

private transient int featureIndex = 0;
private transient int scenarioIndex = 0;
Expand Down Expand Up @@ -695,6 +698,66 @@ public String getFeatureUri() {
return featureUri;
}

/**
* Get the scenario's id.
*
* @return The string id.
*/
public String getId() {
return id;
}

/**
* Set the scenario's id.
*
* @param id The string id.
*/
public void setId(final String id) {
this.id = id;
}

/**
* Check if this scenario is the last of multiple runs.
*
* @return true if this scenario is the last of multiple runs.
*/
public boolean getIsLastOfMultipleScenarioRuns() {
return isLastOfMultipleScenarioRuns;
}

/**
* Set to true if this scenario is the last of multiple runs.
* @param isLastOfMultipleScenarioRuns true if this scenario is the last of multiple runs.
*/
public void setIsLastOfMultipleScenarioRuns(final boolean isLastOfMultipleScenarioRuns) {
this.isLastOfMultipleScenarioRuns = isLastOfMultipleScenarioRuns;
}

/**
* Check if this scenario was run multiple times and it's not the last run.
*
* @return true if this scenario was run multiple times and it's not the last run.
*/
public boolean getIsNotLastOfMultipleScenarioRuns() {
return isNotLastOfMultipleScenarioRuns;
}

/**
* Set to true if this scenario was run multiple times and it's not the last run.
* @param isNotLastOfMultipleScenarioRuns true if this scenario was run multiple times and it's not the last run.
*/
public void setIsNotLastOfMultipleScenarioRuns(final boolean isNotLastOfMultipleScenarioRuns) {
this.isNotLastOfMultipleScenarioRuns = isNotLastOfMultipleScenarioRuns;
}

public List<Element> getChildrenElements() {
return childrenElements;
}

public void setChildrenElements(final List<Element> childrenElements) {
this.childrenElements = childrenElements;
}

/**
* Set the URI of the parent feature file.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Copyright 2023 trivago N.V.
*
* 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 com.trivago.cluecumber.engine.json.processors;

import com.trivago.cluecumber.engine.json.pojo.Element;
import com.trivago.cluecumber.engine.json.pojo.Report;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
* This class preprocesses {@link Element} JSON to add additional information to it and extract attachments.
*/
@Singleton
public class ElementMultipleRunsPreProcessor {

/**
* The default constructor.
*/
@Inject
public ElementMultipleRunsPreProcessor() {
}

/**
* This adds the latest run information to each scenario run multiple times.
* It specifies if it was the last run started or not.
*
* @param reports The list of reports to cycle through.
*/
public void addMultipleRunsInformationToScenarios(final List<Report> reports) {

List<Element> elements = new ArrayList<>();
for (Report report : reports) {
elements.addAll(report.getElements());
}

// Group elements by id (that should combine feature and scenario names) and line, to also ensure that scenario outlines are properly handled
Map<String, Map<Integer, List<Element>>> groupedElements = elements.stream()
.collect(Collectors.groupingBy(
Element::getId,
Collectors.groupingBy(Element::getLine)
));

// set flags based on start time and add children element to last run element
for (Map<Integer, List<Element>> idGroup : groupedElements.values()) {
for (List<Element> lineGroup : idGroup.values()) {
if (lineGroup.size() < 2) {
continue;
}
lineGroup.sort(Comparator.comparing(Element::getStartDateTime).reversed());

Element lastRunElement = lineGroup.get(0);
lastRunElement.setIsLastOfMultipleScenarioRuns(true);

List<Element> childrenElements = new ArrayList<>(lineGroup.subList(1, lineGroup.size()));
for (Element element : childrenElements) {
element.setIsNotLastOfMultipleScenarioRuns(true);
}

lastRunElement.setChildrenElements(childrenElements);
}
}
}
}
Loading

0 comments on commit ca8b1fe

Please sign in to comment.