Skip to content

Commit d15cba5

Browse files
authored
Merge pull request #48 from AutomateThePlanet/smpInternal
Smp internal release 31/10/2024
2 parents f70deed + 5e3be3c commit d15cba5

File tree

11 files changed

+177
-56
lines changed

11 files changed

+177
-56
lines changed

bellatrix.core/src/main/java/solutions/bellatrix/core/assertions/EntitiesAsserter.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,15 @@
1616

1717
import java.lang.reflect.Method;
1818
import java.time.LocalDateTime;
19+
import java.time.OffsetDateTime;
1920
import java.util.ArrayList;
2021
import java.util.Arrays;
2122
import java.util.List;
2223

2324
public class EntitiesAsserter {
2425
public static <TEntity> Boolean areEqual(TEntity expectedObject, TEntity realObject, DateTimeDeltaType deltaType, int deltaQuantity, String... propertiesNotToCompare) {
2526
List<Exception> failedAssertions = assertAreEqualsInternal(expectedObject, realObject, deltaType, deltaQuantity, propertiesNotToCompare);
26-
if (failedAssertions.size() > 1) {
27-
return false;
28-
}
29-
return true;
27+
return failedAssertions.size() <= 1;
3028
}
3129
public static <TEntity> Boolean areEqual(TEntity expectedObject, TEntity realObject, String... propertiesNotToCompare) {
3230
return areEqual(expectedObject, realObject, DateTimeDeltaType.MILLISECONDS, 300, propertiesNotToCompare);
@@ -69,13 +67,20 @@ private static <TEntity> List<Exception> assertAreEqualsInternal(TEntity expecte
6967

7068
try {
7169
if (currentRealProperty.getReturnType() == LocalDateTime.class) {
70+
assert currentExpectedProperty != null;
7271
LocalDateTimeAssert.areEqual(
7372
(LocalDateTime)currentExpectedProperty.invoke(expectedObject),
7473
(LocalDateTime)currentRealProperty.invoke(realObject),
7574
deltaType, deltaQuantity, exceptionMessage);
75+
} else if (currentRealProperty.getReturnType() == OffsetDateTime.class) {
76+
assert currentExpectedProperty != null;
77+
LocalDateTimeAssert.areEqual(
78+
((OffsetDateTime)currentExpectedProperty.invoke(expectedObject)).toLocalDateTime(),
79+
((OffsetDateTime)currentRealProperty.invoke(realObject)).toLocalDateTime(),
80+
deltaType, deltaQuantity, exceptionMessage);
7681
} else {
7782
Assertions.assertEquals(
78-
currentExpectedProperty.invoke(expectedObject),
83+
currentExpectedProperty != null ? currentExpectedProperty.invoke(expectedObject) : null,
7984
currentRealProperty.invoke(realObject),
8085
exceptionMessage);
8186
}

bellatrix.core/src/main/java/solutions/bellatrix/core/assertions/LocalDateTimeAssert.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ else if (actualDate == null){
3737
}
3838

3939
}
40-
public static void areEqual(LocalDateTime expectedDate, LocalDateTime actualDate, Duration expectedDelta, String exceptionMessage) throws Exception {
40+
41+
public static void areEqual(LocalDateTime expectedDate, LocalDateTime actualDate, Duration expectedDelta, String exceptionMessage) {
4142
if (expectedDate == null && actualDate == null){
4243
return;
4344
}
@@ -54,7 +55,7 @@ else if (actualDate == null){
5455
{
5556
var message = exceptionMessage+"\nExpected Date: "+expectedDate+", Actual Date: "+actualDate+
5657
" \nExpected Delta: "+expectedDelta+", Actual Delta: "+actualDelta;
57-
throw new Exception(message);
58+
throw new RuntimeException(message);
5859
}
5960
}
6061
private static Duration getTimeSpanDeltaByType(DateTimeDeltaType type, int count) throws UnsupportedOperationException {

bellatrix.web/src/main/java/solutions/bellatrix/web/components/WebComponent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ public WebElement getWrappedElement() {
119119
try {
120120
wrappedElement.isDisplayed(); // checking if getting property throws exception
121121
return wrappedElement;
122-
} catch (StaleElementReferenceException | NoSuchElementException | NullPointerException ex) {
122+
} catch (StaleElementReferenceException | NoSuchElementException | NullPointerException | ScriptTimeoutException ex ) {
123123
return findElement();
124124
}
125125
}

bellatrix.web/src/main/java/solutions/bellatrix/web/infrastructure/BrowserConfiguration.java

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import org.openqa.selenium.Platform;
1919

2020
import java.util.HashMap;
21+
import java.util.Objects;
2122

2223
public class BrowserConfiguration {
2324
@Setter @Getter private Browser browser;
@@ -72,25 +73,18 @@ public BrowserConfiguration(DeviceName deviceName, Lifecycle browserBehavior, St
7273

7374
@Override
7475
public boolean equals(Object obj) {
75-
if (!(obj instanceof BrowserConfiguration))
76-
return false;
77-
BrowserConfiguration that = (BrowserConfiguration)obj;
78-
if (!((this.getBrowser() == null) ? (that.getBrowser() == null) : this.getBrowser().equals(that.getBrowser())))
79-
return false;
80-
if (this.deviceName != that.deviceName)
81-
return false;
82-
if (!(this.getLifecycle() == null ? that.getLifecycle() == null : this.getLifecycle().equals(that.getLifecycle())))
83-
return false;
84-
if (this.getHeight() != that.getHeight())
85-
return false;
86-
if (this.getWidth() != that.getWidth())
87-
return false;
88-
if (this.getVersion() != that.getVersion())
89-
return false;
90-
if (!(this.getPlatform() == null ? that.getPlatform() == null : this.getPlatform().equals(that.getPlatform())))
91-
return false;
92-
if (!(this.getDriverOptions() == null ? that.getDriverOptions() == null : this.getDriverOptions().equals(that.getDriverOptions())))
93-
return false;
94-
return true;
76+
if (this == obj) return true;
77+
if (obj == null || getClass() != obj.getClass()) return false;
78+
79+
BrowserConfiguration that = (BrowserConfiguration) obj;
80+
81+
if (!Objects.equals(this.getBrowser(), that.getBrowser())) return false;
82+
if (!Objects.equals(this.deviceName, that.deviceName)) return false;
83+
if (!Objects.equals(this.getLifecycle(), that.getLifecycle())) return false;
84+
if (this.getHeight() != that.getHeight()) return false;
85+
if (this.getWidth() != that.getWidth()) return false;
86+
if (this.getVersion() != that.getVersion()) return false;
87+
if (!Objects.equals(this.getPlatform(), that.getPlatform())) return false;
88+
return Objects.equals(this.getDriverOptions(), that.getDriverOptions());
9589
}
9690
}

bellatrix.web/src/main/java/solutions/bellatrix/web/infrastructure/BrowserLifecyclePlugin.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,6 @@ private boolean shouldRestartBrowser() {
109109
return true;
110110
} else if (!previousConfiguration.equals(currentConfiguration)) {
111111
return true;
112-
} else if (currentConfiguration.getLifecycle() == Lifecycle.REUSE_IF_STARTED) {
113-
return false;
114-
} else if (currentConfiguration.getLifecycle() == Lifecycle.RESTART_EVERY_TIME) {
115-
return true;
116112
} else {
117113
return false;
118114
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package solutions.bellatrix.web.infrastructure;
2+
3+
import com.google.gson.*;
4+
import com.google.gson.reflect.TypeToken;
5+
import com.google.gson.stream.JsonReader;
6+
import com.google.gson.stream.JsonToken;
7+
import com.google.gson.stream.JsonWriter;
8+
9+
import java.io.IOException;
10+
import java.lang.reflect.ParameterizedType;
11+
import java.lang.reflect.Type;
12+
import java.util.ArrayList;
13+
import java.util.Collection;
14+
import java.util.List;
15+
16+
public class EmptyObjectTypeAdapterFactory implements TypeAdapterFactory {
17+
@Override
18+
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
19+
TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
20+
21+
return new TypeAdapter<T>() {
22+
@Override
23+
public void write(JsonWriter out, T value) throws IOException {
24+
delegate.write(out, value);
25+
}
26+
27+
@Override
28+
public T read(JsonReader in) throws IOException {
29+
if (in.peek() == JsonToken.BEGIN_ARRAY) {
30+
JsonArray arr = new JsonParser().parse(in).getAsJsonArray();
31+
if (arr.size() == 0) {
32+
if (isCollectionType(type.getType())) {
33+
return delegate.fromJsonTree(arr);
34+
} else {
35+
return delegate.fromJsonTree(new JsonObject());
36+
}
37+
}
38+
return delegate.fromJsonTree(arr);
39+
}
40+
return delegate.read(in);
41+
}
42+
};
43+
}
44+
45+
private boolean isCollectionType(Type type) {
46+
if (type instanceof Class<?>) {
47+
return Collection.class.isAssignableFrom((Class<?>)type);
48+
} else if (type instanceof ParameterizedType) {
49+
return isCollectionType(((ParameterizedType)type).getRawType());
50+
}
51+
return false;
52+
}
53+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package solutions.bellatrix.web.infrastructure;
2+
3+
import com.google.gson.*;
4+
5+
import java.lang.reflect.Type;
6+
import java.time.LocalDateTime;
7+
import java.time.format.DateTimeFormatter;
8+
9+
public class LocalDateTimeAdapter implements JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
10+
private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
11+
12+
@Override
13+
public JsonElement serialize(LocalDateTime src, Type typeOfSrc, JsonSerializationContext context) {
14+
return new JsonPrimitive(formatter.format(src).replace("+00:00", ""));
15+
}
16+
17+
@Override
18+
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
19+
throws JsonParseException {
20+
return LocalDateTime.parse(json.getAsString().replace("+00:00", ""), formatter);
21+
}
22+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package solutions.bellatrix.web.infrastructure;
2+
3+
import com.google.gson.*;
4+
5+
import java.lang.reflect.Type;
6+
import java.time.LocalDateTime;
7+
import java.time.OffsetDateTime;
8+
import java.time.ZoneOffset;
9+
import java.time.format.DateTimeFormatter;
10+
11+
public class OffsetDateTimeTypeAdapter implements JsonSerializer<OffsetDateTime>, JsonDeserializer<OffsetDateTime> {
12+
private final DateTimeFormatter formatter = DateTimeFormatter.ISO_OFFSET_DATE_TIME;
13+
private final DateTimeFormatter localDateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
14+
15+
@Override
16+
public JsonElement serialize(OffsetDateTime src, Type typeOfSrc, JsonSerializationContext context) {
17+
return new JsonPrimitive(formatter.format(src));
18+
}
19+
20+
@Override
21+
public OffsetDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
22+
throws JsonParseException {
23+
OffsetDateTime result;
24+
try {
25+
result = OffsetDateTime.parse(json.getAsString(), formatter);
26+
}
27+
catch(Exception ex) {
28+
result = LocalDateTime.parse(json.getAsString(), localDateTimeFormatter).atOffset(ZoneOffset.UTC);
29+
}
30+
31+
return result;
32+
}
33+
}

bellatrix.web/src/main/java/solutions/bellatrix/web/infrastructure/ProxyServer.java

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@
1313

1414
package solutions.bellatrix.web.infrastructure;
1515

16-
import com.google.gson.Gson;
17-
import com.google.gson.JsonArray;
18-
import com.google.gson.JsonObject;
19-
import com.google.gson.JsonParser;
16+
import com.google.gson.*;
2017
import lombok.SneakyThrows;
2118
import net.lightbody.bmp.BrowserMobProxyServer;
2219
import net.lightbody.bmp.core.har.HarEntry;
@@ -37,6 +34,8 @@
3734
import java.lang.reflect.Type;
3835
import java.net.ServerSocket;
3936
import java.time.Duration;
37+
import java.time.LocalDateTime;
38+
import java.time.OffsetDateTime;
4039
import java.util.ArrayList;
4140
import java.util.Arrays;
4241
import java.util.List;
@@ -55,6 +54,8 @@ public class ProxyServer {
5554
HttpStatus.SC_PARTIAL_CONTENT,
5655
HttpStatus.SC_MULTI_STATUS);
5756

57+
private static Gson gson;
58+
5859
@SneakyThrows
5960
public static int init() {
6061
Log.info("Starting Proxy Service...");
@@ -64,6 +65,11 @@ public static int init() {
6465
PROXY_SERVER.get().enableHarCaptureTypes(CaptureType.REQUEST_CONTENT, CaptureType.RESPONSE_CONTENT, CaptureType.REQUEST_HEADERS);
6566
PORT.set(port);
6667
Log.info("Proxy Service Started at Port %s".formatted(port));
68+
gson = new GsonBuilder()
69+
.registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
70+
.registerTypeAdapter(OffsetDateTime.class, new OffsetDateTimeTypeAdapter())
71+
.registerTypeAdapterFactory(new EmptyObjectTypeAdapterFactory())
72+
.create();
6773
return port;
6874
}
6975

@@ -164,7 +170,7 @@ public static void waitForResponse(WebDriver driver, String requestPartialUrl, H
164170
catch (TimeoutException exception){
165171
String allUrlsString = getSimilarRequestsString(requestPartialUrl, allHarEntries);
166172

167-
throw new AssertionFailedError(String.format("The expected response with request URL '%s' with method %s is not loaded! \r\nSimilar requests: %s", requestPartialUrl, httpMethod, allUrlsString));
173+
throw new RuntimeException(String.format("The expected response with request URL '%s' with method %s is not loaded! \r\nSimilar requests: %s", requestPartialUrl, httpMethod, allUrlsString));
168174
}
169175
}
170176

@@ -220,7 +226,7 @@ public static <T> T getLastRequest(Class<T> requestModelClass) {
220226
return getCapturedEntries().stream()
221227
.map(HarEntry::getRequest)
222228
.filter(request -> request.getPostData() != null)
223-
.map(request -> new Gson().fromJson(request.getPostData().getText(), requestModelClass))
229+
.map(request -> gson.fromJson(request.getPostData().getText(), requestModelClass))
224230
.reduce((first, second) -> second)
225231
.orElse(null);
226232
}
@@ -229,7 +235,7 @@ public static <T> T getLastResponse(Class<T> responseModelClass) {
229235
return getCapturedEntries().stream()
230236
.map(HarEntry::getResponse)
231237
.filter(response -> response.getContent() != null)
232-
.map(response -> new Gson().fromJson(getDataObject(response.getContent().getText()), responseModelClass))
238+
.map(response -> gson.fromJson(getDataObject(response.getContent().getText()), responseModelClass))
233239
.reduce((first, second) -> second)
234240
.orElse(null);
235241
}
@@ -238,13 +244,13 @@ public static <T> T getRequestByIndex(int index, Class<T> requestModelClass) {
238244
var entries = getCapturedEntries();
239245
var harEntry = entries.get(index);
240246
String json = harEntry.getRequest().getPostData().getText();
241-
return new Gson().fromJson(json, requestModelClass);
247+
return gson.fromJson(json, requestModelClass);
242248
}
243249

244250
public static <T> T getResponseByIndex(int index, Class<T> responseModelClass) {
245251
var harEntry = getCapturedEntries().get(index);
246252
String json = harEntry.getResponse().getContent().getText();
247-
return new Gson().fromJson(getDataObject(json), responseModelClass);
253+
return gson.fromJson(getDataObject(json), responseModelClass);
248254
}
249255

250256
public static <T> T getRequestByUrl(String url, String httpMethod, Class<T> requestModelClass) {
@@ -258,7 +264,7 @@ public static <T> T getRequestByUrl(String url, String httpMethod, Class<T> requ
258264
}
259265
String json = harEntry.getRequest().getPostData().getText();
260266
try {
261-
return new Gson().fromJson(json, requestModelClass);
267+
return gson.fromJson(json, requestModelClass);
262268
}
263269
catch (Exception e) {
264270
throw new RuntimeException("Error occurred while converting json to model. Json was: %s".formatted(json), e);
@@ -276,7 +282,7 @@ public static <T> T getRequestByUrl(String url, String httpMethod, Type modelTyp
276282
}
277283
String json = harEntry.getRequest().getPostData().getText();
278284
try {
279-
return new Gson().fromJson(json, modelType);
285+
return gson.fromJson(json, modelType);
280286
}
281287
catch (Exception e) {
282288
throw new RuntimeException("Error occurred while converting json to model. Json was: %s".formatted(json), e);
@@ -295,7 +301,7 @@ public static <T> T getResponseByUrl(String url, String httpMethod, Class<T> res
295301
}
296302
String json = harEntry.getResponse().getContent().getText();
297303
try {
298-
return new Gson().fromJson(getDataObject(json), responseModelClass);
304+
return gson.fromJson(getDataObject(json), responseModelClass);
299305
}
300306
catch (Exception ex){
301307
throw new AssertionFailedError("Cannot get JSON body from the string: " + json + ". Error was: " + ex.getMessage());
@@ -313,7 +319,12 @@ public static <T> T getResponseByUrl(String url, String httpMethod, Type respons
313319
return null;
314320
}
315321
String json = harEntry.getResponse().getContent().getText();
316-
return new Gson().fromJson(getDataObject(json), responseModelType);
322+
try {
323+
return gson.fromJson(getDataObject(json), responseModelType);
324+
}
325+
catch (Exception ex) {
326+
throw new RuntimeException("Failed to Serialize Json to Object: \n Entity Type: %s\n Json was: %s".formatted(responseModelType.getTypeName(), json));
327+
}
317328
}
318329

319330
public static void blockRequestByUrl(String url, HttpMethod httpMethod) {

0 commit comments

Comments
 (0)