From f164434a020f92d56f13a3d92ce23631cdfa5d98 Mon Sep 17 00:00:00 2001 From: Felix P Date: Thu, 14 Mar 2024 12:39:44 +0100 Subject: [PATCH] Hide Create/Finish build. Implements IDisposable interface --- visual-dotnet/SauceLabs.Visual/VisualApi.cs | 15 +++--- .../SauceLabs.Visual/VisualClient.cs | 47 +++++++++++++++++-- 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/visual-dotnet/SauceLabs.Visual/VisualApi.cs b/visual-dotnet/SauceLabs.Visual/VisualApi.cs index faad8aaf..896b5fcb 100644 --- a/visual-dotnet/SauceLabs.Visual/VisualApi.cs +++ b/visual-dotnet/SauceLabs.Visual/VisualApi.cs @@ -1,4 +1,5 @@ -using System.Net.Http; +using System; +using System.Net.Http; using System.Net.Http.Headers; using System.Reflection; using System.Threading.Tasks; @@ -12,7 +13,7 @@ namespace SauceLabs.Visual { - internal class VisualApi where T : IHasCapabilities, IHasSessionId + internal class VisualApi : IDisposable where T : IHasCapabilities, IHasSessionId { private readonly string _username; private readonly string _accessKey; @@ -45,11 +46,6 @@ public VisualApi(T webdriver, Region region, string username, string accessKey, httpClient); } - ~VisualApi() - { - _graphQlClient.Dispose(); - } - public async Task>> CreateBuild(CreateBuildIn input) { var request = CreateAuthenticatedRequest(CreateBuildMutation.OperationDocument, CreateBuildMutation.OperationName, new { input }); @@ -98,5 +94,10 @@ private AuthenticatedGraphQLRequest CreateAuthenticatedRequest(string query, str Variables = variables }; } + + public void Dispose() + { + _graphQlClient.Dispose(); + } } } \ No newline at end of file diff --git a/visual-dotnet/SauceLabs.Visual/VisualClient.cs b/visual-dotnet/SauceLabs.Visual/VisualClient.cs index 5dc93a30..ee04169a 100644 --- a/visual-dotnet/SauceLabs.Visual/VisualClient.cs +++ b/visual-dotnet/SauceLabs.Visual/VisualClient.cs @@ -14,13 +14,15 @@ namespace SauceLabs.Visual /// /// VisualClient provides an access to Sauce Labs Visual services. /// - public class VisualClient + public class VisualClient : IDisposable { private readonly VisualApi _api; private readonly string _sessionId; private readonly string _jobId; private readonly string _sessionMetadataBlob; private readonly List _screenshotIds = new List(); + public VisualBuild Build { get; } + private readonly bool _externalBuild; public bool CaptureDom { get; set; } = false; /// @@ -38,6 +40,32 @@ public VisualClient(WebDriver wd, Region region, string username, string accessK var response = _api.WebDriverSessionInfo(_jobId, _sessionId).Result; var metadata = response.EnsureValidResponse(); _sessionMetadataBlob = metadata.Result.Blob; + + var createBuildResponse = CreateBuild(new CreateBuildOptions()).Result; + Build = new VisualBuild(createBuildResponse.Id, createBuildResponse.Url); + _externalBuild = false; + } + + /// + /// Creates a new instance of VisualClient + /// + /// the instance of the WebDriver session + /// the Sauce Labs region to connect to + /// the Sauce Labs username + /// the Sauce Labs access key + /// the options of the build creation + public VisualClient(WebDriver wd, Region region, string username, string accessKey, CreateBuildOptions buildOptions) + { + _api = new VisualApi(wd, region, username, accessKey); + _sessionId = wd.SessionId.ToString(); + _jobId = wd.Capabilities.HasCapability("jobUuid") ? wd.Capabilities.GetCapability("jobUuid").ToString() : _sessionId; + var response = _api.WebDriverSessionInfo(_jobId, _sessionId).Result; + var metadata = response.EnsureValidResponse(); + _sessionMetadataBlob = metadata.Result.Blob; + + var createBuildResponse = CreateBuild(buildOptions).Result; + Build = new VisualBuild(createBuildResponse.Id, createBuildResponse.Url); + _externalBuild = false; } /// @@ -45,7 +73,7 @@ public VisualClient(WebDriver wd, Region region, string username, string accessK /// /// the options for the build creation /// a VisualBuild instance - public async Task CreateBuild(CreateBuildOptions? options = null) + private async Task CreateBuild(CreateBuildOptions? options = null) { var result = (await _api.CreateBuild(new CreateBuildIn { @@ -61,7 +89,7 @@ public async Task CreateBuild(CreateBuildOptions? options = null) /// FinishBuild finishes a build /// /// the build to finish - public async Task FinishBuild(VisualBuild build) + private async Task FinishBuild(VisualBuild build) { (await _api.FinishBuild(build.Id)).EnsureValidResponse(); } @@ -73,14 +101,14 @@ public async Task FinishBuild(VisualBuild build) /// the name of the screenshot /// the configuration for the screenshot capture and comparison /// - public async Task VisualCheck(VisualBuild build, string name, VisualCheckOptions? options = null) + public async Task VisualCheck(string name, VisualCheckOptions? options = null) { var ignored = new List(); ignored.AddRange(options?.IgnoreRegions?.Select(r => new RegionIn(r)) ?? new List()); ignored.AddRange(options?.IgnoreElements?.Select(r => new RegionIn(r)) ?? new List()); var result = (await _api.CreateSnapshotFromWebDriver(new CreateSnapshotFromWebDriverIn( - buildUuid: build.Id, + buildUuid: Build.Id, name: name, jobId: _jobId, diffingMethod: options?.DiffingMethod ?? DiffingMethod.Simple, @@ -92,6 +120,15 @@ public async Task VisualCheck(VisualBuild build, string name, VisualChec return result.Result.Id; } + public void Dispose() + { + _api.Dispose(); + if (!_externalBuild) + { + FinishBuild(Build).Wait(); + } + } + /// /// VisualResults returns the results of screenshot comparison. ///