diff --git a/Lombiq.Tests.UI.AppExtensions/Lombiq.Tests.UI.AppExtensions.csproj b/Lombiq.Tests.UI.AppExtensions/Lombiq.Tests.UI.AppExtensions.csproj index b96e86238..8cf7b1060 100644 --- a/Lombiq.Tests.UI.AppExtensions/Lombiq.Tests.UI.AppExtensions.csproj +++ b/Lombiq.Tests.UI.AppExtensions/Lombiq.Tests.UI.AppExtensions.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 false $(DefaultItemExcludes);.git*;node_modules\** @@ -33,8 +33,8 @@ - - + + diff --git a/Lombiq.Tests.UI.Samples/Helpers/SetupHelpers.cs b/Lombiq.Tests.UI.Samples/Helpers/SetupHelpers.cs index 7c8e73cc7..fe4ff9f32 100644 --- a/Lombiq.Tests.UI.Samples/Helpers/SetupHelpers.cs +++ b/Lombiq.Tests.UI.Samples/Helpers/SetupHelpers.cs @@ -78,7 +78,7 @@ private static void AssertSetupSuccessful(UITestContext context) { var validationErrors = context.GetAll(By.ClassName("field-validation-error")); - if (!validationErrors.Any()) throw; + if (validationErrors.Count == 0) throw; var errors = "\n- " + validationErrors.Select(element => element.Text.Trim()).Join("\n- "); throw new AssertionException($"Setup has failed with the following validation errors:{errors}"); diff --git a/Lombiq.Tests.UI.Samples/Lombiq.Tests.UI.Samples.csproj b/Lombiq.Tests.UI.Samples/Lombiq.Tests.UI.Samples.csproj index 2f30ec9a8..83a572ce6 100644 --- a/Lombiq.Tests.UI.Samples/Lombiq.Tests.UI.Samples.csproj +++ b/Lombiq.Tests.UI.Samples/Lombiq.Tests.UI.Samples.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 false diff --git a/Lombiq.Tests.UI.Shortcuts/Controllers/ErrorController.cs b/Lombiq.Tests.UI.Shortcuts/Controllers/ErrorController.cs index 3f9728bcc..7935cd317 100644 --- a/Lombiq.Tests.UI.Shortcuts/Controllers/ErrorController.cs +++ b/Lombiq.Tests.UI.Shortcuts/Controllers/ErrorController.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using System; -using System.Diagnostics.CodeAnalysis; namespace Lombiq.Tests.UI.Shortcuts.Controllers; @@ -11,8 +10,6 @@ public class ErrorController : Controller { public const string ExceptionMessage = "This action intentionally causes an exception!"; - // This only happens in the CI for some reason. - [SuppressMessage("Usage", "CA1822:Mark members as static", Justification = "It's a controller action.")] [AllowAnonymous] public IActionResult Index() => throw new InvalidOperationException(ExceptionMessage); diff --git a/Lombiq.Tests.UI.Shortcuts/Lombiq.Tests.UI.Shortcuts.csproj b/Lombiq.Tests.UI.Shortcuts/Lombiq.Tests.UI.Shortcuts.csproj index d077d6b04..44f05f170 100644 --- a/Lombiq.Tests.UI.Shortcuts/Lombiq.Tests.UI.Shortcuts.csproj +++ b/Lombiq.Tests.UI.Shortcuts/Lombiq.Tests.UI.Shortcuts.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 false true $(DefaultItemExcludes);.git*;node_modules\** @@ -34,15 +34,15 @@ - - - - - - - - - + + + + + + + + + @@ -50,7 +50,7 @@ - + diff --git a/Lombiq.Tests.UI.Shortcuts/Manifest.cs b/Lombiq.Tests.UI.Shortcuts/Manifest.cs index 012139940..a281e0653 100644 --- a/Lombiq.Tests.UI.Shortcuts/Manifest.cs +++ b/Lombiq.Tests.UI.Shortcuts/Manifest.cs @@ -14,15 +14,15 @@ Category = "Development", Description = "WARNING: Only enable this feature in the UI testing environment. Provides shortcuts for common " + "operations that UI tests might want to do or check.", - Dependencies = new[] - { + Dependencies = + [ "OrchardCore.ContentManagement", "OrchardCore.ContentTypes", "OrchardCore.DisplayManagement", "OrchardCore.Roles", "OrchardCore.Tenants", "OrchardCore.Users", - } + ] )] [assembly: Feature( @@ -37,10 +37,10 @@ Name = "Media Cache Purge - Shortcuts - Lombiq UI Testing Toolbox", Category = "Development", Description = "WARNING: Only enable this feature in the UI testing environment. Provides shortcut for Media Cache Purge.", - Dependencies = new[] - { + Dependencies = + [ "OrchardCore.Media.Cache", - } + ] )] [assembly: Feature( @@ -48,8 +48,8 @@ Name = "Workflows - Shortcuts - Lombiq UI Testing Toolbox", Category = "Development", Description = "WARNING: Only enable this feature in the UI testing environment. Provides shortcut for Workflows.", - Dependencies = new[] - { + Dependencies = + [ "OrchardCore.Workflows.Http", - } + ] )] diff --git a/Lombiq.Tests.UI.Tests.UI/Lombiq.Tests.UI.Tests.UI.csproj b/Lombiq.Tests.UI.Tests.UI/Lombiq.Tests.UI.Tests.UI.csproj index b5305d04e..36cbc2eed 100644 --- a/Lombiq.Tests.UI.Tests.UI/Lombiq.Tests.UI.Tests.UI.csproj +++ b/Lombiq.Tests.UI.Tests.UI/Lombiq.Tests.UI.Tests.UI.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 enable enable diff --git a/Lombiq.Tests.UI/Extensions/BasicOrchardFeaturesTestingUITestContextExtensions.cs b/Lombiq.Tests.UI/Extensions/BasicOrchardFeaturesTestingUITestContextExtensions.cs index 2c6582c45..d601038be 100644 --- a/Lombiq.Tests.UI/Extensions/BasicOrchardFeaturesTestingUITestContextExtensions.cs +++ b/Lombiq.Tests.UI/Extensions/BasicOrchardFeaturesTestingUITestContextExtensions.cs @@ -659,9 +659,9 @@ await context public static Task ExecuteTestAsync( this UITestContext context, string testName, Func testFunctionAsync) { - if (context is null) throw new ArgumentNullException(nameof(context)); - if (testName is null) throw new ArgumentNullException(nameof(testName)); - if (testFunctionAsync is null) throw new ArgumentNullException(nameof(testFunctionAsync)); + ArgumentNullException.ThrowIfNull(context); + ArgumentNullException.ThrowIfNull(testName); + ArgumentNullException.ThrowIfNull(testFunctionAsync); return ExecuteTestInnerAsync(context, testName, testFunctionAsync); } diff --git a/Lombiq.Tests.UI/Extensions/ExtendedLoggingExtensions.cs b/Lombiq.Tests.UI/Extensions/ExtendedLoggingExtensions.cs index 32bfe12f2..cb1a29ef5 100644 --- a/Lombiq.Tests.UI/Extensions/ExtendedLoggingExtensions.cs +++ b/Lombiq.Tests.UI/Extensions/ExtendedLoggingExtensions.cs @@ -131,7 +131,7 @@ private static TResult ExecuteSection(this UITestContext context, LogSe throw new InvalidOperationException("Impossible to reach."); }); - private static Task ExecuteSectionAsync(this UITestContext context, LogSection section, Func functionAsync) => + private static Task ExecuteSectionAsync(this UITestContext context, LogSection section, Func functionAsync) => context.ExecuteSectionAsync( section, async () => diff --git a/Lombiq.Tests.UI/Extensions/FormUITestContextExtensions.cs b/Lombiq.Tests.UI/Extensions/FormUITestContextExtensions.cs index 926905923..11e4bf1c7 100644 --- a/Lombiq.Tests.UI/Extensions/FormUITestContextExtensions.cs +++ b/Lombiq.Tests.UI/Extensions/FormUITestContextExtensions.cs @@ -110,8 +110,7 @@ public static void FillInMonacoEditor( { var script = $@" monaco.editor.getEditors().find((element) => - element.getContainerDomNode().id == {JsonConvert.SerializeObject(editorId)}) - .getModel().setValue({JsonConvert.SerializeObject(text)});"; + element.getContainerDomNode().id == {JsonConvert.SerializeObject(editorId)}).setValue({JsonConvert.SerializeObject(text)});"; context.ExecuteScript(script); } @@ -125,8 +124,7 @@ public static string GetMonacoEditorText( { var script = $@" return monaco.editor.getEditors().find((element) => - element.getContainerDomNode().id == {JsonConvert.SerializeObject(editorId)}) - .getModel().getValue();"; + element.getContainerDomNode().id == {JsonConvert.SerializeObject(editorId)}).getValue();"; return context.ExecuteScript(script) as string; } diff --git a/Lombiq.Tests.UI/Extensions/ShortcutsUITestContextExtensions.cs b/Lombiq.Tests.UI/Extensions/ShortcutsUITestContextExtensions.cs index c2a824207..0119802e3 100644 --- a/Lombiq.Tests.UI/Extensions/ShortcutsUITestContextExtensions.cs +++ b/Lombiq.Tests.UI/Extensions/ShortcutsUITestContextExtensions.cs @@ -342,10 +342,7 @@ public static async Task PurgeMediaCacheDirectlyAsync(this UITestContext context public static Task GetApplicationInfoAsync(this UITestContext context) => context.GetApi().GetApplicationInfoFromApiAsync(); - // This is required to instantiate ILogger<>. -#pragma warning disable S2094 // Classes should not be empty private sealed class ExecuteRecipeShortcut { } -#pragma warning restore S2094 // Classes should not be empty /// /// Executes a recipe identified by its name directly. @@ -646,7 +643,7 @@ internal static async Task WaitInteractiveModeAsync(this UITestContext context) } private static bool IsAdminTheme(IManifestInfo manifest) => - manifest.Tags.Any(tag => tag.EqualsOrdinalIgnoreCase(ManifestConstants.AdminTag)); + manifest.Tags.Any(tag => tag.EqualsOrdinalIgnoreCase(value: ManifestConstants.AdminTag)); private static async Task PermissionExistsAsync( IEnumerable permissionProviders, string permissionName) => diff --git a/Lombiq.Tests.UI/Extensions/ShouldlyExtensions.cs b/Lombiq.Tests.UI/Extensions/ShouldlyExtensions.cs index e0b161f38..1d200966c 100644 --- a/Lombiq.Tests.UI/Extensions/ShouldlyExtensions.cs +++ b/Lombiq.Tests.UI/Extensions/ShouldlyExtensions.cs @@ -51,7 +51,7 @@ public static void ShouldBeEmptyWhen( JsonSerializerOptions jsonSerializerOptions = null) { var results = enumerable.Where(condition).ToList(); - if (!results.Any()) return; + if (results.Count == 0) return; var message = messageTransform == null ? JsonSerializer.Serialize(results, jsonSerializerOptions) diff --git a/Lombiq.Tests.UI/Extensions/TypedRouteUITestContextExtensions.cs b/Lombiq.Tests.UI/Extensions/TypedRouteUITestContextExtensions.cs index f3a2535c1..ddd059010 100644 --- a/Lombiq.Tests.UI/Extensions/TypedRouteUITestContextExtensions.cs +++ b/Lombiq.Tests.UI/Extensions/TypedRouteUITestContextExtensions.cs @@ -43,11 +43,16 @@ public static string GetRelativeUrlOfAction( this UITestContext context, Expression> actionExpression, params (string Key, object Value)[] additionalArguments) - where TController : ControllerBase => - TypedRoute - .CreateFromExpression(actionExpression, additionalArguments, CreateServiceProvider(context)) + where TController : ControllerBase + { + using var serviceProvider = CreateServiceProvider(context); + var route = TypedRoute + .CreateFromExpression(actionExpression, additionalArguments, serviceProvider) .ToString(); + return route; + } + /// /// Gets the relative URL generated by for the in /// the . @@ -57,11 +62,17 @@ public static string GetRelativeUrlOfAction( this UITestContext context, Expression> actionExpressionAsync, params (string Key, object Value)[] additionalArguments) - where TController : ControllerBase => - TypedRoute - .CreateFromExpression(actionExpressionAsync.StripResult(), additionalArguments, CreateServiceProvider(context)) + where TController : ControllerBase + { + using var serviceProvider = CreateServiceProvider(context); + + var route = TypedRoute + .CreateFromExpression(actionExpressionAsync.StripResult(), additionalArguments, serviceProvider) .ToString(); + return route; + } + /// /// Gets the absolute URL generated by for the in the /// . @@ -84,7 +95,7 @@ public static Uri GetAbsoluteUrlOfAction( where TController : ControllerBase => context.GetAbsoluteUri(context.GetRelativeUrlOfAction(actionExpressionAsync, additionalArguments)); - private static IServiceProvider CreateServiceProvider(UITestContext context) + private static ServiceProvider CreateServiceProvider(UITestContext context) { var services = new ServiceCollection(); diff --git a/Lombiq.Tests.UI/Extensions/VisualVerificationUITestContextExtensions.cs b/Lombiq.Tests.UI/Extensions/VisualVerificationUITestContextExtensions.cs index d94b6d2bc..bd4852947 100644 --- a/Lombiq.Tests.UI/Extensions/VisualVerificationUITestContextExtensions.cs +++ b/Lombiq.Tests.UI/Extensions/VisualVerificationUITestContextExtensions.cs @@ -82,7 +82,7 @@ public static void AssertVisualVerificationOnAllResolutions( if (exceptions.Count == 1) throw exceptions.Single(); - if (exceptions.Any()) + if (exceptions.Count != 0) { // The UITestExecutionSession doesn't support AggregateException with multiple inner exceptions, so we just // concatenate the exceptions if there are multiple. diff --git a/Lombiq.Tests.UI/Extensions/WebApplicationInstanceExtensions.cs b/Lombiq.Tests.UI/Extensions/WebApplicationInstanceExtensions.cs index 073beb887..ee517817c 100644 --- a/Lombiq.Tests.UI/Extensions/WebApplicationInstanceExtensions.cs +++ b/Lombiq.Tests.UI/Extensions/WebApplicationInstanceExtensions.cs @@ -37,7 +37,7 @@ public static async Task LogsShouldBeEmptyAsync( .SplitByNewLines() .Where(line => line.Contains("|ERROR|")); - if (permittedErrorLines.Any()) + if (permittedErrorLines.Count != 0) { errorLines = errorLines.Where(line => !permittedErrorLines.Any(line.ContainsOrdinalIgnoreCase)); } diff --git a/Lombiq.Tests.UI/Helpers/WebAppConfigHelper.cs b/Lombiq.Tests.UI/Helpers/WebAppConfigHelper.cs index 0d25b8cb2..b48bb5601 100644 --- a/Lombiq.Tests.UI/Helpers/WebAppConfigHelper.cs +++ b/Lombiq.Tests.UI/Helpers/WebAppConfigHelper.cs @@ -5,15 +5,17 @@ namespace Lombiq.Tests.UI.Helpers; public static class WebAppConfigHelper { + private static readonly string[] Separator = ["src", "test"]; + /// /// Retrieves the absolute path to the assembly (DLL) of the application being tested. /// /// The web app's project name. /// - /// The name of the folder that corresponds to the .NET version in the build output folder (e.g. "net6.0"). + /// The name of the folder that corresponds to the .NET version in the build output folder (e.g. "net8.0"). /// /// The absolute path to the assembly (DLL) of the application being tested. - public static string GetAbsoluteApplicationAssemblyPath(string webAppName, string frameworkFolderName = "net6.0") + public static string GetAbsoluteApplicationAssemblyPath(string webAppName, string frameworkFolderName = "net8.0") { string baseDirectory; @@ -24,7 +26,7 @@ public static string GetAbsoluteApplicationAssemblyPath(string webAppName, strin else { var outputFolderContainingPath = Path.Combine( - AppContext.BaseDirectory.Split(new[] { "src", "test" }, StringSplitOptions.RemoveEmptyEntries)[0], + AppContext.BaseDirectory.Split(Separator, StringSplitOptions.RemoveEmptyEntries)[0], "src", webAppName, "bin"); diff --git a/Lombiq.Tests.UI/Lombiq.Tests.UI.csproj b/Lombiq.Tests.UI/Lombiq.Tests.UI.csproj index 6f086f898..4617f4e78 100644 --- a/Lombiq.Tests.UI/Lombiq.Tests.UI.csproj +++ b/Lombiq.Tests.UI/Lombiq.Tests.UI.csproj @@ -1,7 +1,7 @@ - net6.0 + net8.0 false $(DefaultItemExcludes);.git*