Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add video display in tests #400

Merged
merged 6 commits into from
Jun 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 34 additions & 1 deletion src/main/java/com/aventstack/extentreports/ExtentTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.aventstack.extentreports.model.RunResult;
import com.aventstack.extentreports.model.ScreenCapture;
import com.aventstack.extentreports.model.Test;
import com.aventstack.extentreports.model.Video;
import com.aventstack.extentreports.model.service.ExceptionInfoService;
import com.aventstack.extentreports.util.Assert;

Expand Down Expand Up @@ -1110,7 +1111,7 @@ public ExtentTest addScreenCaptureFromPath(String path) {
public ExtentTest addScreenCaptureFromBase64String(String base64, String title) {
Assert.notEmpty(base64, "ScreenCapture's base64 string must not be null or empty");
if (!base64.startsWith("data:"))
base64 = "data:image/png;base64," + base64;
base64 = ScreenCapture.BASE64_ENCODED + base64;
Media m = ScreenCapture.builder().base64(base64).title(title).build();
model.addMedia(m);
extent.onMediaAdded(m, model);
Expand All @@ -1120,4 +1121,36 @@ public ExtentTest addScreenCaptureFromBase64String(String base64, String title)
public ExtentTest addScreenCaptureFromBase64String(String base64) {
return addScreenCaptureFromBase64String(base64, null);
}

public ExtentTest addVideoFromPath(String path, String title) {
Assert.notEmpty(path, "Video path must not be null or empty");
Media m = Video.builder().path(path).title(title).build();
model.addMedia(m);
extent.onMediaAdded(m, model);
return this;
}

public ExtentTest addVideoFromPath(String path) {
return addVideoFromPath(path, null);
}

public ExtentTest addVideoFromBase64String(String base64, String title) {
Assert.notEmpty(base64, "Video's base64 string must not be null or empty");
if (!base64.startsWith("data:"))
base64 = Video.BASE64_ENCODED + base64;
Media m = Video.builder().base64(base64).title(title).build();
model.addMedia(m);
extent.onMediaAdded(m, model);
return this;
}

public ExtentTest addVideoFromBase64String(String base64) {
return addVideoFromBase64String(base64, null);
}

public ExtentTest addMedia(Media m) {
model.addMedia(m);
extent.onMediaAdded(m, model);
return this;
}
}
27 changes: 25 additions & 2 deletions src/main/java/com/aventstack/extentreports/MediaEntityBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

import com.aventstack.extentreports.model.Media;
import com.aventstack.extentreports.model.ScreenCapture;
import com.aventstack.extentreports.model.Video;
import com.aventstack.extentreports.util.Assert;

/**
* Media builder for base64 and binary screenshots
*
*/
public class MediaEntityBuilder {
private static final String BASE64_ENCODED = "data:image/png;base64,";

private static ThreadLocal<Media> media = new ThreadLocal<>();

private static class MediaBuilderInstance {
Expand Down Expand Up @@ -43,12 +44,34 @@ public static MediaEntityBuilder createScreenCaptureFromPath(String path) {
public static MediaEntityBuilder createScreenCaptureFromBase64String(String base64, String title) {
Assert.notEmpty(base64, "ScreenCapture's base64 string must not be null or empty");
if (!base64.startsWith("data:"))
base64 = BASE64_ENCODED + base64;
base64 = ScreenCapture.BASE64_ENCODED + base64;
media.set(ScreenCapture.builder().base64(base64).title(title).build());
return getInstance();
}

public static MediaEntityBuilder createScreenCaptureFromBase64String(String base64) {
return createScreenCaptureFromBase64String(base64, null);
}

public static MediaEntityBuilder createVideoFromPath(String path, String title) {
Assert.notEmpty(path, "Video path must not be null or empty");
media.set(Video.builder().path(path).title(title).build());
return getInstance();
}

public static MediaEntityBuilder createVideoFromPath(String path) {
return createVideoFromPath(path, null);
}

public static MediaEntityBuilder createVideoFromBase64String(String base64, String title) {
Assert.notEmpty(base64, "Video's base64 string must not be null or empty");
if (!base64.startsWith("data:"))
base64 = Video.BASE64_ENCODED + base64;
media.set(Video.builder().base64(base64).title(title).build());
return getInstance();
}

public static MediaEntityBuilder createVideoFromBase64String(String base64) {
return createVideoFromBase64String(base64, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public JsonDeserializer(final File f) {
public List<Test> deserialize() throws IOException {
Gson gson = GsonExtentTypeAdapterBuilder.builder()
.withBddTypeAdapterFactory()
.withScreenCaptureTypeAdapter()
.withMediaTypeAdapter()
.build();
String json = new String(Files.readAllBytes(f.toPath()));
Type t = new TypeToken<ArrayList<Test>>(){}.getType();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.aventstack.extentreports.append;

import java.io.IOException;

import com.aventstack.extentreports.model.Media;
import com.aventstack.extentreports.model.service.MediaService;
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;

public class MediaTypeAdapter extends TypeAdapter<Media> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for writing tests for this :)


@Override
public void write(JsonWriter out, Media value) throws IOException {
}

@Override
public Media read(JsonReader reader) throws IOException {
reader.beginObject();
String fieldName = null;
int cycle = 0;

String type = null;
String path = null;
String resolvedPath = null;
String title = null;
String base64 = null;

while (reader.hasNext()) {
JsonToken token = reader.peek();
if (token.equals(JsonToken.NAME)) {
fieldName = reader.nextName();
}
if ("string".equalsIgnoreCase(token.name()) && fieldName.equalsIgnoreCase("type")) {
token = reader.peek();
type = reader.nextString();
}
if ("string".equalsIgnoreCase(token.name()) && fieldName.equalsIgnoreCase("path")) {
token = reader.peek();
path = reader.nextString();
}
if ("string".equalsIgnoreCase(token.name()) && fieldName.equalsIgnoreCase("resolvedPath")) {
token = reader.peek();
resolvedPath = reader.nextString();
}
if ("string".equalsIgnoreCase(token.name()) && fieldName.equalsIgnoreCase("title")) {
token = reader.peek();
title = reader.nextString();
}
if ("string".equalsIgnoreCase(token.name()) && fieldName.equalsIgnoreCase("base64")) {
token = reader.peek();
base64 = reader.nextString();
}
if (cycle++ > 10)
return MediaService.createMedia(type, path, resolvedPath, title, base64);
}
reader.endObject();
return MediaService.createMedia(type, path, resolvedPath, title, base64);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@
import com.aventstack.extentreports.ExtentReports;
import com.aventstack.extentreports.ExtentTest;
import com.aventstack.extentreports.GherkinKeyword;
import com.aventstack.extentreports.MediaEntityBuilder;
import com.aventstack.extentreports.model.Log;
import com.aventstack.extentreports.model.Media;
import com.aventstack.extentreports.model.ScreenCapture;
import com.aventstack.extentreports.model.Test;

public class RawEntityConverter {
Expand Down Expand Up @@ -79,24 +77,14 @@ else if (log.hasMedia())
}

private void addMedia(Log log, ExtentTest extentTest, Throwable ex) {
Media m = log.getMedia();
if (m.getPath() != null) {
extentTest.log(log.getStatus(), ex,
MediaEntityBuilder.createScreenCaptureFromPath(m.getPath()).build());
} else if (((ScreenCapture) m).getBase64() != null) {
extentTest.log(log.getStatus(), ex,
MediaEntityBuilder.createScreenCaptureFromBase64String(((ScreenCapture) m).getBase64()).build());
}
Media m = log.getMedia();
extentTest.log(log.getStatus(), ex, m);
}

private void addMedia(Test test, ExtentTest extentTest) {
if (test.getMedia() != null) {
for (Media m : test.getMedia()) {
if (m.getPath() != null) {
extentTest.addScreenCaptureFromPath(m.getPath());
} else if (m instanceof ScreenCapture) {
extentTest.addScreenCaptureFromBase64String(((ScreenCapture) m).getBase64());
}
extentTest.addMedia(m);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.aventstack.extentreports.gson;

import com.aventstack.extentreports.append.ScreenCaptureTypeAdapter;
import com.aventstack.extentreports.append.MediaTypeAdapter;
import com.aventstack.extentreports.model.Media;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
Expand All @@ -18,8 +18,9 @@ public Builder withBddTypeAdapterFactory() {
return this;
}

public Builder withScreenCaptureTypeAdapter() {
builder.registerTypeAdapter(Media.class, new ScreenCaptureTypeAdapter());
public Builder withMediaTypeAdapter() {
//builder.registerTypeAdapter(Media.class, new ScreenCaptureTypeAdapter());
builder.registerTypeAdapter(Media.class, new MediaTypeAdapter());
return this;
}

Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/aventstack/extentreports/model/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,20 @@ public final boolean hasException() {

public final void addMedia(Media media) {
if (media != null && ((media.getPath() != null || media.getResolvedPath() != null)
|| media instanceof ScreenCapture && ((ScreenCapture) media).getBase64() != null))
|| (media instanceof ScreenCapture && ((ScreenCapture) media).getBase64() != null)
|| (media instanceof Video && ((Video) media).getBase64() != null)))
this.media = media;
}

public final boolean hasMedia() {
return media != null;
}

public final boolean hasScreenCapture() {
return media != null && media instanceof ScreenCapture;
}

public final boolean hasVideo() {
return media != null && media instanceof Video;
}
}
5 changes: 5 additions & 0 deletions src/main/java/com/aventstack/extentreports/model/Media.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,13 @@
public class Media implements Serializable, BaseEntity, MetaDataStorable {
private static final long serialVersionUID = 5428859443090457608L;

private MediaType type;
private String path;
private String title;
private String resolvedPath;
private transient Map<String, Object> infoMap;

public enum MediaType {
SCREENCAPTURE, VIDEO
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
@Getter
@Setter
public class ScreenCapture extends Media implements Serializable {
private static final long serialVersionUID = -3047762572007885369L;
private static final long serialVersionUID = -3047762572007885369L;

public static final String BASE64_ENCODED = "data:image/png;base64,";

private String base64;
private String base64;

@Builder
public ScreenCapture(String path, String title, String resolvedPath, String base64) {
super(path, title, resolvedPath, new HashMap<String, Object>());
this.base64 = base64;
}
@Builder
public ScreenCapture(String path, String title, String resolvedPath, String base64) {
super(MediaType.SCREENCAPTURE, path, title, resolvedPath, new HashMap<String, Object>());
this.base64 = base64;
}
}
12 changes: 11 additions & 1 deletion src/main/java/com/aventstack/extentreports/model/Test.java
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,24 @@ public String getFullName() {

public void addMedia(Media m) {
if (m != null
&& (m.getPath() != null || m.getResolvedPath() != null || ((ScreenCapture) m).getBase64() != null))
&& (m.getPath() != null || m.getResolvedPath() != null ||
(m instanceof ScreenCapture && ((ScreenCapture) m).getBase64() != null) ||
(m instanceof Video && ((Video) m).getBase64() != null)))
media.add(m);
end(status);
}

public boolean hasScreenCapture() {
return !media.isEmpty() && media.stream().anyMatch(x -> x instanceof ScreenCapture);
}

public boolean hasVideo() {
return !media.isEmpty() && media.stream().anyMatch(x -> x instanceof Video);
}

public boolean hasMedia() {
return !media.isEmpty() && media.stream().anyMatch(x -> x instanceof Media);
}

public long timeTaken() {
return endTime.getTime() - startTime.getTime();
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/com/aventstack/extentreports/model/Video.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.aventstack.extentreports.model;

import java.io.Serializable;
import java.util.HashMap;

import lombok.Builder;
import lombok.Getter;
import lombok.Setter;

@Getter
@Setter
public class Video extends Media implements Serializable {
private static final long serialVersionUID = -6874043323709622353L;

public static final String BASE64_ENCODED = "data:video/mp4;base64,";

private String base64;

@Builder
public Video(String path, String title, String resolvedPath, String base64) {
super(MediaType.VIDEO, path, title, resolvedPath, new HashMap<String, Object>());
this.base64 = base64;
}
}
Loading