Skip to content

Commit ae448d1

Browse files
authored
Merge pull request #6 from g4-api/development
Development
2 parents 47fc4a7 + 1b21e53 commit ae448d1

19 files changed

Lines changed: 177 additions & 206 deletions

src/G4.Api/Clients/EnvironmentsClient.cs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,9 @@
44

55
using LiteDB;
66

7-
using Microsoft.Extensions.Primitives;
8-
97
using System;
108
using System.Collections.Generic;
119
using System.Linq;
12-
using System.Reflection.Metadata;
1310

1411
namespace G4.Api.Clients
1512
{

src/G4.Api/G4.Api.csproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
<PropertyGroup>
44
<!-- Assembly -->
5-
<TargetFramework>net8.0</TargetFramework>
6-
<AssemblyVersion>8.0.0.0</AssemblyVersion>
7-
<FileVersion>8.0.0.0</FileVersion>
5+
<TargetFramework>net10.0</TargetFramework>
6+
<AssemblyVersion>10.0.0.0</AssemblyVersion>
7+
<FileVersion>10.0.0.0</FileVersion>
88
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
99
<SatelliteResourceLanguages>en-US</SatelliteResourceLanguages>
1010
<LangVersion>latest</LangVersion>
@@ -30,9 +30,9 @@
3030
</ItemGroup>
3131

3232
<ItemGroup>
33-
<PackageReference Include="G4.Plugins" Version="2025.3.28.36" />
34-
<PackageReference Include="G4.Plugins.Common" Version="2025.3.28.107" />
35-
<PackageReference Include="G4.Plugins.Ui" Version="2025.3.28.107" />
33+
<PackageReference Include="G4.Plugins" Version="2026.1.18.46" />
34+
<PackageReference Include="G4.Plugins.Common" Version="2026.1.18.119" />
35+
<PackageReference Include="G4.Plugins.Ui" Version="2026.1.18.119" />
3636
</ItemGroup>
3737

3838
</Project>

src/G4.IntegrationTests/Framework/TestBase.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public static void OneTimeSetup(TestContext context)
4545
WebServer.StartWebHost(); // Start the web host
4646

4747
// Start BrowserStack local agent if the grid endpoint contains "browserstack"
48-
var remoteEndpoint = context.Properties.Contains(key: "Grid.Endpoint")
48+
var remoteEndpoint = context.Properties.ContainsKey(key: "Grid.Endpoint")
4949
? $"{context.Properties["Grid.Endpoint"]}"
5050
: string.Empty;
5151

src/G4.IntegrationTests/Framework/TestCaseBase.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,12 @@ protected TestCaseBase(TestContext context)
4545
_environments ??= [];
4646

4747
// Parse and set the number of test case attempts
48-
_attempts = context.Properties.Contains(key: "Integration.NumberOfAttempts")
48+
_attempts = context.Properties.ContainsKey(key: "Integration.NumberOfAttempts")
4949
? int.Parse($"{context.Properties["Integration.NumberOfAttempts"]}")
5050
: int.Parse("1");
5151

5252
// Parse and set the time interval between test case attempts
53-
_attemptsDelay= context.Properties.Contains(key: "Integration.AttemptsDelay")
53+
_attemptsDelay= context.Properties.ContainsKey(key: "Integration.AttemptsDelay")
5454
? int.Parse($"{context.Properties["Integration.AttemptsDelay"]}")
5555
: int.Parse("15000");
5656

src/G4.IntegrationTests/Framework/TestingServer.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using G4.Extensions;
44
using G4.Models;
55

6-
using Microsoft.AspNetCore;
76
using Microsoft.AspNetCore.Builder;
87
using Microsoft.AspNetCore.Hosting;
98
using Microsoft.AspNetCore.Mvc;
@@ -17,7 +16,6 @@
1716
using System.Collections.Generic;
1817
using System.IO;
1918
using System.Linq;
20-
using System.Net;
2119
using System.Net.Mime;
2220
using System.Text.Json;
2321
using System.Text.Json.Serialization;
@@ -1319,7 +1317,7 @@ public void Configure(IApplicationBuilder app)
13191317
public static class WebServer
13201318
{
13211319
// Static variable to hold the web host instance.
1322-
private static IWebHost s_webHost = NewWebHost(port: 9002, shutdownTimeout: TimeSpan.FromSeconds(60));
1320+
private static IHost s_webHost = NewWebHost(port: 9002, shutdownTimeout: TimeSpan.FromSeconds(60));
13231321

13241322
/// <summary>
13251323
/// Starts the web host asynchronously.
@@ -1333,14 +1331,16 @@ public static void NewWebHost()
13331331
=> s_webHost = NewWebHost(port: 9002, shutdownTimeout: TimeSpan.FromSeconds(60));
13341332

13351333
// Creates a new web host with the specified port and shutdown timeout.
1336-
private static IWebHost NewWebHost(int port, TimeSpan shutdownTimeout)
1334+
private static IHost NewWebHost(int port, TimeSpan shutdownTimeout)
13371335
{
1338-
return WebHost
1336+
return Host
13391337
.CreateDefaultBuilder()
1340-
.UseUrls()
1341-
.ConfigureKestrel(i => i.Listen(IPAddress.Any, port))
1342-
.UseStartup<Startup>()
1343-
.UseShutdownTimeout(shutdownTimeout)
1338+
.ConfigureWebHostDefaults(webBuilder =>
1339+
{
1340+
webBuilder.UseKestrel(options => options.ListenAnyIP(port));
1341+
webBuilder.UseStartup<Startup>();
1342+
webBuilder.UseShutdownTimeout(shutdownTimeout);
1343+
})
13441344
.Build();
13451345
}
13461346

src/G4.IntegrationTests/G4.IntegrationTests.csproj

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
<PropertyGroup>
44
<!-- Assembly -->
5-
<TargetFramework>net8.0</TargetFramework>
5+
<TargetFramework>net10.0</TargetFramework>
66
<IsPackable>false</IsPackable>
7-
<AssemblyVersion>8.0.0.0</AssemblyVersion>
8-
<FileVersion>8.0.0.0</FileVersion>
7+
<AssemblyVersion>10.0.0.0</AssemblyVersion>
8+
<FileVersion>10.0.0.0</FileVersion>
99
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
1010
<SatelliteResourceLanguages>en-US</SatelliteResourceLanguages>
1111
<LangVersion>latest</LangVersion>
1212

1313
<!-- https://learn.microsoft.com/en-us/dotnet/fundamentals/syslib-diagnostics/syslib1040-1049 -->
14-
<NoWarn>$(NoWarn);SYSLIB1045;S4144;MSTEST0016</NoWarn>
14+
<NoWarn>$(NoWarn);SYSLIB1045;S4144;MSTEST0016;MSTEST0001</NoWarn>
1515
</PropertyGroup>
1616

1717
<ItemGroup>
@@ -32,15 +32,15 @@
3232
</ItemGroup>
3333

3434
<ItemGroup>
35-
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="8.0.10" PrivateAssets="all" />
36-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.13.0" />
37-
<PackageReference Include="MSTest.TestAdapter" Version="3.8.3" />
38-
<PackageReference Include="MSTest.TestFramework" Version="3.8.3" />
35+
<PackageReference Include="Microsoft.AspNetCore.MiddlewareAnalysis" Version="10.0.2" PrivateAssets="all" />
36+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
37+
<PackageReference Include="MSTest.TestAdapter" Version="4.0.2" />
38+
<PackageReference Include="MSTest.TestFramework" Version="4.0.2" />
3939
<PackageReference Include="coverlet.collector" Version="6.0.4">
4040
<PrivateAssets>all</PrivateAssets>
4141
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
4242
</PackageReference>
43-
<PackageReference Include="Swashbuckle.AspNetCore" Version="8.0.0" />
43+
<PackageReference Include="Swashbuckle.AspNetCore" Version="10.1.0" />
4444
</ItemGroup>
4545

4646
<ItemGroup>

src/G4.IntegrationTests/Suites.Engine/MultiPhaseDriverTests.cs

Lines changed: 16 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
using G4.Api;
2-
using G4.Extensions;
1+
using G4.Extensions;
32
using G4.IntegrationTests.Engine;
43
using G4.IntegrationTests.Extensions;
54
using G4.IntegrationTests.Framework;
6-
using G4.Models;
75

86
using Microsoft.VisualStudio.TestTools.UnitTesting;
97

10-
using System.IO;
118
using System.Linq;
12-
using System.Text.Json;
139

1410
namespace G4.IntegrationTests.Suites.Engine
1511
{
@@ -19,19 +15,7 @@ namespace G4.IntegrationTests.Suites.Engine
1915
[TestCategory("Engine")]
2016
public class MultiPhaseDriverTests : TestBase
2117
{
22-
[TestMethod]
23-
public void Test()
24-
{
25-
var json = File.ReadAllText(@"E:\Garbage\z.txt");
26-
var autoation = JsonSerializer.Deserialize<G4AutomationModel>(json, new JsonSerializerOptions
27-
{
28-
PropertyNameCaseInsensitive = true
29-
});
30-
var client = new G4Client();
31-
var response = client.Automation.Invoke(autoation);
32-
}
33-
34-
[TestMethod(displayName: "Verify that two WebDriver instances are initiated when a " +
18+
[TestMethod(DisplayName = "Verify that two WebDriver instances are initiated when a " +
3519
"job takes the driver from its parent stage.")]
3620
#region *** Data Set ***
3721
[DataRow("Default()")]
@@ -60,10 +44,11 @@ public void GetJobDriverTest(string jobDriver)
6044
var sessions = driverSessions.Concat([automationDriverSession]).Distinct().ToArray();
6145

6246
// Assert that exactly two unique driver sessions were created
63-
Assert.AreEqual(
47+
Assert.HasCount(
6448
expected: 2,
65-
actual: sessions.Length,
66-
message: "Expected two distinct WebDriver sessions to be initiated.");
49+
collection: sessions,
50+
message: "Expected two distinct WebDriver sessions to be initiated."
51+
);
6752

6853
// Assert that none of the plugins within the job are using the automation driver
6954
// They must be using the driver created by the stage instead
@@ -79,7 +64,7 @@ public void GetJobDriverTest(string jobDriver)
7964
message: "The 'TestParameter' should be 'Foo Bar' after decoding.");
8065
}
8166

82-
[TestMethod(displayName: "Verify that a stage can take a driver from the preceding " +
67+
[TestMethod(DisplayName = "Verify that a stage can take a driver from the preceding " +
8368
"stage or use the default driver from the parent automation.")]
8469
#region *** Data Set ***
8570
[DataRow("Default()")]
@@ -108,16 +93,18 @@ public void GetStageDriver(string stageDriver)
10893
var sessions = driverSessions.Concat([automationDriverSession]).Distinct().ToArray();
10994

11095
// Assert that exactly two unique driver sessions were created
111-
Assert.AreEqual(
96+
Assert.HasCount(
11297
expected: 2,
113-
actual: sessions.Length,
114-
message: "Expected two distinct WebDriver sessions to be initiated.");
98+
collection: sessions,
99+
message: "Expected two distinct WebDriver sessions to be initiated."
100+
);
115101

116102
// Assert that the environment's session parameters count is exactly two
117-
Assert.AreEqual(
103+
Assert.HasCount(
118104
expected: 2,
119-
actual: response.Environment.SessionParameters.Count,
120-
message: "Expected exactly two session parameters to be present.");
105+
collection: response.Environment.SessionParameters,
106+
message: "Expected exactly two session parameters to be present."
107+
);
121108

122109
// Assert that all session parameters have the expected decoded value "Foo Bar"
123110
Assert.IsTrue(
@@ -126,7 +113,7 @@ public void GetStageDriver(string stageDriver)
126113
);
127114
}
128115

129-
[TestMethod(displayName: "Verify that the automation driver is correctly retrieved " +
116+
[TestMethod(DisplayName = "Verify that the automation driver is correctly retrieved " +
130117
"and no exceptions occur during GetStateDriver invocation.")]
131118
public void GetStateDriver()
132119
{

src/G4.UnitTests/Attributes/RetryableTestMethodAttribute.cs

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,47 @@
11
using Microsoft.VisualStudio.TestTools.UnitTesting;
22

33
using System;
4+
using System.Runtime.CompilerServices;
45
using System.Threading;
6+
using System.Threading.Tasks;
57

68
namespace G4.UnitTests.Attributes
79
{
810
/// <summary>
9-
/// A custom test method attribute that allows for retry logic in unit tests.
11+
/// Marks a test method as retryable, allowing it to be executed multiple times
12+
/// before being considered failed.
1013
/// </summary>
11-
/// <param name="numberOfAttempts">The number of times to attempt the test.</param>
12-
/// <param name="displayName">The display name of the test method.</param>
1314
[AttributeUsage(AttributeTargets.Method)]
14-
public class RetryableTestMethodAttribute(int numberOfAttempts, string displayName) : TestMethodAttribute(displayName)
15+
public class RetryableTestMethodAttribute(
16+
int numberOfAttempts,
17+
[CallerFilePath] string callerFilePath = "",
18+
[CallerLineNumber] int callerLineNumber = -1) : TestMethodAttribute(callerFilePath, callerLineNumber)
1519
{
1620
/// <summary>
17-
/// Initializes a new instance of the <see cref="RetryableTestMethodAttribute"/> class with a single attempt.
21+
/// Creates a retryable test attribute with a default of 1 attempt.
1822
/// </summary>
19-
public RetryableTestMethodAttribute()
20-
: this(numberOfAttempts: 1, displayName: null)
23+
/// <param name="callerFilePath">Automatically populated with the source file path of the calling method.</param>
24+
/// <param name="callerLineNumber">Automatically populated with the source line number of the calling method.</param>
25+
public RetryableTestMethodAttribute(
26+
[CallerFilePath] string callerFilePath = "",
27+
[CallerLineNumber] int callerLineNumber = -1)
28+
: this(numberOfAttempts: 1, callerFilePath, callerLineNumber)
2129
{ }
2230

2331
/// <summary>
24-
/// Initializes a new instance of the <see cref="RetryableTestMethodAttribute"/> class with a specified number of attempts.
25-
/// </summary>
26-
/// <param name="numberOfAttempts">The number of times to attempt the test.</param>
27-
public RetryableTestMethodAttribute(int numberOfAttempts)
28-
: this(numberOfAttempts, displayName: null)
29-
{ }
30-
31-
/// <summary>
32-
/// Initializes a new instance of the <see cref="RetryableTestMethodAttribute"/> class with a specified display name.
33-
/// </summary>
34-
/// <param name="displayName">The display name of the test method.</param>
35-
public RetryableTestMethodAttribute(string displayName)
36-
: this(numberOfAttempts: 1, displayName)
37-
{ }
38-
39-
/// <summary>
40-
/// Gets or sets the delay between test attempts in milliseconds.
32+
/// Gets or sets the delay (in milliseconds) between retry attempts.
4133
/// </summary>
34+
/// <remarks>This delay is applied after a failed attempt and before retrying. Default is 1000 ms (1 second).</remarks>
4235
public int DelayBetweenAttempts { get; set; } = 1000;
4336

4437
/// <summary>
45-
/// Gets the number of times the test will be attempted.
38+
/// Gets the total number of attempts allowed for this test method.
4639
/// </summary>
40+
/// <remarks>This includes the initial attempt. For example, a value of 3 means: 1 initial run + 2 retries.</remarks>
4741
public int NumberOfAttempts { get; } = numberOfAttempts;
4842

49-
/// <summary>
50-
/// Executes the test method, retrying up to <see cref="NumberOfAttempts"/> times if it fails.
51-
/// </summary>
52-
/// <param name="testMethod">The test method to be executed.</param>
53-
/// <returns>An array of <see cref="TestResult"/> objects representing the outcome of each test attempt.</returns>
54-
public override TestResult[] Execute(ITestMethod testMethod)
43+
/// <inheritdoc />
44+
public override async Task<TestResult[]> ExecuteAsync(ITestMethod testMethod)
5545
{
5646
// Array to hold the results of each test attempt
5747
TestResult[] results = [];
@@ -63,7 +53,7 @@ public override TestResult[] Execute(ITestMethod testMethod)
6353
try
6454
{
6555
// Execute the test method
66-
results = base.Execute(testMethod);
56+
results = await base.ExecuteAsync(testMethod);
6757

6858
// If all test results are successful, return the results
6959
if (Array.TrueForAll(results, r => r.Outcome == UnitTestOutcome.Passed))

src/G4.UnitTests/Engine/AssembliesLoaderTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace G4.UnitTests.Engine
1313
[TestCategory("UnitTest")]
1414
public class AssembliesLoaderTests
1515
{
16-
[TestMethod(displayName: "Verify that the number of imported assemblies and types " +
16+
[TestMethod(DisplayName = "Verify that the number of imported assemblies and types " +
1717
"meets certain criteria.")]
1818
public void AssembliesNumberTest()
1919
{
@@ -24,16 +24,16 @@ public void AssembliesNumberTest()
2424
var actual = loader.ImportAssemblies();
2525

2626
// Assert that the count of imported assemblies is not zero
27-
Assert.IsTrue(actual.Count != 0);
27+
Assert.IsNotEmpty(actual);
2828

2929
// Assert that the count of unique assemblies is greater than 5
30-
Assert.IsTrue(actual.Select(i => i.Value.Assembly).Count() > 5);
30+
Assert.IsGreaterThan(5, actual.Select(i => i.Value.Assembly).Count());
3131

3232
// Assert that the total count of types across all assemblies is greater than 50
33-
Assert.IsTrue(actual.Sum(i => i.Value.Types.Count()) > 50);
33+
Assert.IsGreaterThan(50, actual.Sum(i => i.Value.Types.Count()));
3434
}
3535

36-
[TestMethod(displayName: "Verify that the SetupCompleted event is raised with the " +
36+
[TestMethod(DisplayName = "Verify that the SetupCompleted event is raised with the " +
3737
"correct event arguments after importing assemblies.")]
3838
public void SetupCompletedEventTest()
3939
{
@@ -51,8 +51,8 @@ public void SetupCompletedEventTest()
5151

5252
// Assert that the event arguments contain information about loaded files, directories, and the base directory
5353
Assert.IsTrue(actual.Files.Any());
54-
Assert.IsTrue(!actual.Directories.Any());
55-
Assert.IsTrue(!string.IsNullOrEmpty(actual.Directory));
54+
Assert.IsFalse(actual.Directories.Any());
55+
Assert.IsFalse(string.IsNullOrEmpty(actual.Directory));
5656
}
5757
}
5858
}

0 commit comments

Comments
 (0)