io.github.eroshenkoam.allure.AllurePDFGenerator Maven / Gradle / Ivy
The newest version!
package io.github.eroshenkoam.allure;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.ListItem;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.PdfWriter;
import io.github.eroshenkoam.allure.util.PdfUtil;
import io.qameta.allure.model.Attachment;
import io.qameta.allure.model.Label;
import io.qameta.allure.model.StepResult;
import io.qameta.allure.model.TestResult;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import static io.github.eroshenkoam.allure.FontHolder.loadArialFont;
import static io.github.eroshenkoam.allure.util.PdfUtil.addEmptyLine;
import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.mapping;
public class AllurePDFGenerator {
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
private final String reportName;
private final Path reportPath;
private final Map filter;
public AllurePDFGenerator(final String reportName, final Path reportPath) {
this.filter = new HashMap<>();
this.reportName = reportName;
this.reportPath = reportPath;
}
public void filter(final Map tags) {
this.filter.putAll(tags);
}
public void generate(final Path outputPath) throws IOException {
if (!Files.isDirectory(reportPath)) {
log("Input [%s] is not directory", reportPath.toAbsolutePath());
return;
}
if (Files.notExists(reportPath)) {
log("Results directory [%s] does not exists", reportPath.toAbsolutePath());
return;
}
if (Files.notExists(outputPath)) {
log("Creating output file [%s] ...", outputPath.toAbsolutePath());
Files.createFile(outputPath);
}
final FontHolder fontHolder = loadArialFont();
final List files = Files.walk(reportPath)
.filter(s -> s.toString().endsWith("-result.json"))
.collect(Collectors.toList());
log("Found [%s] rest results ...", files.size());
try (final Document document = new Document(PageSize.A4)) {
PdfWriter.getInstance(document, Files.newOutputStream(outputPath));
document.newPage();
document.open();
addTitlePage(document, reportName, DATE_FORMAT, fontHolder);
document.newPage();
final Paragraph tableHeader = new Paragraph("Test Details", fontHolder.header2());
addEmptyLine(tableHeader, 2);
document.add(tableHeader);
for (Path path : files) {
final TestResult result = new ObjectMapper().readValue(path.toFile(), TestResult.class);
final Map> labels = result.getLabels().stream().collect(
Collectors.groupingBy(Label::getName, Collectors.mapping(Label::getValue, Collectors.toList()))
);
boolean shouldSkip = Objects.nonNull(filter)
&& !filter.isEmpty()
&& !filter.entrySet().stream().allMatch(e -> labels.getOrDefault(e.getKey(), new ArrayList<>()).contains(e.getValue()));
if (!shouldSkip) {
printTestResultDetails(document, result, fontHolder);
}
}
}
}
private void addTitlePage(final Document document,
final String exportName,
final DateFormat dateFormat,
final FontHolder fontHolder) {
final Paragraph preface = new Paragraph();
addEmptyLine(preface, 5);
preface.add(new Phrase("Allure Report", fontHolder.header1()));
addEmptyLine(preface, 3);
preface.add(new Phrase(exportName, fontHolder.header3()));
addEmptyLine(preface, 2);
preface.add(new Phrase("Date: ", fontHolder.bold()));
preface.add(new Phrase(dateFormat.format(new Date()), fontHolder.normal()));
preface.setAlignment(Element.ALIGN_CENTER);
document.add(preface);
}
private void printTestResultDetails(final Document document,
final TestResult testResult,
final FontHolder fontHolder) {
final Paragraph details = new Paragraph();
details.add(PdfUtil.createEmptyLine());
addTestResultHeader(testResult, fontHolder, details);
details.add(PdfUtil.createEmptyLine());
addCustomFieldsSection(testResult, fontHolder, details);
details.add(PdfUtil.createEmptyLine());
addSteps(testResult, fontHolder, details);
document.add(details);
}
private void addTestResultHeader(final TestResult testResult, final FontHolder fontHolder,
final Paragraph details) {
final Chunk testResultName = new Chunk(testResult.getName(), fontHolder.header3());
final Paragraph testResultStatus = new Paragraph(testResultName);
testResultStatus.add(String.format("%s", new Phrase(testResult.getStatus().name())));
details.add(testResultStatus);
}
private void addCustomFieldsSection(final TestResult testResult,
final FontHolder fontHolder,
final Paragraph details) {
if (CollectionUtils.isNotEmpty(testResult.getLabels())) {
final Map labels = testResult.getLabels().stream().collect(
groupingBy(Label::getName, mapping(Label::getValue, joining(", ")))
);
details.add(new Paragraph("Labels", fontHolder.header4()));
final com.lowagie.text.List list = new com.lowagie.text.List(false);
labels.forEach((key, value) -> {
list.add(new ListItem(String.format("%s: %s", key, value), fontHolder.normal()));
});
details.add(list);
}
}
private void addSteps(final TestResult testResult, final FontHolder fontHolder, final Paragraph details) {
if (Objects.nonNull(testResult.getSteps())) {
details.add(new Paragraph("Scenario", fontHolder.header4()));
final com.lowagie.text.List list = new com.lowagie.text.List(true);
testResult.getSteps().stream()
.map(step -> createStepItem(step, fontHolder))
.forEach(list::add);
details.add(list);
}
}
private ListItem createStepItem(final StepResult step, final FontHolder fontHolder) {
final Font font = fontHolder.normal();
final String stepTitle = String.format("%s [%s]", step.getName(), step.getStatus());
final ListItem stepItem = new ListItem(stepTitle, font);
if (Objects.nonNull(step.getAttachments())) {
final com.lowagie.text.List attachments = new com.lowagie.text.List(false, false);
for (final Attachment attach : step.getAttachments()) {
final String attachmentTitle = String.format("%s (%s)", attach.getName(), attach.getType());
final ListItem attachmentItem = new ListItem(attachmentTitle, font);
final com.lowagie.text.List content = new com.lowagie.text.List(false);
for (final String line : readFile(attach)) {
content.add(new ListItem(line.replace("\t", " "), font));
}
attachmentItem.add(content);
attachments.add(attachmentItem);
}
stepItem.add(attachments);
}
return stepItem;
}
private List readFile(final Attachment attachment) {
final Path file = reportPath.resolve(attachment.getSource());
try (InputStream stream = Files.newInputStream(file)) {
return IOUtils.readLines(stream, StandardCharsets.UTF_8);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private void log(String template, Object... values) {
System.out.println(String.format(template, values));
}
}