Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
33 changes: 33 additions & 0 deletions LambdaTest.Sdk.Utils/SmartUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ public static class SmartUI
private static readonly HttpClient HttpClient = new();
private static readonly ILogger SdkUtilsLogger = Logger.CreateLogger("LambdaTest.Sdk.Utils");


public static async Task<bool> IsSmartUIEnabled()
{
try
Expand Down Expand Up @@ -86,6 +87,38 @@ public static async Task<string> PostSnapshot(DomObject snapshot, string pkg, D
}
}

public static async Task<string> GetSnapshotStatus(string contextId, int pollTimeout, string snapshotName)
{
try
{
var url = $"{Constants.GetSmartUIServerAddress()}/snapshot/status?contextId={contextId}&pollTimeout={pollTimeout}&snapshotName={snapshotName}";

// Using statement ensures proper disposal of HttpClient
using (var client = new HttpClient())
{
client.Timeout = TimeSpan.FromHours(4);

var response = await client.GetAsync(url);

// Ensure successful status code
response.EnsureSuccessStatusCode();

var responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
}
catch (HttpRequestException e)
{
SdkUtilsLogger.LogDebug($"Snapshot Status Error: {e.Message}");
throw new Exception("Snapshot Status Error", e);
}
catch (Exception e)
{
SdkUtilsLogger.LogDebug($"Get Snapshot Status failed: {e.Message}");
throw new Exception("Get Snapshot Status failed", e);
}
}

public class Resource
{
public string content { get; set; } = string.Empty;
Expand Down
73 changes: 56 additions & 17 deletions LambdaTest.Selenium.Driver/SmartUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static class SmartUISnapshot
{
private static readonly ILogger SmartUILogger = Logger.CreateLogger("Lambdatest.Selenium.Driver");

public static async Task CaptureSnapshot(IWebDriver driver, string name, Dictionary<string, object>? options = null)
public static async Task<String> CaptureSnapshot(IWebDriver driver, string name, Dictionary<string, object>? options = null)
{
if (string.IsNullOrEmpty(name))
{
Expand All @@ -31,7 +31,7 @@ public static async Task CaptureSnapshot(IWebDriver driver, string name, Diction

if (domSerializerResponse == null)
{
throw new Exception("Failed to fetch DOM serializer script repsonse.");
throw new Exception("Failed to fetch DOM serializer script response.");
}

var domSerializerScript = JsonSerializer.Deserialize<FetchDomSerializerResponse>(domSerializerResponse, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
Expand All @@ -46,22 +46,20 @@ public static async Task CaptureSnapshot(IWebDriver driver, string name, Diction
((IJavaScriptExecutor)driver).ExecuteScript(script);

// Extract sessionId from driver
string sessionId = null;
string sessionId = "";
if (driver is RemoteWebDriver remoteDriver)
{
sessionId = remoteDriver.SessionId.ToString();
}

if (options == null)
{
options = new Dictionary<string, object>();
}
if (!string.IsNullOrEmpty(sessionId))
{
// Append sessionId to options
if (options == null)
{
options = new Dictionary<string, object>();
}
options["sessionId"] = sessionId;
}

var optionsJSON = JsonSerializer.Serialize(options);
var snapshotScript = @"
var options = " + optionsJSON + @";
Expand Down Expand Up @@ -97,26 +95,67 @@ public static async Task CaptureSnapshot(IWebDriver driver, string name, Diction
Url = domContent.Url
};

var apiResponseJSON = await LambdaTest.Sdk.Utils.SmartUI.PostSnapshot(dom, "Lambdatest.Selenium.Driver", options);
var apiResponse = JsonSerializer.Deserialize<ApiResponse>(apiResponseJSON, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

if (apiResponse?.Data?.Warnings != null && apiResponse.Data.Warnings.Count > 0)
// Handle sync parameter if present
if (options?.ContainsKey("sync") == true && (bool)options["sync"])
{
foreach (var warning in apiResponse.Data.Warnings)
var contextId = Guid.NewGuid().ToString();
options["contextId"] = contextId;

// Post Snapshot
var apiResponseJSON = await LambdaTest.Sdk.Utils.SmartUI.PostSnapshot(dom, "Lambdatest.Selenium.Driver", options);
var apiResponse = JsonSerializer.Deserialize<ApiResponse>(apiResponseJSON, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

if (apiResponse?.Data?.Warnings != null && apiResponse.Data.Warnings.Count > 0)
{
SmartUILogger.LogWarning(warning);
foreach (var warning in apiResponse.Data.Warnings)
{
SmartUILogger.LogWarning(warning);
}
}

SmartUILogger.LogInformation($"Snapshot captured: {name}");

// Get Snapshot Status
var timeout=600;
if (options.ContainsKey("timeout")){
var tempTimeout= (int)options["timeout"];
if (tempTimeout<30||tempTimeout>900){
SmartUILogger.LogWarning("Timeout value is out of range(30-900). Defaulting to 600 seconds.");
}else{
timeout=tempTimeout;
}
}
var snapshotStatusJSON = await LambdaTest.Sdk.Utils.SmartUI.GetSnapshotStatus(contextId, timeout, name);
var snapshotStatus = JsonSerializer.Deserialize<ApiResponse>(snapshotStatusJSON, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
return snapshotStatusJSON;
}
else
{
// If sync is not true, simply post the snapshot
var apiResponseJSON = await LambdaTest.Sdk.Utils.SmartUI.PostSnapshot(dom, "Lambdatest.Selenium.Driver", options);
var apiResponse = JsonSerializer.Deserialize<ApiResponse>(apiResponseJSON, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

SmartUILogger.LogInformation($"Snapshot captured: {name}");
if (apiResponse?.Data?.Warnings != null && apiResponse.Data.Warnings.Count > 0)
{
foreach (var warning in apiResponse.Data.Warnings)
{
SmartUILogger.LogWarning(warning);
}
}

SmartUILogger.LogInformation($"Snapshot captured: {name}");
}
return "";
}
catch (Exception e)
{
SmartUILogger.LogError($"SmartUI snapshot failed: {name}");
SmartUILogger.LogError(e.ToString());
return "";
}
}


private class ApiResponse
{
public ApiData Data { get; set; } = new ApiData();
Expand Down