
com.github.mkolisnyk.cucumber.reporting.CucumberDetailedResults Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cucumber-reports Show documentation
Show all versions of cucumber-reports Show documentation
Library generating different Cucumber reports
package com.github.mkolisnyk.cucumber.reporting;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.Locale;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import com.github.mkolisnyk.cucumber.reporting.types.result.CucumberBeforeAfterResult;
import com.github.mkolisnyk.cucumber.reporting.types.result.CucumberEmbedding;
import com.github.mkolisnyk.cucumber.reporting.types.result.CucumberFeatureResult;
import com.github.mkolisnyk.cucumber.reporting.types.result.CucumberScenarioResult;
import com.github.mkolisnyk.cucumber.reporting.types.result.CucumberStepResult;
/**
* @author Myk Kolisnyk
*/
public class CucumberDetailedResults extends CucumberResultsCommon {
private String screenShotLocation;
private String screenShotWidth;
/**
* @return the screenShotLocation
*/
public final String getScreenShotLocation() {
return screenShotLocation;
}
/**
* @param screenShotLocationValue the screenShotLocation to set
*/
public final void setScreenShotLocation(String screenShotLocationValue) {
this.screenShotLocation = screenShotLocationValue;
}
/**
* @return the screenShotWidth
*/
public final String getScreenShotWidth() {
return screenShotWidth;
}
/**
* @param screenShotWidthValue the screenShotWidth to set
*/
public final void setScreenShotWidth(String screenShotWidthValue) {
this.screenShotWidth = screenShotWidthValue;
}
private String getReportBase() throws IOException {
InputStream is = this.getClass().getResourceAsStream("/results-report-tmpl.html");
String result = IOUtils.toString(is);
return result;
}
private String escapeHtml(String input) {
return StringEscapeUtils.escapeHtml(input);
}
public class OverviewStats {
private int featuresPassed;
private int featuresFailed;
private int featuresUndefined;
private int scenariosPassed;
private int scenariosFailed;
private int scenariosUndefined;
private int stepsPassed;
private int stepsFailed;
private int stepsUndefined;
private float overallDuration;
public OverviewStats() {
featuresPassed = 0;
featuresFailed = 0;
featuresUndefined = 0;
scenariosPassed = 0;
scenariosFailed = 0;
scenariosUndefined = 0;
stepsPassed = 0;
stepsFailed = 0;
stepsUndefined = 0;
overallDuration = 0.f;
}
public final int getFeaturesPassed() {
return featuresPassed;
}
public final int getFeaturesFailed() {
return featuresFailed;
}
public final int getFeaturesUndefined() {
return featuresUndefined;
}
public final int getScenariosPassed() {
return scenariosPassed;
}
public final int getScenariosFailed() {
return scenariosFailed;
}
public final int getScenariosUndefined() {
return scenariosUndefined;
}
public final int getStepsPassed() {
return stepsPassed;
}
public final int getStepsFailed() {
return stepsFailed;
}
public final int getStepsUndefined() {
return stepsUndefined;
}
public final float getOverallDuration() {
return overallDuration;
}
public final void addFeaturesPassed(int featuresPassedValue) {
this.featuresPassed += featuresPassedValue;
}
public final void addFeaturesFailed(int featuresFailedValue) {
this.featuresFailed += featuresFailedValue;
}
public final void addFeaturesUndefined(int featuresUndefinedValue) {
this.featuresUndefined += featuresUndefinedValue;
}
public final void addScenariosPassed(int scenariosPassedValue) {
this.scenariosPassed += scenariosPassedValue;
}
public final void addScenariosFailed(int scenariosFailedValue) {
this.scenariosFailed += scenariosFailedValue;
}
public final void addScenariosUndefined(int scenariosUndefinedValue) {
this.scenariosUndefined += scenariosUndefinedValue;
}
public final void addStepsPassed(int stepsPassedValue) {
this.stepsPassed += stepsPassedValue;
}
public final void addStepsFailed(int stepsFailedValue) {
this.stepsFailed += stepsFailedValue;
}
public final void addStepsUndefined(int stepsUndefinedValue) {
this.stepsUndefined += stepsUndefinedValue;
}
public final void addOverallDuration(float overallDurationValue) {
this.overallDuration += overallDurationValue;
}
}
public OverviewStats valuateOverviewStats(CucumberFeatureResult[] results) {
OverviewStats stats = new OverviewStats();
for (CucumberFeatureResult result : results) {
result.valuate();
stats.addOverallDuration(result.getDuration());
if (result.getStatus().equals("passed")) {
stats.addFeaturesPassed(1);
} else if (result.getStatus().equals("failed")) {
stats.addFeaturesFailed(1);
} else {
stats.addFeaturesUndefined(1);
}
stats.addScenariosPassed(result.getPassed());
stats.addScenariosFailed(result.getFailed());
stats.addScenariosUndefined(result.getUndefined() + result.getSkipped());
for (CucumberScenarioResult scenario : result.getElements()) {
stats.addStepsPassed(scenario.getPassed());
stats.addStepsFailed(scenario.getFailed());
stats.addStepsUndefined(scenario.getUndefined() + scenario.getSkipped());
}
}
return stats;
}
private String generateOverview(CucumberFeatureResult[] results) {
final int secondsInMinute = 60;
final int secondsInHour = 3600;
final float highestPercent = 100.f;
float overallDuration = 0.f;
OverviewStats stats = valuateOverviewStats(results);
overallDuration = stats.getOverallDuration();
return String.format(
Locale.US,
""
+ "Passed Failed Undefined %%Passed "
+ "Features %d %d "
+ "%d %.2f "
+ "Scenarios %d %d "
+ "%d %.2f "
+ "Steps %d %d "
+ "%d %.2f
"
+ "Overall Duration: %dh %02dm %02ds",
stats.getFeaturesPassed(),
stats.getFeaturesFailed(),
stats.getFeaturesUndefined(),
highestPercent * (float) stats.getFeaturesPassed()
/ (float) (stats.getFeaturesPassed() + stats.getFeaturesFailed() + stats.getFeaturesUndefined()),
stats.getScenariosPassed(),
stats.getScenariosFailed(),
stats.getScenariosUndefined(),
highestPercent * (float) stats.getScenariosPassed()
/ (float) (stats.getScenariosPassed() + stats.getScenariosFailed() + stats.getScenariosUndefined()),
stats.getStepsPassed(),
stats.getStepsFailed(),
stats.getStepsUndefined(),
highestPercent * (float) stats.getStepsPassed()
/ (float) (stats.getStepsPassed() + stats.getStepsFailed() + stats.getStepsUndefined()),
(int) overallDuration / secondsInHour,
((int) overallDuration % secondsInHour) / secondsInMinute,
((int) overallDuration % secondsInHour) % secondsInMinute);
}
private String generateNameFromId(String scId) {
String result = scId.replaceAll("[; !@#$%^&*()+=]", "_");
return result;
}
private String generateTableOfContents(CucumberFeatureResult[] results) {
String reportContent = "";
reportContent += "Table of Contents
";
for (CucumberFeatureResult result : results) {
reportContent += String.format(
Locale.US,
"- %s
",
result.getStatus(),
escapeHtml(result.getId()),
escapeHtml(result.getName()));
for (CucumberScenarioResult scenario : result.getElements()) {
if (scenario.getKeyword().contains("Scenario")) {
reportContent += String.format(
Locale.US,
"- %s
",
scenario.getStatus(),
escapeHtml(scenario.getId()),
escapeHtml(scenario.getName()));
}
}
reportContent += "
";
}
reportContent += "
";
return reportContent;
}
private String generateStepRows(CucumberStepResult step) {
String reportContent = "";
if (step.getRows() != null) {
reportContent += String.format(
Locale.US,
"",
step.getResult().getStatus());
for (int i = 0; i < step.getRows().length; i++) {
reportContent += "";
for (int j = 0; j < step.getRows()[i].length; j++) {
reportContent += String.format(Locale.US,
"%s ", escapeHtml(step.getRows()[i][j]));
}
reportContent += " ";
}
reportContent += "
";
}
return reportContent;
}
private String generateDocString(CucumberStepResult step) {
String reportContent = "";
if (StringUtils.isNotBlank(step.getDocString())) {
reportContent += String.format(
Locale.US,
"",
step.getResult().getStatus());
reportContent += String.format(
Locale.US,
"
%s",
escapeHtml(step.getDocString()).replaceAll("\n", "
"));
reportContent += " ";
}
return reportContent;
}
private String getExtensionFromMime(String mime) {
if (mime.contains("png")) {
return "png";
}
if (mime.contains("jpg") || mime.contains("jpeg")) {
return "jpg";
}
return "txt";
}
private String embeddingScreenShots(CucumberScenarioResult scenario, CucumberStepResult step) throws IOException {
String reportContent = "";
String scenarioId = scenario.getId();
if (StringUtils.isBlank(scenarioId)) {
scenarioId = "background";
// Add more precise background generation
}
if (step.getEmbeddings() != null) {
int index = 0;
long base = new Date().getTime();
for (CucumberEmbedding embedding : step.getEmbeddings()) {
String embedPath = this.getScreenShotLocation()
+ this.generateNameFromId(scenarioId) + (base + index) + "."
+ getExtensionFromMime(embedding.getMimeType());
File embedShot = new File(this.getOutputDirectory() + embedPath);
FileUtils.writeByteArrayToFile(embedShot, embedding.getData());
String widthString = "";
if (StringUtils.isNotBlank(this.getScreenShotWidth())) {
widthString = String.format(Locale.US, "width=\"%s\"", this.getScreenShotWidth());
}
reportContent += String.format(Locale.US,
"
",
step.getResult().getStatus(),
embedPath,
widthString
);
index++;
}
}
return reportContent;
}
private String generateScreenShot(CucumberScenarioResult scenario, CucumberStepResult step) throws IOException {
String reportContent = "";
if (step.getResult().getStatus().trim().equalsIgnoreCase("failed")) {
reportContent += String.format(
Locale.US,
"%s%s ",
step.getResult().getStatus(),
"
",
escapeHtml(step.getResult().getErrorMessage()).replaceAll(System.lineSeparator(),
"
" + System.lineSeparator())
);
String scenarioId = scenario.getId();
if (StringUtils.isBlank(scenarioId)) {
scenarioId = "background";
// Add more precise background generation
}
String filePath = this.getScreenShotLocation()
+ this.generateNameFromId(scenarioId) + ".png";
File shot = new File(this.getOutputDirectory() + filePath);
if (shot.exists()) {
String widthString = "";
if (StringUtils.isNotBlank(this.getScreenShotWidth())) {
widthString = String.format(Locale.US, "width=\"%s\"", this.getScreenShotWidth());
}
reportContent += String.format(Locale.US,
"
",
step.getResult().getStatus(),
filePath,
widthString
);
}
}
return reportContent;
}
private String generateBeforeAfterRow(CucumberBeforeAfterResult results, String name) {
if (results != null) {
String error = escapeHtml(results.getResult().getErrorMessage());
if (StringUtils.isBlank(error)) {
error = "";
}
return String.format(
Locale.US,
"%s %s "
+ "%s ",
results.getResult().getStatus(),
name,
results.getResult().getDurationTimeString("HH:mm:ss:S"),
results.getResult().getStatus(),
"
" + error.replaceAll(System.lineSeparator(), "
") + ""
);
}
return "";
}
private String generateStepsReport(CucumberFeatureResult[] results) throws IOException {
String content = this.getReportBase();
content = content.replaceAll("__TITLE__", "Detailed Results Report");
content = content.replaceAll("__OVERVIEW__", generateOverview(results));
String reportContent = "";
reportContent += generateTableOfContents(results);
reportContent += "Detailed Results Report
";
for (CucumberFeatureResult result : results) {
reportContent += String.format(
Locale.US,
"Feature: %s "
+ "
%s "
+ "Passed: %d "
+ "Failed: %d "
+ "Undefined: %d Duration: %.2fs "
+ ""
+ " ",
result.getStatus(),
escapeHtml(result.getId()),
escapeHtml(result.getName()),
result.getStatus(),
escapeHtml(result.getDescription()).replaceAll(System.lineSeparator(),
"
" + System.lineSeparator()),
result.getStatus(),
result.getPassed(),
result.getFailed(),
result.getUndefined() + result.getSkipped(),
result.getDuration(),
result.getStatus());
for (CucumberScenarioResult scenario : result.getElements()) {
reportContent += String.format(
Locale.US,
"%s: %s "
+ "
%s "
+ ""
+ "Passed: %d Failed: %d "
+ "Undefined: %d Duration: %.2fs "
+ "%s"
+ ""
+ " ",
scenario.getStatus(),
scenario.getKeyword(),
escapeHtml(scenario.getId()),
escapeHtml(scenario.getName()),
scenario.getStatus(),
escapeHtml(scenario.getDescription()).replaceAll(System.lineSeparator(),
"
" + System.lineSeparator()),
scenario.getStatus(),
scenario.getPassed(),
scenario.getFailed(),
scenario.getUndefined() + scenario.getSkipped(),
scenario.getDuration(),
this.generateBeforeAfterRow(scenario.getBefore(), "Before"),
scenario.getStatus());
for (CucumberStepResult step : scenario.getSteps()) {
reportContent += String.format(
Locale.US,
"%s %s %s ",
step.getResult().getStatus(),
step.getKeyword(),
escapeHtml(step.getName()),
step.getResult().getDurationTimeString("HH:mm:ss:S")
);
reportContent += this.generateStepRows(step);
reportContent += this.generateDocString(step);
reportContent += this.generateScreenShot(scenario, step);
reportContent += this.embeddingScreenShots(scenario, step);
}
reportContent += "
"
+ this.generateBeforeAfterRow(scenario.getAfter(), "After")
+ ""
+ "Back to Table of Contents ";
}
reportContent += "
";
}
reportContent += "
";
//reportContent = reportContent.replaceAll("£", "£");
reportContent = this.replaceHtmlEntitiesWithCodes(reportContent);
reportContent = reportContent.replaceAll("[$]", "$");
content = content.replaceAll("__REPORT__", reportContent);
return content;
}
public void executeDetailedResultsReport(boolean toPdf, boolean aggregate) throws Exception {
CucumberFeatureResult[] features = readFileContent(aggregate);
String formatName = "";
if (aggregate) {
formatName = "%s%s%s-agg-test-results.html";
} else {
formatName = "%s%s%s-test-results.html";
}
File outFile = new File(
String.format(Locale.US,
formatName,
this.getOutputDirectory(), File.separator, this.getOutputName()));
String content = generateStepsReport(features);
FileUtils.writeStringToFile(outFile, content, "UTF-8");
if (toPdf) {
this.exportToPDF(outFile, "test-results");
}
}
@Override
public int[][] getStatuses(CucumberFeatureResult[] results) {
// TODO Auto-generated method stub
return null;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy