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 Current Test/Class elements #10

Merged
merged 14 commits into from
Mar 22, 2024
1 change: 0 additions & 1 deletion visual-dotnet/SauceLabs.Visual.Tests/VisualApiTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using NUnit.Framework;
using RichardSzalay.MockHttp;
using SauceLabs.Visual.GraphQL;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,9 @@ public CreateSnapshotFromWebDriverIn(
DiffingMethod diffingMethod,
RegionIn[] regions,
bool captureDom,
string? clipSelector
string? clipSelector,
string? suiteName,
string? testName
)
{
BuildUuid = buildUuid;
Expand All @@ -50,6 +52,8 @@ public CreateSnapshotFromWebDriverIn(
SessionId = sessionId;
CaptureDom = captureDom;
ClipSelector = clipSelector;
SuiteName = suiteName;
TestName = testName;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

namespace SauceLabs.Visual.Utils
{
public static class GraphQLResponseExtension
internal static class GraphQLResponseExtension
{
public static T EnsureValidResponse<T>(this GraphQLResponse<T> response)
{
Expand Down
2 changes: 1 addition & 1 deletion visual-dotnet/SauceLabs.Visual/Utils/StringUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace SauceLabs.Visual.Utils
{
public static class StringUtils
internal static class StringUtils
{
/// <summary>
/// <c>IsNullOrEmpty</c> checks that the string null, empty or contains only whitespaces.
Expand Down
26 changes: 26 additions & 0 deletions visual-dotnet/SauceLabs.Visual/VisualCheckOptions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Diagnostics;
using System.Linq;
using OpenQA.Selenium;
using SauceLabs.Visual.Models;

Expand All @@ -14,5 +16,29 @@ public class VisualCheckOptions
public IWebElement[]? IgnoreElements { get; set; }
public bool? CaptureDom { get; set; }
public string? ClipSelector { get; set; }

/// <summary>
/// <c>SuiteName</c> manually set the SuiteName of the Test.
/// </summary>
public string? SuiteName { get; set; }
FriggaHel marked this conversation as resolved.
Show resolved Hide resolved
/// <summary>
/// <c>TestName</c> manually set the TestName of the Test.
/// </summary>
public string? TestName { get; set; }

private bool HasIncompleteTestContext() => string.IsNullOrEmpty(SuiteName) || string.IsNullOrEmpty(TestName);

internal void EnsureTestContextIsPopulated(string callerMemberName, string? previousSuiteName)
{
if (string.IsNullOrEmpty(callerMemberName) || HasIncompleteTestContext())
{
return;
}

var stack = new StackTrace();
var frame = stack.GetFrames()?.FirstOrDefault(f => f.GetMethod().Name == callerMemberName);
SuiteName ??= frame?.GetMethod().DeclaringType?.FullName ?? previousSuiteName;
TestName ??= callerMemberName;
}
}
}
26 changes: 20 additions & 6 deletions visual-dotnet/SauceLabs.Visual/VisualClient.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using OpenQA.Selenium;
using Polly;
Expand All @@ -26,6 +27,8 @@
public bool CaptureDom { get; set; } = false;
private readonly ResiliencePipeline _retryPipeline;

private string? _previousSuiteName = null;

/// <summary>
/// Creates a new instance of <c>VisualClient</c>
/// </summary>
Expand Down Expand Up @@ -106,7 +109,7 @@
/// <param name="region">the Sauce Labs region to connect to</param>
/// <param name="username">the Sauce Labs username</param>
/// <param name="accessKey">the Sauce Labs access key</param>
private VisualClient(WebDriver wd, Region region, string username, string accessKey)

Check warning on line 112 in visual-dotnet/SauceLabs.Visual/VisualClient.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Build' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 112 in visual-dotnet/SauceLabs.Visual/VisualClient.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Build' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 112 in visual-dotnet/SauceLabs.Visual/VisualClient.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Build' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 112 in visual-dotnet/SauceLabs.Visual/VisualClient.cs

View workflow job for this annotation

GitHub Actions / build

Non-nullable property 'Build' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.
{
if (StringUtils.IsNullOrEmpty(username) || StringUtils.IsNullOrEmpty(accessKey))
{
Expand Down Expand Up @@ -220,22 +223,33 @@
/// <param name="name">the name of the screenshot</param>
/// <param name="options">the configuration for the screenshot capture and comparison</param>
/// <returns></returns>
public async Task<string> VisualCheck(string name, VisualCheckOptions? options = null)
public Task<string> VisualCheck(string name, VisualCheckOptions? options = null,
[CallerMemberName] string callerMemberName = "")
{
options ??= new VisualCheckOptions();
options.EnsureTestContextIsPopulated(callerMemberName, _previousSuiteName);
_previousSuiteName = options.SuiteName;
return VisualCheckAsync(name, options);
}

private async Task<string> VisualCheckAsync(string name, VisualCheckOptions options)
{
var ignored = new List<RegionIn>();
ignored.AddRange(options?.IgnoreRegions?.Select(r => new RegionIn(r)) ?? new List<RegionIn>());
ignored.AddRange(options?.IgnoreElements?.Select(r => new RegionIn(r)) ?? new List<RegionIn>());
ignored.AddRange(options.IgnoreRegions?.Select(r => new RegionIn(r)) ?? new List<RegionIn>());
ignored.AddRange(options.IgnoreElements?.Select(r => new RegionIn(r)) ?? new List<RegionIn>());

var result = (await _api.CreateSnapshotFromWebDriver(new CreateSnapshotFromWebDriverIn(
buildUuid: Build.Id,
name: name,
jobId: _jobId,
diffingMethod: options?.DiffingMethod ?? DiffingMethod.Simple,
diffingMethod: options.DiffingMethod ?? DiffingMethod.Simple,
regions: ignored.ToArray(),
sessionId: _sessionId,
sessionMetadata: _sessionMetadataBlob ?? "",
captureDom: options?.CaptureDom ?? CaptureDom,
clipSelector: options?.ClipSelector
captureDom: options.CaptureDom ?? CaptureDom,
clipSelector: options.ClipSelector,
suiteName: options.SuiteName,
testName: options.TestName
))).EnsureValidResponse();
result.Result.Diffs.Nodes.ToList().ForEach(d => _screenshotIds.Add(d.Id));
return result.Result.Id;
Expand Down