diff --git a/src/main/java/net/masterthought/cucumber/ReportBuilder.java b/src/main/java/net/masterthought/cucumber/ReportBuilder.java index 8c5c514d0..ad859865a 100755 --- a/src/main/java/net/masterthought/cucumber/ReportBuilder.java +++ b/src/main/java/net/masterthought/cucumber/ReportBuilder.java @@ -1,34 +1,26 @@ package net.masterthought.cucumber; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; -import java.io.Reader; -import java.io.Writer; -import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import com.fasterxml.jackson.databind.SerializationFeature; -import net.masterthought.cucumber.generators.ErrorPage; -import net.masterthought.cucumber.generators.FailuresOverviewPage; -import net.masterthought.cucumber.generators.FeatureReportPage; -import net.masterthought.cucumber.generators.FeaturesOverviewPage; -import net.masterthought.cucumber.generators.StepsOverviewPage; -import net.masterthought.cucumber.generators.TagReportPage; -import net.masterthought.cucumber.generators.TagsOverviewPage; -import net.masterthought.cucumber.generators.TrendsOverviewPage; -import net.masterthought.cucumber.json.Feature; +import net.masterthought.cucumber.generators.*; +import net.masterthought.cucumber.json.*; import net.masterthought.cucumber.json.support.TagObject; import org.apache.commons.io.FileUtils; +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Base64; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import static java.nio.charset.StandardCharsets.UTF_8; + public class ReportBuilder { private static final Logger LOG = Logger.getLogger(ReportBuilder.class.getName()); @@ -54,7 +46,7 @@ public class ReportBuilder { private ReportResult reportResult; private final ReportParser reportParser; - private Configuration configuration; + private final Configuration configuration; private List jsonFiles; /** @@ -64,45 +56,46 @@ public class ReportBuilder { */ private boolean wasTrendsFileSaved = false; - public ReportBuilder(List jsonFiles, Configuration configuration) { - this.jsonFiles = jsonFiles; + public ReportBuilder(Configuration configuration) { this.configuration = configuration; reportParser = new ReportParser(configuration); } + @Deprecated + public ReportBuilder(List jsonFiles, Configuration configuration) { + this(configuration); + this.jsonFiles = jsonFiles; + } + /** * Parses provided files and generates the report. When generating process fails * report with information about error is provided. * * @return stats for the generated report + * @deprecated use {@link #generateReportsFromFiles(List)} instead */ + @Deprecated public Reportable generateReports() { - Trends trends = null; + return generateReportsFromFiles(jsonFiles); + } + /** + * Parses provided files and generates the report. When generating process fails + * report with information about error is provided. + * + * @return stats for the generated report + */ + public Reportable generateReportsFromFiles(List pathsTojsonFiles) { try { // first copy static resources so ErrorPage is displayed properly copyStaticResources(); - // create directory for embeddings before files are generated - createEmbeddingsDirectory(); - // add metadata info sourced from files reportParser.parseClassificationsFiles(configuration.getClassificationFiles()); // parse json files for results - List features = reportParser.parseJsonFiles(jsonFiles); - reportResult = new ReportResult(features, configuration); - Reportable reportable = reportResult.getFeatureReport(); - - if (configuration.isTrendsAvailable()) { - // prepare data required by generators, collect generators and generate pages - trends = updateAndSaveTrends(reportable); - } - - // Collect and generate pages in a single pass - generatePages(trends); - - return reportable; + List features = reportParser.parseJsonFiles(pathsTojsonFiles); + return generateReportsFromFeatures(features); // whatever happens we want to provide at least error page instead of incomplete report or exception } catch (Exception e) { @@ -121,6 +114,62 @@ public Reportable generateReports() { } } + /** + * Parses provided features and generates the report. When generating process fails + * report with information about error is provided. + * + * @return stats for the generated report + */ + public Reportable generateReportsFromFeatures(List features) { + reportResult = new ReportResult(features, configuration); + Reportable reportable = reportResult.getFeatureReport(); + + Trends trends = null; + if (configuration.isTrendsAvailable()) { + // prepare data required by generators, collect generators and generate pages + trends = updateAndSaveTrends(reportable); + } + + generateEmbeddings(); + + // Collect and generate pages in a single pass + generatePages(trends); + + return reportable; + } + + private void generateEmbeddings() { + // create directory for embeddings before files are generated + createEmbeddingsDirectory(); + + reportResult.getAllFeatures().forEach(feature -> { + for (Element element : feature.getElements()) { + for (Hook hook : element.getAfter()) { + storeEmbedding(hook.getEmbeddings(), configuration.getEmbeddingDirectory()); + } + for (Hook hook : element.getBefore()) { + storeEmbedding(hook.getEmbeddings(), configuration.getEmbeddingDirectory()); + } + for (Step step : element.getSteps()) { + storeEmbedding(step.getEmbeddings(), configuration.getEmbeddingDirectory()); + } + } + }); + } + + private void storeEmbedding(Embedding[] embeddings, File embeddingDirectory) { + for (Embedding embedding : embeddings) { + Path file = FileSystems.getDefault().getPath(embeddingDirectory.getAbsolutePath(), + embedding.getFileId() + "." + embedding.getExtension()); + byte[] decodedData = Base64.getDecoder().decode(embedding.getData().getBytes(UTF_8)); + try { + Files.write(file, decodedData); + } catch (IOException e) { + throw new ValidationException(e); + } + } + } + private void copyStaticResources() { copyResources("css", "cucumber.css", "bootstrap.min.css", "font-awesome.min.css"); copyResources("js", "jquery.min.js", "jquery.tablesorter.min.js", "bootstrap.min.js", "Chart.min.js", @@ -144,7 +193,7 @@ private void copyResources(String resourceLocation, String... resources) { // don't change this implementation unless you verified it works on Jenkins try { FileUtils.copyInputStreamToFile( - this.getClass().getResourceAsStream("/" + resourceLocation + "/" + resource), tempFile); + getClass().getResourceAsStream("/" + resourceLocation + "/" + resource), tempFile); } catch (IOException e) { // based on FileUtils implementation, should never happen even is declared throw new ValidationException(e); @@ -226,6 +275,7 @@ private void saveTrends(Trends trends, File file) { private void generateErrorPage(Exception exception) { LOG.log(Level.INFO, "Unexpected error", exception); + //FIXME jsonfiles can be null when generating from Features ErrorPage errorPage = new ErrorPage(reportResult, configuration, exception, jsonFiles); errorPage.generatePage(); } diff --git a/src/main/java/net/masterthought/cucumber/json/deserializers/EmbeddingDeserializer.java b/src/main/java/net/masterthought/cucumber/json/deserializers/EmbeddingDeserializer.java index 401b5c1d8..f54b28952 100644 --- a/src/main/java/net/masterthought/cucumber/json/deserializers/EmbeddingDeserializer.java +++ b/src/main/java/net/masterthought/cucumber/json/deserializers/EmbeddingDeserializer.java @@ -2,20 +2,14 @@ import com.fasterxml.jackson.databind.JsonNode; import net.masterthought.cucumber.Configuration; -import net.masterthought.cucumber.ValidationException; import net.masterthought.cucumber.json.Embedding; -import java.io.File; -import java.io.IOException; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; import java.util.Base64; import static java.nio.charset.StandardCharsets.UTF_8; /** - * Deserializes embedding and stores it in attachment directory. + * Deserializes embedding. * * @author Damian Szczepanik (damianszczepanik@github) */ @@ -37,18 +31,16 @@ public Embedding deserialize(JsonNode rootNode, Configuration configuration) { embedding = new Embedding(mimeType, encodedData); } - storeEmbedding(embedding, configuration.getEmbeddingDirectory()); - return embedding; } private String getBase64EncodedData(String data) { - try{ + try { // If we can successfully decode the data we consider it to be base64 encoded, // so we do not need to do anything here Base64.getDecoder().decode(data); return data; - }catch (IllegalArgumentException e){ + } catch (IllegalArgumentException e) { // decoding failed, therefore we consider the data not to be encoded, // so we need to encode it return new String(Base64.getEncoder().encode(data.getBytes(UTF_8)), UTF_8); @@ -65,15 +57,4 @@ private String findMimeType(JsonNode rootNode) { return rootNode.get("mime_type").asText(); } - private void storeEmbedding(Embedding embedding, File embeddingDirectory) { - Path file = FileSystems.getDefault().getPath(embeddingDirectory.getAbsolutePath(), - embedding.getFileId() + "." + embedding.getExtension()); - byte[] decodedData = Base64.getDecoder().decode(embedding.getData().getBytes(UTF_8)); - try { - Files.write(file, decodedData); - } catch (IOException e) { - throw new ValidationException(e); - } - } - } diff --git a/src/test/java/net/masterthought/cucumber/ReportGenerator.java b/src/test/java/net/masterthought/cucumber/ReportGenerator.java index fe104a09e..81d9103d7 100644 --- a/src/test/java/net/masterthought/cucumber/ReportGenerator.java +++ b/src/test/java/net/masterthought/cucumber/ReportGenerator.java @@ -66,14 +66,15 @@ protected void setUpWithJson(String... jsonFiles) { protected void initWithJson(String... jsonFiles) { if (jsonFiles != null) { - for (String jsonFile : jsonFiles) + for (String jsonFile : jsonFiles) { jsonReports.add(reportFromResource(jsonFile)); + } } } protected void initWithProperties(String... propertyFiles) { for (String propertyFile : propertyFiles) { - this.classificationFiles.add(reportFromResourceProperties(propertyFile)); + classificationFiles.add(reportFromResourceProperties(propertyFile)); } } diff --git a/src/test/java/net/masterthought/cucumber/generators/integrations/FeatureReportPageIntegrationTest.java b/src/test/java/net/masterthought/cucumber/generators/integrations/FeatureReportPageIntegrationTest.java index 97b01e628..a35a8dd00 100644 --- a/src/test/java/net/masterthought/cucumber/generators/integrations/FeatureReportPageIntegrationTest.java +++ b/src/test/java/net/masterthought/cucumber/generators/integrations/FeatureReportPageIntegrationTest.java @@ -1,34 +1,12 @@ package net.masterthought.cucumber.generators.integrations; -import static org.assertj.core.api.Assertions.assertThat; - -import java.io.File; - +import net.masterthought.cucumber.generators.FeatureReportPage; +import net.masterthought.cucumber.generators.integrations.helpers.*; +import net.masterthought.cucumber.json.*; import org.apache.commons.lang.StringUtils; import org.junit.Test; -import net.masterthought.cucumber.generators.FeatureReportPage; -import net.masterthought.cucumber.generators.integrations.helpers.BriefAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.DocumentAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.ElementAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.EmbeddingAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.FeatureAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.HookAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.HooksAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.OutputAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.StepAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.StepsAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.TableAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.TableRowAssertion; -import net.masterthought.cucumber.generators.integrations.helpers.TagAssertion; -import net.masterthought.cucumber.json.Element; -import net.masterthought.cucumber.json.Embedding; -import net.masterthought.cucumber.json.Feature; -import net.masterthought.cucumber.json.Hook; -import net.masterthought.cucumber.json.Output; -import net.masterthought.cucumber.json.Result; -import net.masterthought.cucumber.json.Row; -import net.masterthought.cucumber.json.Step; +import static org.assertj.core.api.Assertions.assertThat; /** * @author Damian Szczepanik (damianszczepanik@github) @@ -306,13 +284,14 @@ public void generatePage_generatesEmbedding() { assertThat(embeddingsElement).hasSameSizeAs(embeddings); embeddingsElement[0].getLinks()[0].hasLabelAndAddress(embeddings[0].getName(), ""); embeddingsElement[0].hasImageContent(embeddings[0]); - assertEmbeddingFileExist(embeddings[0]); + // Embeddings are not generated when the page is generated, therefore it we should not check if the file exists +// assertEmbeddingFileExist(embeddings[0]); embeddingsElement[2].getLinks()[0].hasLabelAndAddress("Attachment 3 (Plain text)", ""); embeddingsElement[2].hasTextContent(embeddings[2].getData()); - assertEmbeddingFileExist(embeddings[2]); +// assertEmbeddingFileExist(embeddings[2]); embeddingsElement[3].getLinks()[0].hasLabelAndAddress(embeddings[3].getName(), ""); embeddingsElement[3].hasSrcDocContent(embeddings[3].getData()); - assertEmbeddingFileExist(embeddings[3]); +// assertEmbeddingFileExist(embeddings[3]); } @Test @@ -335,7 +314,8 @@ public void generatePage_OnRubyFormat_ForAfterHook_generatesEmbedding() { assertThat(embeddingsElement).hasSameSizeAs(embeddings); embeddingsElement[0].hasImageContent(embeddings[0]); - assertEmbeddingFileExist(embeddings[0]); + // Embeddings are not generated when the page is generated, therefore it we should not check if the file exists +// assertEmbeddingFileExist(embeddings[0]); } @Test @@ -425,8 +405,8 @@ private static void validateHook(HookAssertion[] hookAssertions, Hook[] hooks, S } } - private void assertEmbeddingFileExist(Embedding embedding) { - File file = new File(configuration.getEmbeddingDirectory(), embedding.getFileName()); - assertThat(file).exists(); - } +// private void assertEmbeddingFileExist(Embedding embedding) { +// File file = new File(configuration.getEmbeddingDirectory(), embedding.getFileName()); +// assertThat(file).exists(); +// } }