Skip to content

Commit b465c9f

Browse files
Merge pull request #64 from LambdaTest/stage
Release 1.0.24-beta.1
2 parents c84b6d2 + ef0098f commit b465c9f

8 files changed

Lines changed: 396 additions & 4 deletions

File tree

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
}
77

88
group = 'io.github.lambdatest'
9-
version = '1.0.23'
9+
version = '1.0.24-beta.1'
1010
description = 'lambdatest-java-sdk'
1111

1212
repositories {
@@ -82,7 +82,7 @@ afterEvaluate {
8282
mavenJava(MavenPublication) {
8383
groupId = 'io.github.lambdatest'
8484
artifactId = 'lambdatest-java-sdk'
85-
version = '1.0.23'
85+
version = '1.0.24-beta.1'
8686

8787
pom {
8888
name.set('LambdaTest Java SDK')

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<modelVersion>4.0.0</modelVersion>
77
<groupId>io.github.lambdatest</groupId>
88
<artifactId>lambdatest-java-sdk</artifactId>
9-
<version>1.0.23</version>
9+
<version>1.0.24-beta.1</version>
1010
<name>lambdatest-java-sdk</name>
1111
<description>LambdaTest SDK in Java</description>
1212
<url>https://www.lambdatest.com</url>
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package io.github.lambdatest;
2+
3+
import org.openqa.selenium.WebDriver;
4+
import io.github.lambdatest.utils.LoggerUtil;
5+
import io.github.lambdatest.utils.SmartUIUtil;
6+
import io.github.lambdatest.constants.Constants;
7+
import org.json.JSONObject;
8+
9+
import java.util.logging.Logger;
10+
11+
/**
12+
* Provides methods to fetch aggregate visual comparison results from SmartUI.
13+
*
14+
* <p>Two overloaded methods are available:
15+
* <ul>
16+
* <li>{@link #smartuiResults(WebDriver)} - fetches results for a specific session (driver's sessionId)</li>
17+
* <li>{@link #smartuiResults()} - fetches results for the entire active build</li>
18+
* </ul>
19+
*/
20+
public class SmartUIResults {
21+
22+
private static final Logger log = LoggerUtil.createLogger("lambdatest-java-sdk");
23+
private static final SmartUIUtil smartUIUtils = new SmartUIUtil();
24+
25+
/**
26+
* Fetches SmartUI visual comparison results for the session associated with the given WebDriver.
27+
*
28+
* <p>This method extracts the sessionId from the RemoteWebDriver and queries the SmartUI server
29+
* for screenshot data filtered by that session. The response contains screenshots grouped by name
30+
* with a summary indicating variant and screenshot counts.
31+
*
32+
* @param driver A Selenium WebDriver instance (must be a RemoteWebDriver)
33+
* @return JSONObject containing screenshots grouped by name and a summary with type "session"
34+
* @throws Exception if the driver is null, not a RemoteWebDriver, or the request fails
35+
*/
36+
public static JSONObject smartuiResults(WebDriver driver) throws Exception {
37+
if (driver == null) {
38+
throw new IllegalArgumentException(Constants.Errors.SELENIUM_DRIVER_NULL);
39+
}
40+
41+
if (!smartUIUtils.isSmartUIRunning()) {
42+
throw new IllegalStateException(Constants.Errors.SMARTUI_NOT_RUNNING);
43+
}
44+
45+
try {
46+
// Extract sessionId from the driver (null-safe)
47+
org.openqa.selenium.remote.SessionId sid = ((org.openqa.selenium.remote.RemoteWebDriver) driver).getSessionId();
48+
if (sid == null) {
49+
throw new IllegalStateException("Unable to get sessionId from the driver");
50+
}
51+
String sessionId = sid.toString();
52+
53+
log.info("Fetching SmartUI results for sessionId: " + sessionId);
54+
55+
// CLI server resolves buildId and projectToken from its context
56+
String resultsResponse = smartUIUtils.getSmartUIResults(sessionId);
57+
log.info("SmartUI results fetched successfully for sessionId: " + sessionId);
58+
59+
return new JSONObject(resultsResponse);
60+
61+
} catch (ClassCastException e) {
62+
throw new IllegalArgumentException("Driver must be an instance of RemoteWebDriver to extract sessionId", e);
63+
} catch (Exception e) {
64+
throw e;
65+
}
66+
}
67+
68+
/**
69+
* Fetches SmartUI visual comparison results for the entire active build.
70+
*
71+
* <p>This method queries the SmartUI server for all screenshot data in the current build
72+
* without filtering by session. The response contains screenshots grouped by name
73+
* with a summary indicating variant and screenshot counts.
74+
*
75+
* @return JSONObject containing screenshots grouped by name and a summary with type "build"
76+
* @throws Exception if the SmartUI server is not running or the request fails
77+
*/
78+
public static JSONObject smartuiResults() throws Exception {
79+
if (!smartUIUtils.isSmartUIRunning()) {
80+
throw new IllegalStateException(Constants.Errors.SMARTUI_NOT_RUNNING);
81+
}
82+
83+
try {
84+
log.info("Fetching SmartUI results for entire build");
85+
86+
// CLI server resolves buildId from its active build context
87+
String resultsResponse = smartUIUtils.getSmartUIResults(null);
88+
log.info("SmartUI results fetched successfully for build");
89+
90+
return new JSONObject(resultsResponse);
91+
92+
} catch (Exception e) {
93+
throw e;
94+
}
95+
}
96+
}

src/main/java/io/github/lambdatest/SmartUISnapshot.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import org.openqa.selenium.WebDriver;
44
import io.github.lambdatest.utils.LoggerUtil;
55
import io.github.lambdatest.utils.SmartUIUtil;
6+
import io.github.lambdatest.utils.WebElementResolver;
67
import io.github.lambdatest.constants.Constants;
78
import io.github.lambdatest.models.ResponseData;
89
import io.github.lambdatest.models.SnapshotResponse;
@@ -65,6 +66,13 @@ public static JSONObject smartuiSnapshot(WebDriver driver, String snapshotName,
6566
options.put("sessionId", sessionId);
6667
}
6768

69+
// Resolve any WebElement objects in element/ignoreDOM/selectDOM to CSS selectors
70+
try {
71+
WebElementResolver.resolveWebElements(jsExecutor, options);
72+
} catch (Exception e) {
73+
log.warning("Failed to resolve WebElement options: " + e.getMessage());
74+
}
75+
6876
// Convert the options map to JSON string
6977
String jsonOptions = gson.toJson(options);
7078

src/main/java/io/github/lambdatest/constants/Constants.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ interface SmartUIRoutes {
3434
public static final String SMARTUI_UPLOAD_PDF_ROUTE = "/pdf/upload";
3535
public static final String SMARTUI_BUILD_SCREENSHOTS_ROUTE = "/smartui/2.0/build/screenshots";
3636
public static final String SMARTUI_SNAPSHOT_STATUS_ROUTE = "/snapshot/status";
37+
public static final String SMARTUI_RESULTS_ROUTE = "/smartui/results";
3738
}
3839

3940
//Request methods
@@ -82,5 +83,6 @@ interface Errors {
8283
public static final String NULL_OPTIONS_OBJECT = "Options object is null or missing in request.";
8384
public static final String DEVICE_NAME_NULL = "Device name is a mandatory parameter.";
8485
public static final String SNAPSHOT_STATUS_FAILED = "Get snapshot status failed";
86+
public static final String SMARTUI_RESULTS_FAILED = "Failed to fetch SmartUI results";
8587
}
86-
}
88+
}

src/main/java/io/github/lambdatest/utils/HttpClientUtil.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,34 @@ public String getBuildScreenshotsWithPolling(String url, Map<String, String> hea
575575
}
576576
}
577577

578+
public String getSmartUIResults(String sessionId) throws IOException {
579+
try {
580+
String url = SmartUIUtil.getSmartUIServerAddress() +
581+
Constants.SmartUIRoutes.SMARTUI_RESULTS_ROUTE;
582+
if (sessionId != null && !sessionId.isEmpty()) {
583+
url += "?sessionId=" + URLEncoder.encode(sessionId, StandardCharsets.UTF_8);
584+
}
585+
586+
HttpGet request = new HttpGet(url);
587+
request.setHeader("Content-Type", "application/json");
588+
589+
log.info("Fetching SmartUI results from: " + url);
590+
591+
try (CloseableHttpResponse response = httpClient.execute(request)) {
592+
int statusCode = response.getStatusLine().getStatusCode();
593+
HttpEntity entity = response.getEntity();
594+
String responseString = entity != null ? EntityUtils.toString(entity) : null;
595+
if (statusCode == HttpStatus.SC_OK) {
596+
return responseString;
597+
} else {
598+
throw new IOException("SmartUI results request failed with status code: " + statusCode + ". Response: " + responseString);
599+
}
600+
}
601+
} catch (Exception e) {
602+
throw new IOException(Constants.Errors.SMARTUI_RESULTS_FAILED + ": " + e.getMessage(), e);
603+
}
604+
}
605+
578606
public String getSnapshotStatus(String contextId, String snapshotName, int timeout) throws IOException {
579607
try {
580608
String trimmedSnapshotName = snapshotName.trim();

src/main/java/io/github/lambdatest/utils/SmartUIUtil.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,23 @@ public BuildScreenshotsResponse getBuildScreenshots(String projectId, String bui
256256
}
257257
}
258258

259+
/**
260+
* Fetches SmartUI results for a specific session.
261+
* The CLI server resolves buildId and projectToken from its context.
262+
* @param sessionId The session ID to fetch results for (null for build-level results)
263+
* @return JSON string of SmartUI results with screenshots grouped by name and summary
264+
*/
265+
public String getSmartUIResults(String sessionId) throws Exception {
266+
try {
267+
String results = httpClient.getSmartUIResults(sessionId);
268+
log.info("Fetched SmartUI results for sessionId: " + sessionId);
269+
return results;
270+
} catch (Exception e) {
271+
log.severe("Failed to fetch SmartUI results: " + e.getMessage());
272+
throw e;
273+
}
274+
}
275+
259276
public String getSnapshotStatus(String contextId, String snapshotName, int timeout) throws Exception {
260277
try {
261278
String snapshotStatus = httpClient.getSnapshotStatus(contextId, snapshotName, timeout);

0 commit comments

Comments
 (0)