diff --git a/Lombiq.Tests.UI.Samples/Tests/BasicVisualVerificationTests_VerifyNavbar_By_ClassName[Contains]_-navbar-brand_Unix_MicrosoftEdge.png b/Lombiq.Tests.UI.Samples/Tests/BasicVisualVerificationTests_VerifyNavbar_By_ClassName[Contains]_-navbar-brand_Unix_MicrosoftEdge.png new file mode 100644 index 000000000..351f87485 Binary files /dev/null and b/Lombiq.Tests.UI.Samples/Tests/BasicVisualVerificationTests_VerifyNavbar_By_ClassName[Contains]_-navbar-brand_Unix_MicrosoftEdge.png differ diff --git a/Lombiq.Tests.UI.Samples/xunit.runner.json b/Lombiq.Tests.UI.Samples/xunit.runner.json index 3df5bfd1a..07f35a639 100644 --- a/Lombiq.Tests.UI.Samples/xunit.runner.json +++ b/Lombiq.Tests.UI.Samples/xunit.runner.json @@ -2,6 +2,5 @@ "$schema": "https://xunit.net/schema/current/xunit.runner.schema.json", "parallelizeAssembly": false, "parallelizeTestCollections": true, - "maxParallelThreads": 3, - "stopOnFail": true + "maxParallelThreads": 3 } diff --git a/Lombiq.Tests.UI/CloudflareRemoteUITestBase.cs b/Lombiq.Tests.UI/CloudflareRemoteUITestBase.cs index 07d2d31a8..b63fb29a2 100644 --- a/Lombiq.Tests.UI/CloudflareRemoteUITestBase.cs +++ b/Lombiq.Tests.UI/CloudflareRemoteUITestBase.cs @@ -75,6 +75,7 @@ async Task ChangeConfigurationForCloudflareAsync(OrchardCoreUITestExecutorConfig return CloudflareHelper.ExecuteWrappedInIpAccessRuleManagementAsync( () => base.ExecuteTestAsync(baseUri, testAsync, browser, ChangeConfigurationForCloudflareAsync), CloudflareAccountId, - CloudflareApiToken); + CloudflareApiToken, + _testOutputHelper); } } diff --git a/Lombiq.Tests.UI/Helpers/CloudflareHelper.cs b/Lombiq.Tests.UI/Helpers/CloudflareHelper.cs index bbba5b095..f8cc341eb 100644 --- a/Lombiq.Tests.UI/Helpers/CloudflareHelper.cs +++ b/Lombiq.Tests.UI/Helpers/CloudflareHelper.cs @@ -8,6 +8,7 @@ using System.Net.Http; using System.Threading; using System.Threading.Tasks; +using Xunit.Abstractions; namespace Lombiq.Tests.UI.Helpers; @@ -23,12 +24,17 @@ internal static class CloudflareHelper public static async Task ExecuteWrappedInIpAccessRuleManagementAsync( Func testAsync, string cloudflareAccountId, - string cloudflareApiToken) + string cloudflareApiToken, + ITestOutputHelper testOutputHelper) { + testOutputHelper.WriteLineTimestampedAndDebug( + "Current Cloudflare IP Access Rule reference count before entering semaphore: {0}.", _referenceCount); + await _semaphore.WaitAsync(); Interlocked.Increment(ref _referenceCount); - Debug.WriteLine("Current reference count at the start of the test: {0}.", _referenceCount); + testOutputHelper.WriteLineTimestampedAndDebug( + "Current Cloudflare IP Access Rule reference count after entering semaphore: {0}.", _referenceCount); try { @@ -41,7 +47,7 @@ public static async Task ExecuteWrappedInIpAccessRuleManagementAsync( if (_ipAccessRuleId == null) { - Debug.WriteLine("Creating an IP Access Rule for the IP {0}.", (object)_currentIp); + testOutputHelper.WriteLineTimestampedAndDebug("Creating a Cloudflare IP Access Rule for the IP {0}.", _currentIp); // Delete any pre-existing rules for the current IP first. string preexistingRuleId = null; @@ -88,6 +94,9 @@ await ReliabilityHelper.DoWithRetriesAndCatchesAsync( }); ThrowIfNotSuccess(ruleCheckRequestResult, _currentIp, "didn't get activated"); + + testOutputHelper.WriteLineTimestampedAndDebug( + "Created a Cloudflare IP Access Rule for the IP {0} (Rule ID: {1}).", _currentIp, _ipAccessRuleId); } } finally @@ -101,16 +110,36 @@ await ReliabilityHelper.DoWithRetriesAndCatchesAsync( } finally { + testOutputHelper.WriteLineTimestampedAndDebug( + "Current Cloudflare IP Access Rule reference count after the test (including this test): {0}.", _referenceCount); + // Clean up the IP access rule. if (_ipAccessRuleId != null && Interlocked.Decrement(ref _referenceCount) == 0) { - Debug.WriteLine("Removing the IP Access Rule. Current reference count: {0}.", _referenceCount); + testOutputHelper.WriteLineTimestampedAndDebug( + "Removing the Cloudflare IP Access Rule for the IP {0} (Rule ID: {1}) since this test has the last reference to it.", + _currentIp, + _ipAccessRuleId); + + var oldIpAccessRuleId = _ipAccessRuleId; var deleteSucceededResult = await DeleteIpAccessRuleWithRetriesAsync(cloudflareAccountId, _ipAccessRuleId); if (deleteSucceededResult.IsSuccess) _ipAccessRuleId = null; ThrowIfNotSuccess(deleteSucceededResult, _currentIp, "couldn't be deleted"); + + testOutputHelper.WriteLineTimestampedAndDebug( + "Removed the Cloudflare IP Access Rule for the IP {0} (Rule ID: {1}) since this test had the last reference to it.", + _currentIp, + oldIpAccessRuleId); + } + else + { + testOutputHelper.WriteLineTimestampedAndDebug( + "Not removing the Cloudflare IP Access Rule for the IP {0} (Rule ID: {1}) since the current reference count is NOT 0.", + _currentIp, + _ipAccessRuleId); } } }