Skip to content

Commit 8c67fcc

Browse files
committed
fixes #331 - Gson error when merging reports due to Throwable#detailMessage
1 parent 36c7418 commit 8c67fcc

File tree

14 files changed

+247
-89
lines changed

14 files changed

+247
-89
lines changed

src/main/java/com/aventstack/extentreports/AbstractProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,9 @@ protected void onDeviceAdded(Device x, Test test) {
9090
@Override
9191
protected void onFlush() {
9292
getReport().refresh();
93-
if (!usingNaturalConf)
93+
if (!usingNaturalConf) {
9494
getReport().applyOverrideConf();
95+
}
9596
super.onFlush();
9697
}
9798

src/main/java/com/aventstack/extentreports/append/JsonDeserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public JsonDeserializer(final File f) {
2121

2222
public List<Test> deserialize() throws IOException {
2323
Gson gson = GsonExtentTypeAdapterBuilder.builder()
24-
.withBddTypeAdapterFactory()
24+
.withGsonTypeAdapterFactory()
2525
.withScreenCaptureTypeAdapter()
2626
.build();
2727
String json = new String(Files.readAllBytes(f.toPath()));

src/main/java/com/aventstack/extentreports/append/RawEntityConverter.java

Lines changed: 47 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,15 @@
88
import com.aventstack.extentreports.ExtentTest;
99
import com.aventstack.extentreports.GherkinKeyword;
1010
import com.aventstack.extentreports.MediaEntityBuilder;
11+
import com.aventstack.extentreports.model.ExceptionInfo;
1112
import com.aventstack.extentreports.model.Log;
1213
import com.aventstack.extentreports.model.Media;
14+
import com.aventstack.extentreports.model.NamedAttribute;
1315
import com.aventstack.extentreports.model.ScreenCapture;
1416
import com.aventstack.extentreports.model.Test;
1517

1618
public class RawEntityConverter {
19+
1720
private final ExtentReports extent;
1821

1922
public RawEntityConverter(final ExtentReports extent) {
@@ -26,43 +29,42 @@ public void convertAndApply(final File jsonFile) throws IOException {
2629
}
2730

2831
extent.setReportUsesManualConfiguration(true);
29-
List<Test> tests = new JsonDeserializer(jsonFile).deserialize();
30-
for (Test test : tests) {
32+
final List<Test> tests = new JsonDeserializer(jsonFile).deserialize();
33+
34+
for (final Test test : tests) {
35+
ExtentTest extentTest;
3136
try {
32-
if (test.getBddType() == null) {
33-
createDomain(test, extent.createTest(test.getName(), test.getDescription()));
37+
if (test.isBDD()) {
38+
final GherkinKeyword gk = new GherkinKeyword(test.getBddType().getSimpleName());
39+
extentTest = extent.createTest(gk, test.getName(), test.getDescription());
3440
} else {
35-
ExtentTest extentTest = extent.createTest(new GherkinKeyword(test.getBddType().getSimpleName()),
36-
test.getName(), test.getDescription());
37-
createDomain(test, extentTest);
41+
extentTest = extent.createTest(test.getName(), test.getDescription());
3842
}
43+
createDomain(test, extentTest);
3944
} catch (ClassNotFoundException e) {
4045
e.printStackTrace();
4146
}
4247
}
4348
}
4449

45-
public void createDomain(Test test, ExtentTest extentTest) throws ClassNotFoundException {
50+
public void createDomain(final Test test, final ExtentTest extentTest) throws ClassNotFoundException {
4651
extentTest.getModel().setStartTime(test.getStartTime());
4752
extentTest.getModel().setEndTime(test.getEndTime());
48-
addMedia(test, extentTest);
53+
constructTestMedia(test, extentTest);
4954

5055
// create events
5156
for (Log log : test.getLogs()) {
52-
if (log.hasException() && log.hasMedia())
53-
addMedia(log, extentTest, log.getException().getException());
54-
else if (log.hasException())
55-
extentTest.log(log.getStatus(), log.getException().getException());
56-
else if (log.hasMedia())
57-
addMedia(log, extentTest, null);
58-
else
57+
if (log.hasException() || log.hasMedia()) {
58+
constructLog(log, extentTest, log.getException());
59+
} else {
5960
extentTest.log(log.getStatus(), log.getDetails());
61+
}
6062
}
6163

6264
// assign attributes
63-
test.getAuthorSet().stream().map(x -> x.getName()).forEach(extentTest::assignAuthor);
64-
test.getCategorySet().stream().map(x -> x.getName()).forEach(extentTest::assignCategory);
65-
test.getDeviceSet().stream().map(x -> x.getName()).forEach(extentTest::assignDevice);
65+
test.getAuthorSet().stream().map(NamedAttribute::getName).forEach(extentTest::assignAuthor);
66+
test.getCategorySet().stream().map(NamedAttribute::getName).forEach(extentTest::assignCategory);
67+
test.getDeviceSet().stream().map(NamedAttribute::getName).forEach(extentTest::assignDevice);
6668

6769
// handle nodes
6870
for (Test node : test.getChildren()) {
@@ -73,23 +75,38 @@ else if (log.hasMedia())
7375
GherkinKeyword gk = new GherkinKeyword(node.getBddType().getSimpleName());
7476
extentNode = extentTest.createNode(gk, node.getName(), node.getDescription());
7577
}
76-
addMedia(node, extentNode);
78+
constructTestMedia(node, extentNode);
7779
createDomain(node, extentNode);
7880
}
7981
}
8082

81-
private void addMedia(Log log, ExtentTest extentTest, Throwable ex) {
82-
Media m = log.getMedia();
83-
if (m.getPath() != null) {
84-
extentTest.log(log.getStatus(), ex,
85-
MediaEntityBuilder.createScreenCaptureFromPath(m.getPath()).build());
86-
} else if (((ScreenCapture) m).getBase64() != null) {
87-
extentTest.log(log.getStatus(), ex,
88-
MediaEntityBuilder.createScreenCaptureFromBase64String(((ScreenCapture) m).getBase64()).build());
83+
private void constructLog(final Log log, final ExtentTest extentTest, final ExceptionInfo ex) {
84+
final Media m = log.getMedia();
85+
86+
if (m != null) {
87+
if (m.getPath() != null) {
88+
extentTest.log(log.getStatus(),
89+
MediaEntityBuilder.createScreenCaptureFromPath(m.getPath()).build());
90+
}
91+
if (((ScreenCapture) m).getBase64() != null) {
92+
extentTest.log(log.getStatus(),
93+
MediaEntityBuilder.createScreenCaptureFromBase64String(((ScreenCapture) m).getBase64()).build());
94+
}
95+
}
96+
97+
if (ex != null) {
98+
if (!extentTest.getModel().hasLog()) {
99+
extentTest.log(log.getStatus(), log.getDetails());
100+
}
101+
102+
final List<Log> logs = extentTest.getModel().getLogs();
103+
final Log lastLog = logs.get(logs.size() - 1);
104+
lastLog.setException(ex);
105+
extentTest.getModel().getExceptions().add(ex);
89106
}
90107
}
91108

92-
private void addMedia(Test test, ExtentTest extentTest) {
109+
private void constructTestMedia(final Test test, final ExtentTest extentTest) {
93110
if (test.getMedia() != null) {
94111
for (Media m : test.getMedia()) {
95112
if (m.getPath() != null) {
@@ -100,4 +117,5 @@ private void addMedia(Test test, ExtentTest extentTest) {
100117
}
101118
}
102119
}
120+
103121
}

src/main/java/com/aventstack/extentreports/gson/BddTypeAdapter.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,16 @@
1111
import com.google.gson.stream.JsonWriter;
1212

1313
public class BddTypeAdapter extends TypeAdapter<Class<? extends IGherkinFormatterModel>> {
14+
1415
private static final Logger LOG = Logger.getLogger(BddTypeAdapter.class.getName());
1516

1617
@SuppressWarnings("unchecked")
1718
@Override
1819
public Class<? extends IGherkinFormatterModel> read(final JsonReader reader) throws IOException {
19-
int cycle = 0;
2020
while (reader.hasNext()) {
21-
JsonToken token = reader.peek();
21+
final JsonToken token = reader.peek();
2222
if ("string".equalsIgnoreCase(token.name())) {
23-
token = reader.peek();
24-
String s = reader.nextString();
23+
final String s = reader.nextString();
2524
if (s != null && !s.isEmpty()) {
2625
try {
2726
return (Class<? extends IGherkinFormatterModel>) Class.forName(s);
@@ -30,8 +29,6 @@ public Class<? extends IGherkinFormatterModel> read(final JsonReader reader) thr
3029
}
3130
}
3231
}
33-
if (cycle++ > 10)
34-
return null;
3532
}
3633
return null;
3734
}

src/main/java/com/aventstack/extentreports/gson/BddTypeAdapterFactory.java

Lines changed: 0 additions & 16 deletions
This file was deleted.

src/main/java/com/aventstack/extentreports/gson/GsonExtentTypeAdapterBuilder.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66
import com.google.gson.GsonBuilder;
77

88
public class GsonExtentTypeAdapterBuilder {
9+
910
public static Builder builder() {
1011
return new Builder();
1112
}
1213

1314
public static class Builder {
15+
1416
GsonBuilder builder = new GsonBuilder();
1517

16-
public Builder withBddTypeAdapterFactory() {
17-
builder.registerTypeAdapterFactory(new BddTypeAdapterFactory());
18+
public Builder withGsonTypeAdapterFactory() {
19+
builder.registerTypeAdapterFactory(new GsonTypeAdapterFactory());
1820
return this;
1921
}
2022

@@ -26,5 +28,7 @@ public Builder withScreenCaptureTypeAdapter() {
2628
public Gson build() {
2729
return builder.create();
2830
}
31+
2932
}
33+
3034
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.aventstack.extentreports.gson;
2+
3+
import com.aventstack.extentreports.gherkin.model.IGherkinFormatterModel;
4+
import com.google.gson.Gson;
5+
import com.google.gson.TypeAdapter;
6+
import com.google.gson.TypeAdapterFactory;
7+
import com.google.gson.reflect.TypeToken;
8+
9+
public class GsonTypeAdapterFactory implements TypeAdapterFactory {
10+
11+
@SuppressWarnings("unchecked")
12+
@Override
13+
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
14+
if (Class.class.isAssignableFrom(type.getRawType()) &&
15+
type.getType().getTypeName().indexOf(IGherkinFormatterModel.class.getTypeName()) >= 0) {
16+
return (TypeAdapter<T>) new BddTypeAdapter();
17+
}
18+
19+
return null;
20+
}
21+
22+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.aventstack.extentreports.gson;
2+
3+
import com.google.gson.TypeAdapter;
4+
import com.google.gson.stream.JsonReader;
5+
import com.google.gson.stream.JsonWriter;
6+
7+
import java.io.IOException;
8+
9+
public class ThrowableTypeAdapter extends TypeAdapter<Throwable> {
10+
11+
@Override
12+
public Throwable read(final JsonReader reader) {
13+
return new UnsupportedOperationException();
14+
}
15+
16+
@Override
17+
public void write(final JsonWriter out, final Throwable value) throws IOException {
18+
if (value == null) {
19+
out.nullValue();
20+
return;
21+
}
22+
23+
out.beginObject();
24+
out.name("type");
25+
out.value(value.getClass().getSimpleName());
26+
27+
out.name("message");
28+
out.value(value.getMessage());
29+
30+
final Throwable cause = value.getCause();
31+
if (cause != null) {
32+
out.name("cause");
33+
write(out, cause);
34+
}
35+
36+
out.endObject();
37+
}
38+
}

src/main/java/com/aventstack/extentreports/model/ExceptionInfo.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@
1111
@Setter
1212
@ToString
1313
public class ExceptionInfo extends NamedAttribute implements Serializable, BaseEntity {
14+
1415
private static final long serialVersionUID = -8152865623044194249L;
15-
private Throwable exception;
16+
17+
private transient Throwable exception;
1618
private String stackTrace;
17-
19+
1820
@Builder
1921
public ExceptionInfo(Throwable exception, String name, String stackTrace) {
2022
super(name);
2123
this.exception = exception;
2224
this.stackTrace = stackTrace;
2325
}
26+
2427
}

src/main/java/com/aventstack/extentreports/model/Test.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ public void addChild(Test child) {
8383

8484
private void end(Status evtStatus) {
8585
setStatus(Status.max(status, evtStatus));
86-
if (useNaturalConf)
86+
if (useNaturalConf) {
8787
propagateTime();
88+
}
8889
}
8990

9091
private void propagateTime() {

0 commit comments

Comments
 (0)