diff --git a/Directory.Build.props b/Directory.Build.props index ad18505..28b9450 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -20,9 +20,14 @@ Minimum true + + latest + + true false - $(NoWarn);VSTHRD011;VSTHRD002;VSTHRD003;VSTHRD103;VSTHRD105;VSTHRD110;VSTHRD200;MSTEST0045 + + $(NoWarn);VSTHRD011;VSTHRD002;VSTHRD003;VSTHRD103;VSTHRD105;VSTHRD110;VSTHRD200;MSTEST0045;CS1591;CS1573;CS1584;CS1658 diff --git a/src/AdaptiveRemote.App/Configuration/LoggingHostBuilderExtensions.cs b/src/AdaptiveRemote.App/Configuration/LoggingHostBuilderExtensions.cs index 45e5d6e..bcc852b 100644 --- a/src/AdaptiveRemote.App/Configuration/LoggingHostBuilderExtensions.cs +++ b/src/AdaptiveRemote.App/Configuration/LoggingHostBuilderExtensions.cs @@ -10,7 +10,7 @@ internal static class LoggingHostBuilderExtensions internal static IHostBuilder OptionallyAddFileLogging(this IHostBuilder builder) => builder.ConfigureLogging((context, logging) => { - LoggingSettings settings = context.Configuration.GetSection(SettingsKeys.Logging).Get() + LoggingSettings settings = context.Configuration.GetSection(SettingsKeys.Logging).Get() ?? new LoggingSettings(); if (settings.FilePath is not null) { diff --git a/src/AdaptiveRemote.App/Configuration/TestingHostBuilderExtensions.cs b/src/AdaptiveRemote.App/Configuration/TestingHostBuilderExtensions.cs index e05a217..cea49c4 100644 --- a/src/AdaptiveRemote.App/Configuration/TestingHostBuilderExtensions.cs +++ b/src/AdaptiveRemote.App/Configuration/TestingHostBuilderExtensions.cs @@ -7,6 +7,8 @@ namespace AdaptiveRemote.Configuration; internal static class TestingHostBuilderExtensions { + private const string ControlPortSettingKey = $"{SettingsKeys.Testing}:{nameof(TestingSettings.ControlPort)}"; + /// /// Optionally adds test control services for E2E testing. /// The test control endpoint is only added when --test:ControlPort is provided. @@ -15,8 +17,8 @@ internal static IHostBuilder OptionallyAddTestHookEndpoint(this IHostBuilder bui => builder.ConfigureServices((context, services) => { // Only add the service if test:ControlPort is configured - int? controlPort = context.Configuration.GetValue($"{SettingsKeys.Testing}:{nameof(TestingSettings.ControlPort)}"); - + int? controlPort = context.Configuration.GetValue(ControlPortSettingKey); + if (controlPort.HasValue) { services.Configure(context.Configuration.GetSection(SettingsKeys.Testing)); diff --git a/src/AdaptiveRemote.App/Models/RemoteLayoutElement.cs b/src/AdaptiveRemote.App/Models/RemoteLayoutElement.cs index 2e006dc..1961774 100644 --- a/src/AdaptiveRemote.App/Models/RemoteLayoutElement.cs +++ b/src/AdaptiveRemote.App/Models/RemoteLayoutElement.cs @@ -13,5 +13,5 @@ public RemoteLayoutElement(string id, string? placement = null) CSSID = id; } - public override abstract string ToString(); + public abstract override string ToString(); } diff --git a/src/AdaptiveRemote.App/Services/Broadlink/AesWrapper.cs b/src/AdaptiveRemote.App/Services/Broadlink/AesWrapper.cs index efa96d2..a7da388 100644 --- a/src/AdaptiveRemote.App/Services/Broadlink/AesWrapper.cs +++ b/src/AdaptiveRemote.App/Services/Broadlink/AesWrapper.cs @@ -1,5 +1,4 @@ -using System.IO; -using System.Security.Cryptography; +using System.Security.Cryptography; namespace AdaptiveRemote.Services.Broadlink; diff --git a/src/AdaptiveRemote.App/Services/Broadlink/BroadlinkCommandService.cs b/src/AdaptiveRemote.App/Services/Broadlink/BroadlinkCommandService.cs index 2e2baf6..578d368 100644 --- a/src/AdaptiveRemote.App/Services/Broadlink/BroadlinkCommandService.cs +++ b/src/AdaptiveRemote.App/Services/Broadlink/BroadlinkCommandService.cs @@ -22,7 +22,7 @@ public BroadlinkCommandService( _connectionFactory = connectionFactory; } - public async override Task InitializeAsync(ILifecycleActivity activity, CancellationToken cancellationToken) + public override async Task InitializeAsync(ILifecycleActivity activity, CancellationToken cancellationToken) { activity.Description = Phrases.Startup_ConnectingToBroadlink; diff --git a/src/AdaptiveRemote.App/Services/Broadlink/DeviceLocator.cs b/src/AdaptiveRemote.App/Services/Broadlink/DeviceLocator.cs index da5841e..2776f7f 100644 --- a/src/AdaptiveRemote.App/Services/Broadlink/DeviceLocator.cs +++ b/src/AdaptiveRemote.App/Services/Broadlink/DeviceLocator.cs @@ -2,7 +2,7 @@ internal class DeviceLocator : IDeviceLocator { - private IUdpService _udpService; + private readonly IUdpService _udpService; public DeviceLocator(IUdpService udpService) { diff --git a/src/AdaptiveRemote.App/Services/Broadlink/IEncryption.cs b/src/AdaptiveRemote.App/Services/Broadlink/IEncryption.cs index 3087b1d..0f5718a 100644 --- a/src/AdaptiveRemote.App/Services/Broadlink/IEncryption.cs +++ b/src/AdaptiveRemote.App/Services/Broadlink/IEncryption.cs @@ -20,7 +20,7 @@ public interface IEncryption /// Decrypted result Memory Decrypt(Memory memory); - public interface Factory + interface Factory { /// /// Return an encryption model using the default Broadlink key diff --git a/src/AdaptiveRemote.App/Services/Broadlink/SocketWrapper.cs b/src/AdaptiveRemote.App/Services/Broadlink/SocketWrapper.cs index 61bc50e..e289f6e 100644 --- a/src/AdaptiveRemote.App/Services/Broadlink/SocketWrapper.cs +++ b/src/AdaptiveRemote.App/Services/Broadlink/SocketWrapper.cs @@ -7,7 +7,7 @@ namespace AdaptiveRemote.Services.Broadlink; [ExcludeFromCodeCoverage(Justification = "Simple wrapper around System.Net.Socket")] internal class SocketWrapper : ISocket { - private Socket _socket; + private readonly Socket _socket; private SocketWrapper(Socket socket) { diff --git a/src/AdaptiveRemote.App/Services/Conversation/ConversationController.cs b/src/AdaptiveRemote.App/Services/Conversation/ConversationController.cs index 77d8a4e..3b6ad59 100644 --- a/src/AdaptiveRemote.App/Services/Conversation/ConversationController.cs +++ b/src/AdaptiveRemote.App/Services/Conversation/ConversationController.cs @@ -1,5 +1,4 @@ -using System.Runtime.CompilerServices; -using AdaptiveRemote.Logging; +using AdaptiveRemote.Logging; using AdaptiveRemote.Models; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/src/AdaptiveRemote.App/Services/Conversation/IRecognizedSpeech.cs b/src/AdaptiveRemote.App/Services/Conversation/IRecognizedSpeech.cs index 0a406db..bda60ac 100644 --- a/src/AdaptiveRemote.App/Services/Conversation/IRecognizedSpeech.cs +++ b/src/AdaptiveRemote.App/Services/Conversation/IRecognizedSpeech.cs @@ -1,5 +1,4 @@ using System.Diagnostics.CodeAnalysis; -using System.IO; namespace AdaptiveRemote.Services.Conversation; diff --git a/src/AdaptiveRemote.App/Services/Conversation/SamplesRecorder.cs b/src/AdaptiveRemote.App/Services/Conversation/SamplesRecorder.cs index 75b3f9d..e593b23 100644 --- a/src/AdaptiveRemote.App/Services/Conversation/SamplesRecorder.cs +++ b/src/AdaptiveRemote.App/Services/Conversation/SamplesRecorder.cs @@ -1,6 +1,4 @@ -using System.IO; -using AdaptiveRemote.Utilities; -using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; diff --git a/src/AdaptiveRemote.App/Services/IFileSystem.cs b/src/AdaptiveRemote.App/Services/IFileSystem.cs index 97e5329..6b045fc 100644 --- a/src/AdaptiveRemote.App/Services/IFileSystem.cs +++ b/src/AdaptiveRemote.App/Services/IFileSystem.cs @@ -1,6 +1,4 @@ -using System.IO; - -namespace AdaptiveRemote.Services; +namespace AdaptiveRemote.Services; /// /// Abstraction for the file system diff --git a/src/AdaptiveRemote.App/Services/IFileSystemExtensions.cs b/src/AdaptiveRemote.App/Services/IFileSystemExtensions.cs index 2b42c67..71e1679 100644 --- a/src/AdaptiveRemote.App/Services/IFileSystemExtensions.cs +++ b/src/AdaptiveRemote.App/Services/IFileSystemExtensions.cs @@ -1,6 +1,4 @@ -using System.IO; - -namespace AdaptiveRemote.Services; +namespace AdaptiveRemote.Services; internal static class IFileSystemExtensions { diff --git a/src/AdaptiveRemote.App/Services/Lifecycle/LifecycleViewController.cs b/src/AdaptiveRemote.App/Services/Lifecycle/LifecycleViewController.cs index 51453c8..000db64 100644 --- a/src/AdaptiveRemote.App/Services/Lifecycle/LifecycleViewController.cs +++ b/src/AdaptiveRemote.App/Services/Lifecycle/LifecycleViewController.cs @@ -5,6 +5,7 @@ namespace AdaptiveRemote.Services.Lifecycle; internal class LifecycleViewController : ILifecycleViewController { private readonly List _activities; + private readonly object _lock = new(); public LifecycleViewController(LifecycleView viewModel) { @@ -54,7 +55,6 @@ private static string DescriptionFor(LifecyclePhase phase) _ => string.Empty, }; - private object _lock = new(); private void UpdateTaskName() { lock (_lock) diff --git a/src/AdaptiveRemote.App/Services/ProgrammaticSettings/PersistSettings.cs b/src/AdaptiveRemote.App/Services/ProgrammaticSettings/PersistSettings.cs index e8eaae6..6851abc 100644 --- a/src/AdaptiveRemote.App/Services/ProgrammaticSettings/PersistSettings.cs +++ b/src/AdaptiveRemote.App/Services/ProgrammaticSettings/PersistSettings.cs @@ -1,5 +1,4 @@ using System.Collections.Concurrent; -using System.IO; using System.Text.RegularExpressions; using AdaptiveRemote.Logging; using Microsoft.Extensions.Logging; @@ -15,19 +14,19 @@ internal class PersistSettings : IPersistSettings private const string ValueKey = "value"; private const string ValuePattern = @"[^\\r\\n]*"; - private static Regex KeyRegex = new($"^{NamePattern}$", RegexOptions.Singleline); - private static Regex ValueRegex = new($"^{ValuePattern}$", RegexOptions.Singleline); - private static Regex LineRegex = new($"^(?<{NameKey}>{NamePattern}){Separator}(?<{ValueKey}>{ValuePattern})$"); + private static readonly Regex KeyRegex = new($"^{NamePattern}$", RegexOptions.Singleline); + private static readonly Regex ValueRegex = new($"^{ValuePattern}$", RegexOptions.Singleline); + private static readonly Regex LineRegex = new($"^(?<{NameKey}>{NamePattern}){Separator}(?<{ValueKey}>{ValuePattern})$"); private readonly IFileSystem _fileSystem; private readonly string _filePath; private readonly ILogger _logger; private readonly Lazy>> _lazyValues; + private readonly object _lockObject = new(); private bool _needsSave = false; private bool _isSaving = false; - private object _lockObject = new(); public PersistSettings(IFileSystem fileSystem, IOptions settings, ILogger logger) { diff --git a/src/AdaptiveRemote.App/Services/SystemWrappers/SystemIOWrapper.cs b/src/AdaptiveRemote.App/Services/SystemWrappers/SystemIOWrapper.cs index 471b1e9..d466471 100644 --- a/src/AdaptiveRemote.App/Services/SystemWrappers/SystemIOWrapper.cs +++ b/src/AdaptiveRemote.App/Services/SystemWrappers/SystemIOWrapper.cs @@ -1,6 +1,4 @@ -using System.IO; - -namespace AdaptiveRemote.Services.SystemWrappers; +namespace AdaptiveRemote.Services.SystemWrappers; internal class SystemIOWrapper : IFileSystem { diff --git a/src/AdaptiveRemote.App/Services/Testing/TestEndpointService.cs b/src/AdaptiveRemote.App/Services/Testing/TestEndpointService.cs index 936d4ba..d38e2df 100644 --- a/src/AdaptiveRemote.App/Services/Testing/TestEndpointService.cs +++ b/src/AdaptiveRemote.App/Services/Testing/TestEndpointService.cs @@ -4,7 +4,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using StreamJsonRpc; -using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; using System.Reflection; @@ -19,20 +18,16 @@ internal class TestEndpointService : BackgroundService, ITestEndpoint { private readonly TestingSettings _settings; private readonly IApplicationScopeProvider _scopeProvider; - private readonly ILoggerFactory _loggerFactory; private readonly ILogger _logger; - private readonly ConcurrentDictionary _loggers = new(); private TcpListener? _listener; public TestEndpointService( IOptions settings, IApplicationScopeProvider scopeProvider, - ILoggerFactory loggerFactory, ILogger logger) { _settings = settings.Value; _scopeProvider = scopeProvider; - _loggerFactory = loggerFactory; _logger = logger; } diff --git a/src/AdaptiveRemote.App/Services/TiVo/LibraryTiVoConnection.cs b/src/AdaptiveRemote.App/Services/TiVo/LibraryTiVoConnection.cs index bafd257..276f70f 100644 --- a/src/AdaptiveRemote.App/Services/TiVo/LibraryTiVoConnection.cs +++ b/src/AdaptiveRemote.App/Services/TiVo/LibraryTiVoConnection.cs @@ -1,5 +1,4 @@ -using System.IO; -using System.Net; +using System.Net; using AdaptiveRemote.Logging; using I8Beef.TiVo; using I8Beef.TiVo.Commands; diff --git a/src/AdaptiveRemote/App.xaml.cs b/src/AdaptiveRemote/App.xaml.cs index 615ea99..3bc1ba0 100644 --- a/src/AdaptiveRemote/App.xaml.cs +++ b/src/AdaptiveRemote/App.xaml.cs @@ -1,9 +1,6 @@ using System.Windows; using AdaptiveRemote.Services.Lifecycle; -using AdaptiveRemote.Services.Testing; -using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Hosting; -using Microsoft.Web.WebView2.Core; namespace AdaptiveRemote; @@ -15,7 +12,7 @@ protected override void OnStartup(StartupEventArgs e) { WpfAcceleratedServices accelerator = CreateAcceleratedServices(e.Args); accelerator.ViewModel.ShutdownCommand = new ActionCommand(Shutdown); - + accelerator.MainWindow.Show(); IHostBuilder hostBuilder = Host.CreateDefaultBuilder(e.Args) diff --git a/src/AdaptiveRemote/AppHostConfiguration.cs b/src/AdaptiveRemote/AppHostConfiguration.cs index 12919bf..56291e0 100644 --- a/src/AdaptiveRemote/AppHostConfiguration.cs +++ b/src/AdaptiveRemote/AppHostConfiguration.cs @@ -1,6 +1,5 @@ using AdaptiveRemote.Services.Conversation; using AdaptiveRemote.Services.Lifecycle; -using AdaptiveRemote.Services.Testing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; diff --git a/src/AdaptiveRemote/MainWindow.xaml.cs b/src/AdaptiveRemote/MainWindow.xaml.cs index f1aedf9..0ef9ff8 100644 --- a/src/AdaptiveRemote/MainWindow.xaml.cs +++ b/src/AdaptiveRemote/MainWindow.xaml.cs @@ -1,7 +1,7 @@ -using System.ComponentModel; -using System.Windows; +using System.Windows; namespace AdaptiveRemote; + /// /// Interaction logic for MainWindow.xaml /// diff --git a/src/AdaptiveRemote/Services/Lifecycle/BlazorWebViewDebugger.cs b/src/AdaptiveRemote/Services/Lifecycle/BlazorWebViewDebugger.cs index a03d21f..7b12ceb 100644 --- a/src/AdaptiveRemote/Services/Lifecycle/BlazorWebViewDebugger.cs +++ b/src/AdaptiveRemote/Services/Lifecycle/BlazorWebViewDebugger.cs @@ -1,6 +1,5 @@ using AdaptiveRemote.Services.Testing; using Microsoft.AspNetCore.Components.WebView.Wpf; -using Microsoft.Extensions.Configuration; namespace AdaptiveRemote.Services.Lifecycle; diff --git a/src/AdaptiveRemote/Services/Lifecycle/BlazorWindowServicesSetter.cs b/src/AdaptiveRemote/Services/Lifecycle/BlazorWindowServicesSetter.cs index e74245d..3ef4ab6 100644 --- a/src/AdaptiveRemote/Services/Lifecycle/BlazorWindowServicesSetter.cs +++ b/src/AdaptiveRemote/Services/Lifecycle/BlazorWindowServicesSetter.cs @@ -20,6 +20,6 @@ public BlazorWindowServicesSetter(MainWindow mainWindow, IServiceProvider servic public async Task StartAsync(CancellationToken cancellationToken) => await _browser.Dispatcher.InvokeAsync(() => _browser.Services = _services); - + public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; } diff --git a/src/AdaptiveRemote/Services/Lifecycle/WpfAcceleratedServices.cs b/src/AdaptiveRemote/Services/Lifecycle/WpfAcceleratedServices.cs index 23df780..b9ca058 100644 --- a/src/AdaptiveRemote/Services/Lifecycle/WpfAcceleratedServices.cs +++ b/src/AdaptiveRemote/Services/Lifecycle/WpfAcceleratedServices.cs @@ -1,13 +1,12 @@ using AdaptiveRemote.Services.Testing; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; namespace AdaptiveRemote.Services.Lifecycle; public class WpfAcceleratedServices : AcceleratedServices { - private IBrowserDebuggerAccess? _browserDebugger = null; + private readonly IBrowserDebuggerAccess? _browserDebugger; public WpfAcceleratedServices(string[] args) : base(args) @@ -28,7 +27,7 @@ public WpfAcceleratedServices(string[] args) public MainWindow MainWindow { get; } - protected override void AddPrecreatedServices(IServiceCollection services) + protected override void AddPrecreatedServices(IServiceCollection services) { base.AddPrecreatedServices(services); diff --git a/test/AdaptiveRemote.App.Tests/Services/CommandServiceBaseTests.cs b/test/AdaptiveRemote.App.Tests/Services/CommandServiceBaseTests.cs index d9d303d..ae19453 100644 --- a/test/AdaptiveRemote.App.Tests/Services/CommandServiceBaseTests.cs +++ b/test/AdaptiveRemote.App.Tests/Services/CommandServiceBaseTests.cs @@ -17,7 +17,7 @@ public class CommandServiceBaseTests private ILifecycleActivity InitializeActivity => MockInitializeActivity.Object; private ILifecycleActivity CleanupActivity => MockCleanupActivity.Object; - private LayoutGroup RemoteDefinition = new LayoutGroup("ROOT", + private readonly LayoutGroup RemoteDefinition = new LayoutGroup("ROOT", [ new MockCommand("Mock1") { IsEnabled = true, IsActive = true }, new OtherCommand("Other1") { IsEnabled = true, IsActive = true }, diff --git a/test/AdaptiveRemote.App.Tests/Services/Lifecycle/ApplicationLifecycleTests.cs b/test/AdaptiveRemote.App.Tests/Services/Lifecycle/ApplicationLifecycleTests.cs index c78203e..e3e6ef9 100644 --- a/test/AdaptiveRemote.App.Tests/Services/Lifecycle/ApplicationLifecycleTests.cs +++ b/test/AdaptiveRemote.App.Tests/Services/Lifecycle/ApplicationLifecycleTests.cs @@ -253,7 +253,7 @@ public void ApplicationLifecycle_StartAsync_ErrorDuringConstructor_SetsFatalErro .Verifiable(Times.Once); Expect_SetFatalErrorOn(MockLifecycleViewController, expectedError1); - + // Act Task startTask = sut.StartAsync(default); diff --git a/test/AdaptiveRemote.App.Tests/Services/Lifecycle/ScopedLifecycleContainerTests.cs b/test/AdaptiveRemote.App.Tests/Services/Lifecycle/ScopedLifecycleContainerTests.cs index 352e423..7af6da2 100644 --- a/test/AdaptiveRemote.App.Tests/Services/Lifecycle/ScopedLifecycleContainerTests.cs +++ b/test/AdaptiveRemote.App.Tests/Services/Lifecycle/ScopedLifecycleContainerTests.cs @@ -1,8 +1,5 @@ using AdaptiveRemote.Logging; -using AdaptiveRemote.Models; -using AdaptiveRemote.TestUtilities; using FluentAssertions; -using Microsoft.Extensions.Logging; using Moq; namespace AdaptiveRemote.Services.Lifecycle; diff --git a/test/AdaptiveRemote.App.Tests/Services/ScopedBackgroundProcessTests.cs b/test/AdaptiveRemote.App.Tests/Services/ScopedBackgroundProcessTests.cs index 8ab013a..ae1b71a 100644 --- a/test/AdaptiveRemote.App.Tests/Services/ScopedBackgroundProcessTests.cs +++ b/test/AdaptiveRemote.App.Tests/Services/ScopedBackgroundProcessTests.cs @@ -176,10 +176,10 @@ public void ScopedBackgroundProcess_InitializeAsync_OnErrorDuringInitialize_Retu // Arrange Exception expectedException = new DataMisalignedException(); + // No error logged here because lifecycle should report it TestBackgroundProcess sut = CreateSut() .Expect_LogMessages( Expect_Starting - // No error logged here because lifecycle should report it ); sut.ExecuteCompletionSource.SetException(expectedException); diff --git a/test/AdaptiveRemote.App.Tests/TestUtilities/MockLogger.cs b/test/AdaptiveRemote.App.Tests/TestUtilities/MockLogger.cs index ccf0ae3..aef7521 100644 --- a/test/AdaptiveRemote.App.Tests/TestUtilities/MockLogger.cs +++ b/test/AdaptiveRemote.App.Tests/TestUtilities/MockLogger.cs @@ -9,8 +9,8 @@ internal class MockLogger : MockLogger, I internal class MockLogger : ILogger { private readonly List _messages = new(); + private readonly object _lock = new(); private Exception? _assertException = null; - private object _lock = new(); public IEnumerable Messages => _messages; public TestContext? OutputWriter { get; set; } diff --git a/test/AdaptiveRemote.App.Tests/TestUtilities/TaskAssert.cs b/test/AdaptiveRemote.App.Tests/TestUtilities/TaskAssert.cs index 2bd99c7..691a847 100644 --- a/test/AdaptiveRemote.App.Tests/TestUtilities/TaskAssert.cs +++ b/test/AdaptiveRemote.App.Tests/TestUtilities/TaskAssert.cs @@ -52,11 +52,9 @@ public AndConstraint> HaveResult(TResult expectedResult, .TaskShouldBeCompleted() .Given(task => ((Task)task).Result) .ForCondition(CheckEquivalency) - //.ForCondition(result => (result is null) == (expectedResult is null)) - //.FailWith("found {context}.Result=") - //.Then - //.ForCondition(result => result!.Equals(expectedResult)) - .FailWith("found {context}.Result={0}", result => result); + .FailWith( + "found {context}.Result={0}", + result => result); }); return Continuation(); diff --git a/test/AdaptiveRemote.EndtoEndTests.TestServices/ApplicationTestService.cs b/test/AdaptiveRemote.EndtoEndTests.TestServices/ApplicationTestService.cs index 9bdfa86..5c80907 100644 --- a/test/AdaptiveRemote.EndtoEndTests.TestServices/ApplicationTestService.cs +++ b/test/AdaptiveRemote.EndtoEndTests.TestServices/ApplicationTestService.cs @@ -24,7 +24,7 @@ public async Task InvokeCommandAsync(string commandName, CancellationToken cance // Find the Exit command by walking the remote tree Command command = FindCommandByName(_remoteDefinitionService.RemoteRoot, commandName) ?? throw new InvalidOperationException($"{commandName} command not found in remote definition service"); - + if (command.ExecuteAsync is null) { throw new InvalidOperationException($"{commandName} command does not have an ExecuteAsync delegate"); diff --git a/test/AdaptiveRemote.EndtoEndTests.TestServices/BlazorWebViewUITestService.cs b/test/AdaptiveRemote.EndtoEndTests.TestServices/BlazorWebViewUITestService.cs index 8c687f0..40e6dbb 100644 --- a/test/AdaptiveRemote.EndtoEndTests.TestServices/BlazorWebViewUITestService.cs +++ b/test/AdaptiveRemote.EndtoEndTests.TestServices/BlazorWebViewUITestService.cs @@ -13,7 +13,7 @@ public class BlazorWebViewUITestService : PlaywrightUITestService private static readonly TimeSpan InitializePlaywrightTimeout = TimeSpan.FromSeconds(30); public BlazorWebViewUITestService(IBrowserDebuggerAccess browserDebugger, ILogger logger) - : base (new BrowserFromPortProvider(browserDebugger, logger)) + : base(new BrowserFromPortProvider(browserDebugger, logger)) { } @@ -85,7 +85,9 @@ public void Dispose() { _ = _browser.Value.CloseAsync().ConfigureAwait(false); } - catch { } + catch + { + } } if (_playwright.IsValueCreated) diff --git a/test/AdaptiveRemote.EndtoEndTests.TestServices/ILoggerExtensions.cs b/test/AdaptiveRemote.EndtoEndTests.TestServices/ILoggerExtensions.cs index 5defd4d..b553fe6 100644 --- a/test/AdaptiveRemote.EndtoEndTests.TestServices/ILoggerExtensions.cs +++ b/test/AdaptiveRemote.EndtoEndTests.TestServices/ILoggerExtensions.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; namespace AdaptiveRemote.EndtoEndTests; @@ -14,10 +9,10 @@ public static IDisposable LogTimedOperation(this ILogger logger, string operatio return new TimedOperation(logger, operationDescription); } - private class TimedOperation : IDisposable + private sealed class TimedOperation : IDisposable { - private ILogger _logger; - private string _operationDescription; + private readonly ILogger _logger; + private readonly string _operationDescription; private readonly DateTime _startTime; public TimedOperation(ILogger logger, string operationDescription) diff --git a/test/AdaptiveRemote.EndtoEndTests.TestServices/PlaywrightUITestService.cs b/test/AdaptiveRemote.EndtoEndTests.TestServices/PlaywrightUITestService.cs index 8bc0376..0f361b8 100644 --- a/test/AdaptiveRemote.EndtoEndTests.TestServices/PlaywrightUITestService.cs +++ b/test/AdaptiveRemote.EndtoEndTests.TestServices/PlaywrightUITestService.cs @@ -18,13 +18,13 @@ public PlaywrightUITestService(IBrowserUIAccess browserProvider) _browserProvider = browserProvider; } - private IPage CurrentPage => _browserProvider.CurrentPage as IPage + private IPage CurrentPage => _browserProvider.CurrentPage as IPage ?? throw new InvalidOperationException("IBrowserProvider service did not provide an object of type IPage"); public async Task IsButtonVisibleAsync(string label, CancellationToken cancellationToken = default) { ILocator locator = GetButtonLocatorByLabelAsync(label); - + try { return await locator.IsVisibleAsync(); @@ -38,7 +38,7 @@ public async Task IsButtonVisibleAsync(string label, CancellationToken can public async Task IsButtonEnabledAsync(string label, CancellationToken cancellationToken = default) { ILocator locator = GetButtonLocatorByLabelAsync(label); - + try { return await locator.IsEnabledAsync(); @@ -52,7 +52,7 @@ public async Task IsButtonEnabledAsync(string label, CancellationToken can public async Task ClickButtonAsync(string label, CancellationToken cancellationToken = default) { ILocator locator = GetButtonLocatorByLabelAsync(label); - + // Verify the button is visible bool isVisible = await locator.IsVisibleAsync(); if (!isVisible) @@ -79,7 +79,7 @@ private static async Task IsButtonDisabledAsync(ILocator locator) bool hasDisabledAttribute = await locator.GetAttributeAsync("disabled") != null; string? ariaDisabled = await locator.GetAttributeAsync("aria-disabled"); bool isAriaDisabled = ariaDisabled == "true"; - + return hasDisabledAttribute || isAriaDisabled; } diff --git a/test/AdaptiveRemote.EndtoEndTests/ConsoleHostTests.cs b/test/AdaptiveRemote.EndtoEndTests/ConsoleHostTests.cs index 07847b6..9397437 100644 --- a/test/AdaptiveRemote.EndtoEndTests/ConsoleHostTests.cs +++ b/test/AdaptiveRemote.EndtoEndTests/ConsoleHostTests.cs @@ -25,12 +25,12 @@ public static void ClassInitialize(TestContext context) } } - protected override AdaptiveRemoteHostSettings GetHostSettings(string solutionRoot) + protected override AdaptiveRemoteHostSettings GetHostSettings(string solutionRoot) => new( - UIService: UIServiceType.BlazorWebView, + UIService: UIServiceType.BlazorWebView, ExePath: Path.Combine(solutionRoot, "src/AdaptiveRemote.Console/bin/Debug/net8.0-windows7.0/AdaptiveRemote.Console.exe")); - protected override ILogger CreateTypedLogger(AdaptiveRemoteHost host) + protected override ILogger CreateTypedLogger(AdaptiveRemoteHost host) => host.CreateLogger(); [TestMethod] diff --git a/test/AdaptiveRemote.EndtoEndTests/HeadlessHostTests.cs b/test/AdaptiveRemote.EndtoEndTests/HeadlessHostTests.cs index bd112c0..e8149a0 100644 --- a/test/AdaptiveRemote.EndtoEndTests/HeadlessHostTests.cs +++ b/test/AdaptiveRemote.EndtoEndTests/HeadlessHostTests.cs @@ -26,14 +26,14 @@ protected override AdaptiveRemoteHostSettings GetHostSettings(string solutionRoo string exeName = System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows) ? "AdaptiveRemote.Headless.exe" : "AdaptiveRemote.Headless"; - + return new( UIService: UIServiceType.Playwright, ExePath: Path.Combine(solutionRoot, $"src/AdaptiveRemote.Headless/bin/Debug/net8.0/{exeName}"), CommandLineArgs: $"--playwright:TracesDir=\"{TracesPath}\""); } - protected override ILogger CreateTypedLogger(AdaptiveRemoteHost host) + protected override ILogger CreateTypedLogger(AdaptiveRemoteHost host) => host.CreateLogger(); [TestMethod] diff --git a/test/AdaptiveRemote.EndtoEndTests/MSTestSettings.cs b/test/AdaptiveRemote.EndtoEndTests/MSTestSettings.cs index ca9e22f..69390b7 100644 --- a/test/AdaptiveRemote.EndtoEndTests/MSTestSettings.cs +++ b/test/AdaptiveRemote.EndtoEndTests/MSTestSettings.cs @@ -1,4 +1,2 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; - // Do not parallelize E2E tests - running multiple GUI applications simultaneously can cause issues [assembly: DoNotParallelize] diff --git a/test/AdaptiveRemote.EndtoEndTests/WpfHostTests.cs b/test/AdaptiveRemote.EndtoEndTests/WpfHostTests.cs index 802a233..1de1b09 100644 --- a/test/AdaptiveRemote.EndtoEndTests/WpfHostTests.cs +++ b/test/AdaptiveRemote.EndtoEndTests/WpfHostTests.cs @@ -27,7 +27,7 @@ public static void ClassInitialize(TestContext context) protected override AdaptiveRemoteHostSettings GetHostSettings(string solutionRoot) => new( - UIService: UIServiceType.BlazorWebView, + UIService: UIServiceType.BlazorWebView, ExePath: Path.Combine(solutionRoot, "src/AdaptiveRemote/bin/Debug/net8.0-windows/AdaptiveRemote.exe")); protected override ILogger CreateTypedLogger(AdaptiveRemoteHost host) diff --git a/test/Directory.Build.props b/test/Directory.Build.props new file mode 100644 index 0000000..9f91ed7 --- /dev/null +++ b/test/Directory.Build.props @@ -0,0 +1,10 @@ + + + + + + + + $(NoWarn);IDE0051;IDE0052;IDE0059 + +