From 2983fdadfc24ff65fd28a4e95288b3344a89399e Mon Sep 17 00:00:00 2001 From: sporty-turks Date: Sat, 15 Jun 2024 08:58:38 +1000 Subject: [PATCH 1/4] initial refactor commit --- .../AssemblyInitialise.cs | 4 +- .../Attributes/CustomTestAttributes.cs | 5 +- .../Core/AppConfiguration.cs | 2 +- .../Core/AssemblyInitialise.cs | 4 +- .../Core/ConfigurationReader.cs | 54 +++---- .../Core/EmptyConfiguration.cs | 6 +- .../Core/ITestManager.cs | 28 ++-- .../Core/MemoryCache.cs | 2 +- .../Core/MethodManager/TestMethodBase.cs | 22 ++- .../Core/MethodManager/TestMethodCore.cs | 11 +- .../Core/MethodManager/TestMethodManager.cs | 24 ++- .../Core/TestAsyncDeterminationInterceptor.cs | 9 +- .../Core/TestBase.cs | 5 +- .../Core/TestManager.cs | 138 +++++++---------- .../Data/XlsLoader.cs | 5 +- .../Client/NewtonsoftJsonSerializer.cs | 4 - .../Core/ServiceTestBase.cs | 6 +- .../Core/ServiceTestManager.cs | 23 +-- .../AutoTestMate.MsTest.Web.csproj | 1 - .../Constants/Exceptions.cs | 1 - AutoTestMate.MsTest.Web/Core/BasePage.cs | 2 +- .../Core/BasePageContainer.cs | 16 +- .../Core/Browser/SeleniumGridDriverFactory.cs | 9 -- .../Core/LinuxOsProcess.cs | 15 +- .../Core/MethodManager/IWebDriverService.cs | 4 +- .../Core/MethodManager/IWebTestMethod.cs | 2 + .../Core/MethodManager/WebDriverService.cs | 28 ++-- .../Core/MethodManager/WebTestMethod.cs | 31 ++-- .../MethodManager/WebTestMethodManager.cs | 11 +- AutoTestMate.MsTest.Web/Core/ProcessUtils.cs | 139 ++++++++---------- .../Core/SeleniumGridDriverCleanup.cs | 41 ++---- AutoTestMate.MsTest.Web/Core/WebTestBase.cs | 6 +- .../Core/WebTestManager.cs | 55 ++----- AutoTestMate.MsTest.Web/Core/WinOsProcess.cs | 14 +- .../Extensions/WebElementExtensions.cs | 2 +- Test.runsettings | 17 +-- 36 files changed, 279 insertions(+), 467 deletions(-) diff --git a/AutoTestMate.MsTest.Infrastructure.IntegrationTests/AssemblyInitialise.cs b/AutoTestMate.MsTest.Infrastructure.IntegrationTests/AssemblyInitialise.cs index 1b91cab..cd1feb4 100644 --- a/AutoTestMate.MsTest.Infrastructure.IntegrationTests/AssemblyInitialise.cs +++ b/AutoTestMate.MsTest.Infrastructure.IntegrationTests/AssemblyInitialise.cs @@ -11,13 +11,13 @@ public class AssemblyInitialise [AssemblyInitialize] public static void Initialise(TestContext testContext) { - WebTestManager.Instance().OnInitialiseAssemblyDependencies(testContext); + WebTestManager.Instance.OnInitialiseAssemblyDependencies(testContext); } [AssemblyCleanup] public static void Cleanup() { - WebTestManager.Instance().OnDisposeAssemblyDependencies(); + WebTestManager.Instance.OnDisposeAssemblyDependencies(); } } } \ No newline at end of file diff --git a/AutoTestMate.MsTest.Infrastructure/Attributes/CustomTestAttributes.cs b/AutoTestMate.MsTest.Infrastructure/Attributes/CustomTestAttributes.cs index fc57c56..cbc7873 100644 --- a/AutoTestMate.MsTest.Infrastructure/Attributes/CustomTestAttributes.cs +++ b/AutoTestMate.MsTest.Infrastructure/Attributes/CustomTestAttributes.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using AutoTestMate.MsTest.Infrastructure.Core; using AutoTestMate.MsTest.Infrastructure.Helpers; @@ -21,9 +22,9 @@ public virtual void CustomAttributesInitialise(string testMethod) var method = GetType().GetMethod(TestContext.TestName); _actionTestDataAttributes = method.GetCustomAttributes(typeof(ITestDataAttribute), true).OfType(); - foreach (var tesdataAttribute in _actionTestDataAttributes) + foreach (var testDataAttribute in _actionTestDataAttributes) { - tesdataAttribute.BeforeTest(testMethod, TestContext, TestManager); + testDataAttribute.BeforeTest(testMethod, TestContext, TestManager); } if (classAttributes.Any()) diff --git a/AutoTestMate.MsTest.Infrastructure/Core/AppConfiguration.cs b/AutoTestMate.MsTest.Infrastructure/Core/AppConfiguration.cs index 613dcb8..71ff846 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/AppConfiguration.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/AppConfiguration.cs @@ -8,7 +8,7 @@ public class AppConfiguration : IConfiguration { public AppConfiguration() { - Settings = new NameValueCollection(); + Settings = []; var configBuilder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) diff --git a/AutoTestMate.MsTest.Infrastructure/Core/AssemblyInitialise.cs b/AutoTestMate.MsTest.Infrastructure/Core/AssemblyInitialise.cs index ccde100..10982f2 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/AssemblyInitialise.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/AssemblyInitialise.cs @@ -8,13 +8,13 @@ public static class AssemblyInitialise [AssemblyInitialize] public static void Initialise(TestContext testContext) { - TestManager.Instance().OnInitialiseAssemblyDependencies(testContext); + TestManager.Instance.OnInitialiseAssemblyDependencies(testContext); } [AssemblyCleanup] public static void Cleanup() { - TestManager.Instance().OnDisposeAssemblyDependencies(); + TestManager.Instance.OnDisposeAssemblyDependencies(); } } } diff --git a/AutoTestMate.MsTest.Infrastructure/Core/ConfigurationReader.cs b/AutoTestMate.MsTest.Infrastructure/Core/ConfigurationReader.cs index 72f47b5..c1c5f53 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/ConfigurationReader.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/ConfigurationReader.cs @@ -10,21 +10,11 @@ namespace AutoTestMate.MsTest.Infrastructure.Core /// public class ConfigurationReader : IConfigurationReader { - #region Private Variables - - private readonly IDictionary _settings; - private readonly IConfiguration _appConfiguration; - private readonly TestContext _testContext; - - #endregion - - #region Constructor - public ConfigurationReader(TestContext testContext, IConfiguration appConfiguration) { - _settings = new Dictionary(); - _testContext = testContext; - _appConfiguration = appConfiguration; + Settings = new Dictionary(); + TestContext = testContext; + AppConfiguration = appConfiguration; if (testContext != null) { @@ -34,13 +24,11 @@ public ConfigurationReader(TestContext testContext, IConfiguration appConfigurat public ConfigurationReader(TestContext testContext, IConfiguration appConfiguration, IDictionary settings) { - _testContext = testContext; - _appConfiguration = appConfiguration; - _settings = settings; + TestContext = testContext; + AppConfiguration = appConfiguration; + Settings = settings; } - #endregion - #region Public Methods /// @@ -48,19 +36,19 @@ public ConfigurationReader(TestContext testContext, IConfiguration appConfigurat /// public string GetConfigurationValue(string key, bool required = false) { - if (_settings.Count == 0 && _appConfiguration.Settings.Count == 0) + if (Settings.Count == 0 && AppConfiguration.Settings.Count == 0) { throw new KeyNotFoundException($"{key} was not found in the test parameters. Please make sure that the solution has an active .runsettings file and that the parameter is valid."); } - var testSettingsValue = _settings.ContainsKey(key) ? _settings[key] : string.Empty; + var testSettingsValue = Settings.TryGetValue(key, out var setting) ? setting : string.Empty; if (!string.IsNullOrWhiteSpace(testSettingsValue)) { return testSettingsValue; } - var appSettingsDict = _appConfiguration.Settings.AllKeys.ToDictionary(k => k, k => _appConfiguration.Settings[k]); - var appSettingsValue = appSettingsDict.ContainsKey(key) ? appSettingsDict[key] : string.Empty; + var appSettingsDict = AppConfiguration.Settings.AllKeys.ToDictionary(k => k, k => AppConfiguration.Settings[k]); + var appSettingsValue = appSettingsDict.TryGetValue(key, out var value) ? value : string.Empty; if (!string.IsNullOrWhiteSpace(appSettingsValue)) { return string.Equals(appSettingsValue, Constants.Configuration.NullValue) ? null : appSettingsValue; @@ -80,13 +68,13 @@ public void SetTestContext(TestContext testContext) foreach (var key in keys) { var value = testContext.Properties[key.ToString()].ToString(); - if (!_settings.TryGetValue(key.ToString(), out _)) + if (!Settings.TryGetValue(key.ToString(), out _)) { - _settings.Add(key.ToString(), value); + Settings.Add(key.ToString(), value); } else { - _settings[key.ToString()] = value; + Settings[key.ToString()] = value; } } @@ -111,17 +99,17 @@ public void SetTestContext(TestContext testContext) } public void AddSetting(string key, string value) { - if (!_settings.ContainsKey(key)) + if (!Settings.ContainsKey(key)) { - _settings.Add(key, value); + Settings.Add(key, value); } } public bool UpdateSetting(string key, string value) { - if (!_settings.ContainsKey(key)) return false; + if (!Settings.ContainsKey(key)) return false; - _settings[key] = value; + Settings[key] = value; return true; } @@ -130,9 +118,11 @@ public bool UpdateSetting(string key, string value) #region Public Properties public string LogLevel => GetConfigurationValue(Constants.Configuration.LogLevelKey); public string LogName => GetConfigurationValue(Constants.Configuration.LogNameKey); - public IDictionary Settings => _settings; - public IConfiguration AppConfiguration => _appConfiguration; - public TestContext TestContext => _testContext; + public IDictionary Settings { get; } + + public IConfiguration AppConfiguration { get; } + + public TestContext TestContext { get; } #endregion } diff --git a/AutoTestMate.MsTest.Infrastructure/Core/EmptyConfiguration.cs b/AutoTestMate.MsTest.Infrastructure/Core/EmptyConfiguration.cs index 87a7f51..045921d 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/EmptyConfiguration.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/EmptyConfiguration.cs @@ -4,10 +4,6 @@ namespace AutoTestMate.MsTest.Infrastructure.Core { public class EmptyConfiguration : IConfiguration { - public EmptyConfiguration() - { - Settings = new NameValueCollection(); - } - public NameValueCollection Settings { get; set; } + public NameValueCollection Settings { get; set; } = []; } } \ No newline at end of file diff --git a/AutoTestMate.MsTest.Infrastructure/Core/ITestManager.cs b/AutoTestMate.MsTest.Infrastructure/Core/ITestManager.cs index 2c69bbc..869a601 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/ITestManager.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/ITestManager.cs @@ -4,23 +4,23 @@ namespace AutoTestMate.MsTest.Infrastructure.Core { - public interface ITestManager - { + public interface ITestManager + { WindsorContainer Container { get; } - TestContext TestContext { get; } - IConfigurationReader ConfigurationReader { get; } - ITestMethodManager TestMethodManager { get; } + TestContext TestContext { get; } + IConfigurationReader ConfigurationReader { get; } + ITestMethodManager TestMethodManager { get; } IConfiguration AppConfiguration { get; } - ILoggingUtility LoggingUtility { get; } - void OnInitialiseAssemblyDependencies(TestContext testContext = null); - void OnDisposeAssemblyDependencies(); + ILoggingUtility LoggingUtility { get; } + void OnInitialiseAssemblyDependencies(TestContext testContext = null); + void OnDisposeAssemblyDependencies(); void OnTestMethodInitialise(string testMethod, TestContext testContext = null); - void OnTestCleanup(string testMethod); - void InitialiseIoc(); - void InitialiseTestContext(TestContext testContext = null); - void InitialiseTestContextDependencies(); + void OnTestCleanup(string testMethod); + void InitialiseIoc(); + void InitialiseTestContext(TestContext testContext = null); + void InitialiseTestContextDependencies(); void Dispose(string testMethod); void UpdateConfigurationReader(string testMethod, IConfigurationReader configurationReader); - void SetTextContext(TestContext testContext); - } + void SetTestContext(TestContext testContext); + } } \ No newline at end of file diff --git a/AutoTestMate.MsTest.Infrastructure/Core/MemoryCache.cs b/AutoTestMate.MsTest.Infrastructure/Core/MemoryCache.cs index 9ffd83e..7f70a1d 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/MemoryCache.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/MemoryCache.cs @@ -5,7 +5,7 @@ namespace AutoTestMate.MsTest.Infrastructure.Core { public class MemoryCache : IMemoryCache { - public const int DefaultCacheMinutes = 5; + private const int DefaultCacheMinutes = 5; private readonly Microsoft.Extensions.Caching.Memory.MemoryCache _memoryCache; diff --git a/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodBase.cs b/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodBase.cs index 4423b44..4b898d4 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodBase.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodBase.cs @@ -5,20 +5,16 @@ namespace AutoTestMate.MsTest.Infrastructure.Core.MethodManager { - public abstract class TestMethodBase : ITestMethodBase, IDisposable + public abstract class TestMethodBase( + ILoggingUtility loggingUtility, + IConfigurationReader configurationReader, + string testMethod) + : ITestMethodBase, IDisposable { - protected TestMethodBase(ILoggingUtility loggingUtility, IConfigurationReader configurationReader, string testMethod) - { - IsInitialised = false; - LoggingUtility = loggingUtility; - ConfigurationReader = configurationReader; - TestMethod = testMethod; - } - - public string TestMethod { get; set; } - public bool IsInitialised { get; set; } - public IConfigurationReader ConfigurationReader { get; set; } - public ILoggingUtility LoggingUtility { get; set; } + public string TestMethod { get; set; } = testMethod; + public bool IsInitialised { get; set; } = false; + public IConfigurationReader ConfigurationReader { get; set; } = configurationReader; + public ILoggingUtility LoggingUtility { get; set; } = loggingUtility; public virtual void Dispose() { diff --git a/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodCore.cs b/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodCore.cs index 96acda7..b8817f7 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodCore.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodCore.cs @@ -1,9 +1,8 @@ namespace AutoTestMate.MsTest.Infrastructure.Core.MethodManager { - public class TestMethodCore : TestMethodBase - { - public TestMethodCore(ILoggingUtility loggingUtility, IConfigurationReader configurationReader, string testMethod): base(loggingUtility, configurationReader, testMethod) - { - } - } + public class TestMethodCore( + ILoggingUtility loggingUtility, + IConfigurationReader configurationReader, + string testMethod) + : TestMethodBase(loggingUtility, configurationReader, testMethod); } \ No newline at end of file diff --git a/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodManager.cs b/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodManager.cs index 7c6efc6..31a9f92 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodManager.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/MethodManager/TestMethodManager.cs @@ -1,25 +1,19 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using Microsoft.VisualStudio.TestTools.UnitTesting; -using NLog.Fluent; namespace AutoTestMate.MsTest.Infrastructure.Core.MethodManager { - public class TestMethodManager : ITestMethodManager + public class TestMethodManager( + TestContext testContext, + IConfiguration appConfiguration, + ILoggingUtility loggingUtility) + : ITestMethodManager { - public TestMethodManager(TestContext testContext, IConfiguration appConfiguration, ILoggingUtility loggingUtility) - { - TestContext = testContext; - AppConfiguration = appConfiguration; - LoggingUtility = loggingUtility; - TestMethods = new ConcurrentDictionary(); - } - - public ConcurrentDictionary TestMethods { get; set; } - public TestContext TestContext { get; set; } - public ILoggingUtility LoggingUtility { get; set; } - public IConfiguration AppConfiguration { get; set; } + public ConcurrentDictionary TestMethods { get; set; } = new(); + public TestContext TestContext { get; set; } = testContext; + public ILoggingUtility LoggingUtility { get; set; } = loggingUtility; + public IConfiguration AppConfiguration { get; set; } = appConfiguration; public virtual void CheckTestAlreadyInitialised(string testMethod) { diff --git a/AutoTestMate.MsTest.Infrastructure/Core/TestAsyncDeterminationInterceptor.cs b/AutoTestMate.MsTest.Infrastructure/Core/TestAsyncDeterminationInterceptor.cs index ac0dd41..d49d5eb 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/TestAsyncDeterminationInterceptor.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/TestAsyncDeterminationInterceptor.cs @@ -2,9 +2,6 @@ namespace AutoTestMate.MsTest.Infrastructure.Core; -public class TestAsyncDeterminationInterceptor : AsyncDeterminationInterceptor where TInterceptor: IAsyncInterceptor -{ - public TestAsyncDeterminationInterceptor(TInterceptor asyncInterceptor) : base((IAsyncInterceptor)asyncInterceptor) - { - } -} \ No newline at end of file +public class TestAsyncDeterminationInterceptor(TInterceptor asyncInterceptor) + : AsyncDeterminationInterceptor(asyncInterceptor) + where TInterceptor : IAsyncInterceptor; \ No newline at end of file diff --git a/AutoTestMate.MsTest.Infrastructure/Core/TestBase.cs b/AutoTestMate.MsTest.Infrastructure/Core/TestBase.cs index c8ec15d..0bad73c 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/TestBase.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/TestBase.cs @@ -15,7 +15,7 @@ public virtual void OnTestInitialise() try { - TestManager = Core.TestManager.Instance(); + TestManager = Core.TestManager.Instance; TestManager.OnTestMethodInitialise(testMethod, TestContext); CustomAttributesInitialise(testMethod); } @@ -30,13 +30,12 @@ public virtual void OnTestInitialise() } [TestCleanup] - public virtual void OnTestCleanup() + public virtual void OnTestCleanUp() { var testMethod = TestContext.TestName; try { - CustomAttributesCleanup(testMethod); TestManager.Dispose(testMethod); diff --git a/AutoTestMate.MsTest.Infrastructure/Core/TestManager.cs b/AutoTestMate.MsTest.Infrastructure/Core/TestManager.cs index 0a4c15e..c950a59 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/TestManager.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/TestManager.cs @@ -8,53 +8,27 @@ namespace AutoTestMate.MsTest.Infrastructure.Core { - public class TestManager : ITestManager - { - #region Private Variables - - private static TestManager _uniqueInstance; - private static readonly object SyncLock = new Object(); - - #endregion - - #region Constructor - - protected TestManager() { } - - #endregion - - #region Properties - public static TestManager Instance() - { - // Lock entire body of method - lock (SyncLock) - { - // ReSharper disable once ConvertIfStatementToNullCoalescingExpression - if (_uniqueInstance == null) - { - _uniqueInstance = new TestManager(); - } - - return _uniqueInstance; - } - } - public WindsorContainer Container { get; set; } - public ILoggingUtility LoggingUtility => Container.Resolve(); - public IConfigurationReader ConfigurationReader => Container.Resolve(); + public class TestManager : ITestManager + { + private static readonly Lazy Singleton = new(() => new TestManager()); + public static TestManager Instance => Singleton.Value; + + protected TestManager() { } + + public WindsorContainer Container { get; private set; } + public ILoggingUtility LoggingUtility => Container.Resolve(); + public IConfigurationReader ConfigurationReader => Container.Resolve(); public IConfiguration AppConfiguration => Container.Resolve(); - public ITestMethodManager TestMethodManager => Container.Resolve(); + public ITestMethodManager TestMethodManager => Container.Resolve(); public TestContext TestContext => Container.Resolve(); - #endregion - - #region Public Methods - public virtual void OnInitialiseAssemblyDependencies(TestContext testContext = null) { InitialiseIoc(); InitialiseTestContext(testContext); InitialiseTestContextDependencies(); } + public virtual void OnDisposeAssemblyDependencies() { Dispose(null); @@ -63,16 +37,15 @@ public virtual void OnDisposeAssemblyDependencies() public virtual void OnTestMethodInitialise(string testMethod, TestContext testContext = null) { - TestMethodManager.CheckTestAlreadyInitialised(testMethod); + TestMethodManager.CheckTestAlreadyInitialised(testMethod); - try + try { TestMethodManager.Add(testMethod); } catch (Exception exp) { LoggingUtility.Error(exp.Message); - //Dispose(testMethod); This should be called on TestCleanup throw; } } @@ -86,62 +59,57 @@ public virtual void InitialiseTestContext(TestContext testContext = null) { if (testContext == null) return; - Container.Register(Component.For().Instance(testContext).OverridesExistingRegistration()) - .Register(Component.For().ImplementedBy().OverridesExistingRegistration()) - .Register(Component.For().ImplementedBy().LifestyleSingleton()) - .Register(Component.For().Instance(this).OverridesExistingRegistration().LifeStyle.Singleton); + Container.Register( + Component.For().Instance(testContext).OverridesExistingRegistration(), + Component.For().ImplementedBy().OverridesExistingRegistration(), + Component.For().ImplementedBy().LifestyleSingleton(), + Component.For().Instance(this).OverridesExistingRegistration().LifeStyle.Singleton + ); - if (TestContext.Properties["UseAppSettings"] != null && TestContext.Properties["UseAppSettings"].ToString().ToLower() == "false")//issue with linux - { - Container.Register(Component.For().ImplementedBy().LifestyleSingleton()); - } - else - { - Container.Register(Component.For().ImplementedBy().LifestyleSingleton()); - } + var useAppSettings = TestContext.Properties["UseAppSettings"]?.ToString().ToLower() != "false"; + var configurationType = useAppSettings ? typeof(AppConfiguration) : typeof(EmptyConfiguration); + + Container.Register(Component.For().ImplementedBy(configurationType).LifestyleSingleton()); } - - public virtual void InitialiseIoc() + + public virtual void InitialiseIoc() { var container = new WindsorContainer(new DefaultKernel(new AutomationDependencyResolver(), null), new DefaultComponentInstaller()); - container.Register(Component.For().ImplementedBy().LifestyleSingleton()) - .Register(Component.For().ImplementedBy()) - .Register(Component.For().ImplementedBy().LifestyleSingleton()); + container.Register( + Component.For().ImplementedBy().LifestyleSingleton(), + Component.For().ImplementedBy(), + Component.For().ImplementedBy().LifestyleSingleton() + ); Container = container; } - public virtual void InitialiseTestContextDependencies() - { + public virtual void InitialiseTestContextDependencies() + { + // Implementation can be provided here or in inheritted classes } - public virtual void UpdateConfigurationReader(string testMethod, IConfigurationReader configurationReader) - { - if (configurationReader != null) - { - TestMethodManager.UpdateConfigurationReader(testMethod, configurationReader); - } - else //TODO: check to see if this can be removed, possibly no longer required - { - var updateConfigurationReader = new ConfigurationReader(TestContext, AppConfiguration); - TestMethodManager.UpdateConfigurationReader(testMethod, updateConfigurationReader); - } - } - public virtual void Dispose(string testMethod) + + public virtual void UpdateConfigurationReader(string testMethod, IConfigurationReader configurationReader) { - if (string.IsNullOrWhiteSpace(testMethod)) - { - TestMethodManager.Dispose(); - return; - } - - TestMethodManager.Dispose(testMethod); + var reader = configurationReader ?? new ConfigurationReader(TestContext, AppConfiguration); + TestMethodManager.UpdateConfigurationReader(testMethod, reader); } - public void SetTextContext(TestContext testContext) + + public virtual void Dispose(string testMethod) { - Container.Register(Component.For().Instance(testContext).OverridesExistingRegistration()); + if (string.IsNullOrWhiteSpace(testMethod)) + { + TestMethodManager.Dispose(); + return; + } + + TestMethodManager.Dispose(testMethod); } - #endregion - } -} + public virtual void SetTestContext(TestContext testContext) + { + Container.Register(Component.For().Instance(testContext).OverridesExistingRegistration()); + } + } +} \ No newline at end of file diff --git a/AutoTestMate.MsTest.Infrastructure/Data/XlsLoader.cs b/AutoTestMate.MsTest.Infrastructure/Data/XlsLoader.cs index 9d12de4..d214954 100644 --- a/AutoTestMate.MsTest.Infrastructure/Data/XlsLoader.cs +++ b/AutoTestMate.MsTest.Infrastructure/Data/XlsLoader.cs @@ -77,10 +77,7 @@ public DataTable AsDataTable() public IEnumerable AsDataRows() { - if (_table == null) - { - _table = AsDataTable(); - } + _table ??= AsDataTable(); return new List(); } diff --git a/AutoTestMate.MsTest.Services/Client/NewtonsoftJsonSerializer.cs b/AutoTestMate.MsTest.Services/Client/NewtonsoftJsonSerializer.cs index d7ad7de..34b21f9 100644 --- a/AutoTestMate.MsTest.Services/Client/NewtonsoftJsonSerializer.cs +++ b/AutoTestMate.MsTest.Services/Client/NewtonsoftJsonSerializer.cs @@ -47,7 +47,6 @@ public string Serialize(object obj) { using (var stringWriter = new StringWriter()) - { using (var jsonTextWriter = new JsonTextWriter(stringWriter)) @@ -66,12 +65,9 @@ public T Deserialize(RestSharp.IRestResponse response) { var content = response.Content; - using (var stringReader = new StringReader(content)) - { using (var jsonTextReader = new JsonTextReader(stringReader)) - { return _serializer.Deserialize(jsonTextReader); } diff --git a/AutoTestMate.MsTest.Services/Core/ServiceTestBase.cs b/AutoTestMate.MsTest.Services/Core/ServiceTestBase.cs index 705d8a2..16611bf 100644 --- a/AutoTestMate.MsTest.Services/Core/ServiceTestBase.cs +++ b/AutoTestMate.MsTest.Services/Core/ServiceTestBase.cs @@ -16,7 +16,7 @@ public override void OnTestInitialise() var testMethod = TestContext.TestName; try { - TestManager = ServiceTestManager.Instance(); + TestManager = ServiceTestManager.Instance; TestManager.OnTestMethodInitialise(testMethod,TestContext); CustomAttributesInitialise(testMethod); } @@ -27,9 +27,9 @@ public override void OnTestInitialise() } [TestCleanup] - public override void OnTestCleanup() + public override void OnTestCleanUp() { - base.OnTestCleanup(); + base.OnTestCleanUp(); } #endregion diff --git a/AutoTestMate.MsTest.Services/Core/ServiceTestManager.cs b/AutoTestMate.MsTest.Services/Core/ServiceTestManager.cs index f812a11..9229f1b 100644 --- a/AutoTestMate.MsTest.Services/Core/ServiceTestManager.cs +++ b/AutoTestMate.MsTest.Services/Core/ServiceTestManager.cs @@ -10,29 +10,12 @@ namespace AutoTestMate.MsTest.Services.Core { public class ServiceTestManager : TestManager { - #region Private Variables - - private static ServiceTestManager _uniqueInstance; - private static readonly object SyncLock = new Object(); - - #endregion + + private static readonly Lazy Singleton = new(() => new ServiceTestManager()); + public new static ServiceTestManager Instance => Singleton.Value; #region Properties - public new static ServiceTestManager Instance() - { - // Lock entire body of method - lock (SyncLock) - { - // ReSharper disable once ConvertIfStatementToNullCoalescingExpression - if (_uniqueInstance == null) - { - _uniqueInstance = new ServiceTestManager(); - } - return _uniqueInstance; - } - } - public virtual bool UseWcfServices { get diff --git a/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj b/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj index 92b8243..e71e4e1 100644 --- a/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj +++ b/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj @@ -34,7 +34,6 @@ - diff --git a/AutoTestMate.MsTest.Web/Constants/Exceptions.cs b/AutoTestMate.MsTest.Web/Constants/Exceptions.cs index 82615be..60f7b6e 100644 --- a/AutoTestMate.MsTest.Web/Constants/Exceptions.cs +++ b/AutoTestMate.MsTest.Web/Constants/Exceptions.cs @@ -2,7 +2,6 @@ { public class Exceptions { - #region Constants public const string ExceptionMsgWebBrowserWaitInstanceNotInitialised = "The WebDriver browser wait instance was not initialized. You should first call the method Start."; diff --git a/AutoTestMate.MsTest.Web/Core/BasePage.cs b/AutoTestMate.MsTest.Web/Core/BasePage.cs index c9b4d75..9909832 100644 --- a/AutoTestMate.MsTest.Web/Core/BasePage.cs +++ b/AutoTestMate.MsTest.Web/Core/BasePage.cs @@ -17,7 +17,7 @@ public abstract class BasePage protected BasePage(string testMethod) { TestMethod = testMethod; - WebTestManager = WebTestManager.Instance(); + WebTestManager = WebTestManager.Instance; WebTestMethodManager = WebTestManager.WebTestMethodManager; WebTestMethod = (WebTestMethod)WebTestMethodManager.TryGetValue(testMethod); Driver = WebTestMethod?.WebDriver; diff --git a/AutoTestMate.MsTest.Web/Core/BasePageContainer.cs b/AutoTestMate.MsTest.Web/Core/BasePageContainer.cs index 8041ac8..e762e15 100644 --- a/AutoTestMate.MsTest.Web/Core/BasePageContainer.cs +++ b/AutoTestMate.MsTest.Web/Core/BasePageContainer.cs @@ -10,10 +10,6 @@ namespace AutoTestMate.MsTest.Web.Core [ExcludeFromCodeCoverage] public abstract class BasePageContainer { - private readonly IWebDriver _driver; - private readonly IConfigurationReader _configurationReader; - private readonly ILoggingUtility _loggingUtility; - /// /// Constructor of Base Page /// @@ -22,15 +18,15 @@ protected BasePageContainer(ITestMethodManager testMethodManager, TestContext te var webTestMethodManager = (WebTestMethodManager)testMethodManager; var webTestMethod = (WebTestMethod)webTestMethodManager.TryGetValue(testContext.TestName); - _driver = webTestMethod?.WebDriver; - _configurationReader = webTestMethod?.ConfigurationReader; - _loggingUtility = webTestMethodManager.LoggingUtility; + Driver = webTestMethod?.WebDriver; + ConfigurationReader = webTestMethod?.ConfigurationReader; + LoggingUtility = webTestMethodManager.LoggingUtility; } - public IWebDriver Driver => _driver; + public IWebDriver Driver { get; } - public IConfigurationReader ConfigurationReader => _configurationReader; + public IConfigurationReader ConfigurationReader { get; } - public ILoggingUtility LoggingUtility => _loggingUtility; + public ILoggingUtility LoggingUtility { get; } } } \ No newline at end of file diff --git a/AutoTestMate.MsTest.Web/Core/Browser/SeleniumGridDriverFactory.cs b/AutoTestMate.MsTest.Web/Core/Browser/SeleniumGridDriverFactory.cs index d3f7130..6d67a5c 100644 --- a/AutoTestMate.MsTest.Web/Core/Browser/SeleniumGridDriverFactory.cs +++ b/AutoTestMate.MsTest.Web/Core/Browser/SeleniumGridDriverFactory.cs @@ -1,18 +1,9 @@ using System; -using System.ComponentModel.DataAnnotations; using System.Diagnostics.CodeAnalysis; -using System.IO; -using System.Reflection; using System.Text; using AutoTestMate.MsTest.Infrastructure.Core; -using AutoTestMate.MsTest.Infrastructure.Helpers; using AutoTestMate.MsTest.Web.Constants; -using AutoTestMate.MsTest.Web.Enums; using OpenQA.Selenium; -using OpenQA.Selenium.Chrome; -using OpenQA.Selenium.Edge; -using OpenQA.Selenium.Firefox; -using OpenQA.Selenium.IE; using OpenQA.Selenium.Remote; //using System.Text.Encoding.CodePages; diff --git a/AutoTestMate.MsTest.Web/Core/LinuxOsProcess.cs b/AutoTestMate.MsTest.Web/Core/LinuxOsProcess.cs index 9239af4..e2bf6d4 100644 --- a/AutoTestMate.MsTest.Web/Core/LinuxOsProcess.cs +++ b/AutoTestMate.MsTest.Web/Core/LinuxOsProcess.cs @@ -8,17 +8,10 @@ namespace AutoTestMate.MsTest.Web.Core { - public class LinuxOsProcess : IProcess + public class LinuxOsProcess(ILoggingUtility loggingUtility) : IProcess { public const string UnixPidRegex = @"\w+\s+(\d+).*"; - private readonly ILoggingUtility _loggingUtility; - - public LinuxOsProcess(ILoggingUtility loggingUtility) - { - _loggingUtility = loggingUtility; - } - public IEnumerable GetProcessesByName(string name) { name = Path.GetFileNameWithoutExtension(name); @@ -47,7 +40,7 @@ public void Kill(int id) } catch (System.Exception exp) { - _loggingUtility.Error("Error while killing child processes " + exp.Message); + loggingUtility.Error("Error while killing child processes " + exp.Message); } return; @@ -89,7 +82,7 @@ private List FilterProcessListBy(List processList, string filter { if (processList == null) { - return new List(); + return []; } return filter == null ? processList : processList.FindAll(i => i != null && i.ToLower().Contains(filter.ToLower())); @@ -104,7 +97,7 @@ public int GetPidFrom(string pidString, string pattern) } catch { - _loggingUtility.Warning($"Cannot convert pid {pidString} to integer during driver cleanup process."); + loggingUtility.Warning($"Cannot convert pid {pidString} to integer during driver cleanup process."); return 0; } } diff --git a/AutoTestMate.MsTest.Web/Core/MethodManager/IWebDriverService.cs b/AutoTestMate.MsTest.Web/Core/MethodManager/IWebDriverService.cs index 8ba32c1..015a0ee 100644 --- a/AutoTestMate.MsTest.Web/Core/MethodManager/IWebDriverService.cs +++ b/AutoTestMate.MsTest.Web/Core/MethodManager/IWebDriverService.cs @@ -1,6 +1,4 @@ -using System.Collections.Concurrent; -using AutoTestMate.MsTest.Infrastructure.Core; -using AutoTestMate.MsTest.Infrastructure.Core.MethodManager; +using AutoTestMate.MsTest.Infrastructure.Core; using OpenQA.Selenium; using OpenQA.Selenium.Support.UI; diff --git a/AutoTestMate.MsTest.Web/Core/MethodManager/IWebTestMethod.cs b/AutoTestMate.MsTest.Web/Core/MethodManager/IWebTestMethod.cs index b7be7f4..34df8c7 100644 --- a/AutoTestMate.MsTest.Web/Core/MethodManager/IWebTestMethod.cs +++ b/AutoTestMate.MsTest.Web/Core/MethodManager/IWebTestMethod.cs @@ -6,8 +6,10 @@ namespace AutoTestMate.MsTest.Web.Core.MethodManager { public interface IWebTestMethod { + IWebDriverService WebDriverService { get; set; } IWebDriver WebDriver { get; set; } WebDriverWait WebDriverWait { get; set; } IFactory DriverCleanup { get; set; } + void StartWebDriver(); } } \ No newline at end of file diff --git a/AutoTestMate.MsTest.Web/Core/MethodManager/WebDriverService.cs b/AutoTestMate.MsTest.Web/Core/MethodManager/WebDriverService.cs index 19388fe..a28113d 100644 --- a/AutoTestMate.MsTest.Web/Core/MethodManager/WebDriverService.cs +++ b/AutoTestMate.MsTest.Web/Core/MethodManager/WebDriverService.cs @@ -1,29 +1,21 @@ using System; -using System.Collections.Concurrent; using AutoTestMate.MsTest.Infrastructure.Core; -using AutoTestMate.MsTest.Infrastructure.Core.MethodManager; -using NLog.Config; using OpenQA.Selenium; using OpenQA.Selenium.Support.UI; namespace AutoTestMate.MsTest.Web.Core.MethodManager { - public class WebDriverService : IWebDriverService + public class WebDriverService( + ILoggingUtility loggingUtility, + IFactory driverCleanup, + IFactory webDriverFactory, + IConfigurationReader configurationReader) + : IWebDriverService { - public WebDriverService(ILoggingUtility loggingUtility, IFactory driverCleanup, IFactory webDriverFactory, IConfigurationReader configurationReader) - { - DriverCleanup = driverCleanup; - WebDriverFactory = webDriverFactory; - ConfigurationReader = configurationReader; - LoggingUtility = loggingUtility; - } - - public IFactory DriverCleanup { get; set; } - public IConfigurationReader ConfigurationReader { get; set; } - public IFactory WebDriverFactory { get; set; } - public ILoggingUtility LoggingUtility { get; set; } - - + public IFactory DriverCleanup { get; set; } = driverCleanup; + public IConfigurationReader ConfigurationReader { get; set; } = configurationReader; + public IFactory WebDriverFactory { get; set; } = webDriverFactory; + public ILoggingUtility LoggingUtility { get; set; } = loggingUtility; public (IWebDriver, WebDriverWait) StartWebDriver(string testMethod) { var driverCleanup = DriverCleanup.Create(); diff --git a/AutoTestMate.MsTest.Web/Core/MethodManager/WebTestMethod.cs b/AutoTestMate.MsTest.Web/Core/MethodManager/WebTestMethod.cs index bfe38a7..2ee16b8 100644 --- a/AutoTestMate.MsTest.Web/Core/MethodManager/WebTestMethod.cs +++ b/AutoTestMate.MsTest.Web/Core/MethodManager/WebTestMethod.cs @@ -1,9 +1,6 @@ -using System; -using System.Collections.Generic; -using System.Text; -using AutoTestMate.MsTest.Infrastructure.Core; +using AutoTestMate.MsTest.Infrastructure.Core; using AutoTestMate.MsTest.Infrastructure.Core.MethodManager; -using DocumentFormat.OpenXml.Presentation; +using Castle.Facilities.Startable; using OpenQA.Selenium; using OpenQA.Selenium.Support.UI; @@ -11,28 +8,44 @@ namespace AutoTestMate.MsTest.Web.Core.MethodManager { public class WebTestMethod : TestMethodBase, IWebTestMethod { - public WebTestMethod (IFactory driverCleanup, ILoggingUtility loggingUtility, IConfigurationReader configurationReader, string testMethod) : base(loggingUtility, configurationReader, testMethod) + public WebTestMethod(IFactory driverCleanup, + ILoggingUtility loggingUtility, + IConfigurationReader configurationReader, + IWebDriverService webDriverService, + string testMethod) : base(loggingUtility, configurationReader, testMethod) { + WebDriverService = webDriverService; DriverCleanup = driverCleanup; + StartWebDriver(); } public IWebDriver WebDriver { get; set; } + public IWebDriverService WebDriverService { get; set; } public WebDriverWait WebDriverWait { get; set; } public IFactory DriverCleanup { get; set; } + public void StartWebDriver() + { + if (WebDriverService != null) + { + var browser = WebDriverService.StartWebDriver(TestMethod); + + WebDriver = browser.Item1; + WebDriverWait = browser.Item2; + } + } + public override void Dispose() { try { var testWebDriverExists = WebDriver != null; - if (testWebDriverExists) { WebDriver?.Quit(); } WebDriverWait = null; - } catch (System.Exception exp) { @@ -48,8 +61,6 @@ public override void Dispose() IsInitialised = false; } - - } } } diff --git a/AutoTestMate.MsTest.Web/Core/MethodManager/WebTestMethodManager.cs b/AutoTestMate.MsTest.Web/Core/MethodManager/WebTestMethodManager.cs index 2d56368..ffeb317 100644 --- a/AutoTestMate.MsTest.Web/Core/MethodManager/WebTestMethodManager.cs +++ b/AutoTestMate.MsTest.Web/Core/MethodManager/WebTestMethodManager.cs @@ -22,15 +22,10 @@ public override ITestMethodBase Add(string testMethod) IConfigurationReader configurationReader = new ConfigurationReader(TestContext, AppConfiguration); - var webTestMethod = new WebTestMethod(DriverCleanup, LoggingUtility, configurationReader, testMethod); - - var browser = WebDriverService.StartWebDriver(testMethod); - - webTestMethod.WebDriver = browser.Item1; - webTestMethod.WebDriverWait = browser.Item2; - + var webTestMethod = new WebTestMethod(DriverCleanup, LoggingUtility, configurationReader, WebDriverService, testMethod); + TestMethods.AddOrUpdate(testMethod, webTestMethod, (key, oldValue) => webTestMethod); - + return webTestMethod; } diff --git a/AutoTestMate.MsTest.Web/Core/ProcessUtils.cs b/AutoTestMate.MsTest.Web/Core/ProcessUtils.cs index b6731a0..a7a07c4 100644 --- a/AutoTestMate.MsTest.Web/Core/ProcessUtils.cs +++ b/AutoTestMate.MsTest.Web/Core/ProcessUtils.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Text.RegularExpressions; namespace AutoTestMate.MsTest.Web.Core @@ -28,73 +29,53 @@ public static void Main(string[] args) public static void findAndKillProcessRuningOn(string port) { - List pidList = new List(); - List list = new List(); - switch (getOSName()) + var pidList = new List(); + List list; + switch (GetOsName()) { case Platform.UNIX: - list = findUnixProcess(); - list = filterProcessListBy(processList: list, filter: ":" + port); - - foreach (string pidString in list) - { - string pid = getPidFrom(pidString: pidString, pattern: UNIX_PID_REGX); - - if (!String.IsNullOrEmpty(pid)) - { - pidList.Add(pid); - } - } + list = FindUnixProcess(); + list = FilterProcessListBy(processList: list, filter: ":" + port); + pidList.AddRange(list.Select(pidString => GetPidFrom(pidString: pidString, pattern: UNIX_PID_REGX)).Where(pid => !string.IsNullOrEmpty(pid))); break; case Platform.WIN: - list = findWindowsProcess(); - list = filterProcessListBy(processList: list, filter: ":" + port); - - foreach (string pidString in list) - { - string pid = getPidFrom(pidString: pidString, pattern: WIND_PID_REGX); - - if (!String.IsNullOrEmpty(pid)) - { - pidList.Add(pid); - } - } + list = FindWindowsProcess(); + list = FilterProcessListBy(processList: list, filter: ":" + port); + pidList.AddRange(list.Select(pidString => GetPidFrom(pidString: pidString, pattern: WIND_PID_REGX)).Where(pid => !string.IsNullOrEmpty(pid))); break; default: Console.WriteLine("No match found"); break; } - foreach (string pid in pidList) + foreach (var pid in pidList) { - killProcesBy(pidString: pid); + KillProcessBy(pidString: pid); } } - public static Platform getOSName() + public static Platform GetOsName() { - string os = System.Environment.OSVersion.VersionString; + var os = System.Environment.OSVersion.VersionString; Console.WriteLine("OS = {0}", os); - if (os != null && os.ToLower().Contains("unix")) + if (os.ToLower().Contains("unix", StringComparison.CurrentCultureIgnoreCase)) { - Console.WriteLine("UNXI machine"); + Console.WriteLine("UNIX machine"); return Platform.UNIX; } - else - { - Console.WriteLine("Windows machine"); - return Platform.WIN; - } + + Console.WriteLine("WINDOWS machine"); + return Platform.WIN; } - public static void killProcesBy(string pidString) + public static void KillProcessBy(string pidString) { - int pid = -1; + var pid = -1; if (pidString != null && int.TryParse(s: pidString, result: out pid)) { - Process p = Process.GetProcessById(pid); + var p = Process.GetProcessById(pid); p.Kill(); Console.WriteLine("Killed pid =" + pidString); } @@ -105,84 +86,80 @@ public static void killProcesBy(string pidString) } - public static List findUnixProcess() + public static List FindUnixProcess() { - ProcessStartInfo processStart = new ProcessStartInfo(); - processStart.FileName = "bash"; - processStart.Arguments = "-c lsof -i"; - - processStart.RedirectStandardOutput = true; - processStart.UseShellExecute = false; - processStart.CreateNoWindow = true; - - Process process = new Process(); + var processStart = new ProcessStartInfo + { + FileName = "bash", + Arguments = "-c lsof -i", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + var process = new Process(); process.StartInfo = processStart; process.Start(); - String outstr = process.StandardOutput.ReadToEnd(); + var outstr = process.StandardOutput.ReadToEnd(); - return splitByLineBreak(outstr); + return SplitByLineBreak(outstr); } - public static List findWindowsProcess() + public static List FindWindowsProcess() { - ProcessStartInfo processStart = new ProcessStartInfo(); - processStart.FileName = "netstat.exe"; - processStart.Arguments = "-aon"; - - processStart.RedirectStandardOutput = true; - processStart.UseShellExecute = false; - processStart.CreateNoWindow = true; - - Process process = new Process(); + var processStart = new ProcessStartInfo + { + FileName = "netstat.exe", + Arguments = "-aon", + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true + }; + + var process = new Process(); process.StartInfo = processStart; process.Start(); - String outstr = process.StandardOutput.ReadToEnd(); + var outstr = process.StandardOutput.ReadToEnd(); - return splitByLineBreak(outstr); + return SplitByLineBreak(outstr); } - public static List splitByLineBreak(string processLines) + public static List SplitByLineBreak(string processLines) { - List processList = new List(); + var processList = new List(); if (processLines != null) { - string[] list = processLines.Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries); + var list = processLines.Split([Environment.NewLine], StringSplitOptions.RemoveEmptyEntries); processList.AddRange(collection: list); } return processList; } - public static List filterProcessListBy(List processList, - String filter) + public static List FilterProcessListBy(List processList, + string filter) { - if (processList == null) { - return new List(); - } - - if (filter == null) - { - return processList; + return []; } - return processList.FindAll(i => i != null && i.ToLower().Contains(filter.ToLower())); + return filter == null ? processList : processList.FindAll(i => i != null && i.ToLower().Contains(filter.ToLower())); } - public static String getPidFrom(String pidString, String pattern) + public static String GetPidFrom(String pidString, String pattern) { - MatchCollection matches = Regex.Matches(pidString, pattern); + var matches = Regex.Matches(pidString, pattern); if (matches != null && matches.Count > 0) { return matches[0].Groups[1].Value; } - return ""; + return string.Empty; } } } diff --git a/AutoTestMate.MsTest.Web/Core/SeleniumGridDriverCleanup.cs b/AutoTestMate.MsTest.Web/Core/SeleniumGridDriverCleanup.cs index 6f41ba1..32ffa8a 100644 --- a/AutoTestMate.MsTest.Web/Core/SeleniumGridDriverCleanup.cs +++ b/AutoTestMate.MsTest.Web/Core/SeleniumGridDriverCleanup.cs @@ -1,39 +1,25 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using AutoTestMate.MsTest.Infrastructure.Core; +using AutoTestMate.MsTest.Infrastructure.Core; namespace AutoTestMate.MsTest.Web.Core { - public class SeleniumGridDriverCleanupFactory : IFactory + public class SeleniumGridDriverCleanupFactory( + IConfigurationReader configurationReader, +#pragma warning disable CS9113 // Parameter is unread. + ILoggingUtility loggingUtility, +#pragma warning restore CS9113 // Parameter is unread. + IProcess osProcess) + : IFactory { - private readonly IConfigurationReader _configurationReader; - private readonly ILoggingUtility _loggingUtility; - private readonly IProcess _osProcess; - public SeleniumGridDriverCleanupFactory(IConfigurationReader configurationReader, ILoggingUtility loggingUtility, IProcess osProcess) - { - _configurationReader = configurationReader; - _loggingUtility = loggingUtility; - _osProcess = osProcess; - } - public virtual IDriverCleanup Create() { - return new SeleniumGridDriverCleanup(_osProcess, _configurationReader); + return new SeleniumGridDriverCleanup(osProcess, configurationReader); } } - public class SeleniumGridDriverCleanup : IDriverCleanup +#pragma warning disable CS9113 // Parameter is unread. + public class SeleniumGridDriverCleanup(IProcess process, IConfigurationReader configurationReader) : IDriverCleanup +#pragma warning restore CS9113 // Parameter is unread. { - public const int MaxKillAttemps = 100; - private readonly IConfigurationReader _configurationReader; - - public SeleniumGridDriverCleanup(IProcess process, IConfigurationReader configurationReader) - { - _configurationReader = configurationReader; - Process = process; - } - public void Dispose() { } @@ -42,7 +28,6 @@ public void Initialise() { } - public IProcess Process { get; } - + public IProcess Process { get; } = process; } } \ No newline at end of file diff --git a/AutoTestMate.MsTest.Web/Core/WebTestBase.cs b/AutoTestMate.MsTest.Web/Core/WebTestBase.cs index a74a03b..1fefa37 100644 --- a/AutoTestMate.MsTest.Web/Core/WebTestBase.cs +++ b/AutoTestMate.MsTest.Web/Core/WebTestBase.cs @@ -15,7 +15,7 @@ public abstract class WebTestBase : ServiceTestBase public override void OnTestInitialise() { var testMethod = TestMethod; - TestManager = WebTestManager.Instance(); + TestManager = WebTestManager.Instance; try { @@ -44,10 +44,10 @@ public override void OnTestInitialise() } [TestCleanup] - public override void OnTestCleanup() + public override void OnTestCleanUp() { var testMethod = TestMethod; - TestManager = WebTestManager.Instance(); + TestManager = WebTestManager.Instance; WebTestMethodManager.TestMethods.TryGetValue(testMethod, out ITestMethodBase testMethodBase); var webTestMethod = (WebTestMethod)testMethodBase; diff --git a/AutoTestMate.MsTest.Web/Core/WebTestManager.cs b/AutoTestMate.MsTest.Web/Core/WebTestManager.cs index 25c537f..ab26db9 100644 --- a/AutoTestMate.MsTest.Web/Core/WebTestManager.cs +++ b/AutoTestMate.MsTest.Web/Core/WebTestManager.cs @@ -2,7 +2,6 @@ using System.Diagnostics.CodeAnalysis; using AutoTestMate.MsTest.Infrastructure.Core; using AutoTestMate.MsTest.Infrastructure.Core.MethodManager; -using AutoTestMate.MsTest.Infrastructure.Helpers; using AutoTestMate.MsTest.Services.Core; using AutoTestMate.MsTest.Web.Constants; using AutoTestMate.MsTest.Web.Core.Attributes; @@ -17,36 +16,10 @@ namespace AutoTestMate.MsTest.Web.Core [SuppressMessage("ReSharper", "UnusedMember.Global")] public class WebTestManager : ServiceTestManager { - #region Private Variables - - private static WebTestManager _uniqueInstance; - private static readonly object SyncLock = new Object(); - - #endregion - - #region Properties - - public new static WebTestManager Instance() - { - // Lock entire body of method - lock (SyncLock) - { - // ReSharper disable once ConvertIfStatementToNullCoalescingExpression - if (_uniqueInstance == null) - { - _uniqueInstance = new WebTestManager(); - } - return _uniqueInstance; - } - } - - public static bool IsManagerNull() - { - lock (SyncLock) - { - return _uniqueInstance == null; - } - } + private static readonly Lazy Singleton = new(() => new WebTestManager()); + public new static WebTestManager Instance => Singleton.Value; + + private WebTestManager() { } public WebTestMethodManager WebTestMethodManager => (WebTestMethodManager)Container.Resolve(); @@ -61,15 +34,10 @@ public bool IsDriverNull(string testMethod) return webTestMethod.WebDriver == null; } - #endregion - - #region Constructor - - private WebTestManager() { } - - #endregion - - #region Public Methods + public static bool IsManagerNull() + { + return Singleton == null; + } public override void OnInitialiseAssemblyDependencies(TestContext testContext = null) { @@ -123,7 +91,6 @@ public override void OnTestMethodInitialise(string testMethod, TestContext testC throw; } } - public override void Dispose(string testMethod) { try @@ -142,8 +109,6 @@ public override void Dispose(string testMethod) { LoggingUtility.Error(e.Message); } - } - - #endregion - } + } + } } diff --git a/AutoTestMate.MsTest.Web/Core/WinOsProcess.cs b/AutoTestMate.MsTest.Web/Core/WinOsProcess.cs index e9fe7d3..fd21f5f 100644 --- a/AutoTestMate.MsTest.Web/Core/WinOsProcess.cs +++ b/AutoTestMate.MsTest.Web/Core/WinOsProcess.cs @@ -1,21 +1,15 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Management; using AutoTestMate.MsTest.Infrastructure.Core; namespace AutoTestMate.MsTest.Web.Core { - public class WinOsProcess : IProcess + public class WinOsProcess(ILoggingUtility utility) : IProcess { - private readonly ILoggingUtility _loggingUtility; - - public WinOsProcess(ILoggingUtility loggingUtility) - { - _loggingUtility = loggingUtility; - } - public IEnumerable GetProcessesByName(string name) { return Process.GetProcessesByName(name).Select(p => p.Id); @@ -42,7 +36,7 @@ public void Kill(int id) } catch (System.Exception exp) { - var loggingUtility = _loggingUtility; + var loggingUtility = utility ?? throw new ArgumentNullException(nameof(utility)); loggingUtility.Error("Error while killing process " + exp.Message); } @@ -57,6 +51,8 @@ private void KillAllChildProcesses(int id) } } + //Message suppressed due to class only for windows + [SuppressMessage("Interoperability", "CA1416:Validate platform compatibility")] public List GetChildProcesses(int parentId) { var result = new List(); diff --git a/AutoTestMate.MsTest.Web/Extensions/WebElementExtensions.cs b/AutoTestMate.MsTest.Web/Extensions/WebElementExtensions.cs index 10888f2..aaf9c7b 100644 --- a/AutoTestMate.MsTest.Web/Extensions/WebElementExtensions.cs +++ b/AutoTestMate.MsTest.Web/Extensions/WebElementExtensions.cs @@ -195,7 +195,7 @@ public static bool VisibleWait(this IWebElement elm, uint timeOut = 10, uint pol } catch (System.Exception exp) { - var loggingUtility = WebTestManager.Instance().LoggingUtility; + var loggingUtility = WebTestManager.Instance.LoggingUtility; loggingUtility.Warning(exp.Message + exp.StackTrace); return false; } diff --git a/Test.runsettings b/Test.runsettings index 46e3c0a..9780b98 100644 --- a/Test.runsettings +++ b/Test.runsettings @@ -4,24 +4,21 @@ - /home/jopo/Development/TestResults/ + /home/sporty-turks/development/proDev/TestResults/ x64 - - - Framework45 - true - 6 + false + 4 - + - - + + @@ -31,7 +28,7 @@ - + From bffdcb1095b50a3690f0edfb54361574a2f037dc Mon Sep 17 00:00:00 2001 From: sporty-turks Date: Sat, 15 Jun 2024 09:14:23 +1000 Subject: [PATCH 2/4] Add database files --- .../Data/DataAccessBase.cs | 11 +++++++++++ .../Data/IDataAccessBase.cs | 10 ++++++++++ 2 files changed, 21 insertions(+) create mode 100644 AutoTestMate.MsTest.Infrastructure/Data/DataAccessBase.cs create mode 100644 AutoTestMate.MsTest.Infrastructure/Data/IDataAccessBase.cs diff --git a/AutoTestMate.MsTest.Infrastructure/Data/DataAccessBase.cs b/AutoTestMate.MsTest.Infrastructure/Data/DataAccessBase.cs new file mode 100644 index 0000000..1d91b28 --- /dev/null +++ b/AutoTestMate.MsTest.Infrastructure/Data/DataAccessBase.cs @@ -0,0 +1,11 @@ +using AutoTestMate.MsTest.Infrastructure.Core; + +namespace AutoTestMate.MsTest.Infrastructure.Data +{ + public class DataAccessBase(IConfigurationReader configReader, ILoggingUtility loggingUtility) : IDataAccessBase + { + public IConfigurationReader ConfigurationReader { get; } = configReader; + public ILoggingUtility LoggingUtility { get; } = loggingUtility; + public string ConnectionString => ConfigurationReader.GetConfigurationValue("AutomatedTestingDatabaseConnectionString"); + } +} \ No newline at end of file diff --git a/AutoTestMate.MsTest.Infrastructure/Data/IDataAccessBase.cs b/AutoTestMate.MsTest.Infrastructure/Data/IDataAccessBase.cs new file mode 100644 index 0000000..9bda47e --- /dev/null +++ b/AutoTestMate.MsTest.Infrastructure/Data/IDataAccessBase.cs @@ -0,0 +1,10 @@ +using AutoTestMate.MsTest.Infrastructure.Core; + +namespace AutoTestMate.MsTest.Infrastructure.Data; + +public interface IDataAccessBase +{ + IConfigurationReader ConfigurationReader { get; } + ILoggingUtility LoggingUtility { get; } + string ConnectionString { get; } +} \ No newline at end of file From 991884e3b784d5300f3d0ba9c65dccea933ba437 Mon Sep 17 00:00:00 2001 From: sporty-turks Date: Mon, 17 Jun 2024 10:55:22 +1000 Subject: [PATCH 3/4] screenshots and results directory refactor, upgraded mstest framework version --- ...est.Infrastructure.IntegrationTests.csproj | 6 +- .../ConfigurationReaderTests.cs | 1 + .../LoggingUtilityTests.cs | 20 +++++- ...ate.MsTest.Infrastructure.UnitTests.csproj | 6 +- .../AutoTestMate.MsTest.Infrastructure.csproj | 4 +- .../Core/LoggingUtility.cs | 15 +++-- .../AutoTestMate.MsTest.Services.csproj | 2 +- .../AutoTestMate.MsTest.Web.csproj | 2 +- AutoTestMate.MsTest.Web/Core/WebTestBase.cs | 66 +++++++++++++------ Test.runsettings | 17 ++--- 10 files changed, 91 insertions(+), 48 deletions(-) diff --git a/AutoTestMate.MsTest.Infrastructure.IntegrationTests/AutoTestMate.MsTest.Infrastructure.IntegrationTests.csproj b/AutoTestMate.MsTest.Infrastructure.IntegrationTests/AutoTestMate.MsTest.Infrastructure.IntegrationTests.csproj index 435d13f..3436f92 100644 --- a/AutoTestMate.MsTest.Infrastructure.IntegrationTests/AutoTestMate.MsTest.Infrastructure.IntegrationTests.csproj +++ b/AutoTestMate.MsTest.Infrastructure.IntegrationTests/AutoTestMate.MsTest.Infrastructure.IntegrationTests.csproj @@ -27,9 +27,9 @@ - - - + + + diff --git a/AutoTestMate.MsTest.Infrastructure.IntegrationTests/ConfigurationReaderTests.cs b/AutoTestMate.MsTest.Infrastructure.IntegrationTests/ConfigurationReaderTests.cs index 932802a..7754c58 100644 --- a/AutoTestMate.MsTest.Infrastructure.IntegrationTests/ConfigurationReaderTests.cs +++ b/AutoTestMate.MsTest.Infrastructure.IntegrationTests/ConfigurationReaderTests.cs @@ -16,6 +16,7 @@ public void GetAppConfigConfigurationValues() Assert.IsTrue(configurationReader.GetConfigurationValue("ForceKillProcess") == "false"); Assert.IsTrue(configurationReader.GetConfigurationValue("Headless") == "false"); Assert.IsTrue(configurationReader.GetConfigurationValue("BrowserOs").ToLower() == "linux"); + } [TestMethod] diff --git a/AutoTestMate.MsTest.Infrastructure.IntegrationTests/LoggingUtilityTests.cs b/AutoTestMate.MsTest.Infrastructure.IntegrationTests/LoggingUtilityTests.cs index f136c95..9a1307c 100644 --- a/AutoTestMate.MsTest.Infrastructure.IntegrationTests/LoggingUtilityTests.cs +++ b/AutoTestMate.MsTest.Infrastructure.IntegrationTests/LoggingUtilityTests.cs @@ -1,13 +1,29 @@ +using System; +using AutoTestMate.MsTest.Infrastructure.Core.MethodManager; +using AutoTestMate.MsTest.Web.Core; +using AutoTestMate.MsTest.Web.Core.MethodManager; +using AutoTestMate.MsTest.Web.Extensions; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace AutoTestMate.MsTest.Infrastructure.IntegrationTests { [TestClass] - public class LoggingUtilityTests + public class LoggingUtilityTests: WebTestBase { [TestMethod] - public void TestMethod1() + public void EnsureLoggingFileCreated() { + LoggingUtility.Info("This is an info message"); + LoggingUtility.Error("This is an info message"); } + [TestMethod] + public void EnsureScreenshotCreated() + { + LoggingUtility.Info("This is an info message"); + LoggingUtility.Error("This is an info message"); + + CaptureScreenshot(); + } + } } \ No newline at end of file diff --git a/AutoTestMate.MsTest.Infrastructure.UnitTests/AutoTestMate.MsTest.Infrastructure.UnitTests.csproj b/AutoTestMate.MsTest.Infrastructure.UnitTests/AutoTestMate.MsTest.Infrastructure.UnitTests.csproj index fed7637..c18e062 100644 --- a/AutoTestMate.MsTest.Infrastructure.UnitTests/AutoTestMate.MsTest.Infrastructure.UnitTests.csproj +++ b/AutoTestMate.MsTest.Infrastructure.UnitTests/AutoTestMate.MsTest.Infrastructure.UnitTests.csproj @@ -7,9 +7,9 @@ - - - + + + diff --git a/AutoTestMate.MsTest.Infrastructure/AutoTestMate.MsTest.Infrastructure.csproj b/AutoTestMate.MsTest.Infrastructure/AutoTestMate.MsTest.Infrastructure.csproj index e504e64..aeceeea 100644 --- a/AutoTestMate.MsTest.Infrastructure/AutoTestMate.MsTest.Infrastructure.csproj +++ b/AutoTestMate.MsTest.Infrastructure/AutoTestMate.MsTest.Infrastructure.csproj @@ -49,8 +49,8 @@ - - + + diff --git a/AutoTestMate.MsTest.Infrastructure/Core/LoggingUtility.cs b/AutoTestMate.MsTest.Infrastructure/Core/LoggingUtility.cs index 8c165f0..35aa1d2 100644 --- a/AutoTestMate.MsTest.Infrastructure/Core/LoggingUtility.cs +++ b/AutoTestMate.MsTest.Infrastructure/Core/LoggingUtility.cs @@ -38,8 +38,15 @@ private void SetupLogger() var outputDirectory = _configurationReader.GetConfigurationValue(Constants.Configuration.OutputFileDirectory); string outputFile; - - if (!string.IsNullOrWhiteSpace(outputDirectory) && outputDirectory.Contains("/")) //handle relative paths + + if (!string.IsNullOrWhiteSpace(outputDirectory) && outputDirectory.Contains("~")) //handle relative paths + { + var homeDirRoot = Environment.GetEnvironmentVariable("HOME") + "/"; + var outputDir = outputDirectory.Trim('~'); + var homeDir = Path.GetDirectoryName(homeDirRoot) + outputDir; + outputFile = $"{homeDir}/{_defaultFileName}"; + } + else if (!string.IsNullOrWhiteSpace(outputDirectory) && outputDirectory.Contains("/")) //handle relative paths { outputFile = $"{outputDirectory}/{_defaultFileName}"; } @@ -105,8 +112,8 @@ public void Debug(string message, bool logTestContext = false) } private void TestContextWriteLine(string message, bool logTestContext) - { - if (logTestContext) + { + if (logTestContext) { _testContext.WriteLine(message); } diff --git a/AutoTestMate.MsTest.Services/AutoTestMate.MsTest.Services.csproj b/AutoTestMate.MsTest.Services/AutoTestMate.MsTest.Services.csproj index fdfc3a2..006ada6 100644 --- a/AutoTestMate.MsTest.Services/AutoTestMate.MsTest.Services.csproj +++ b/AutoTestMate.MsTest.Services/AutoTestMate.MsTest.Services.csproj @@ -18,7 +18,7 @@ - + diff --git a/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj b/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj index e71e4e1..00c9433 100644 --- a/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj +++ b/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj @@ -35,7 +35,7 @@ - + diff --git a/AutoTestMate.MsTest.Web/Core/WebTestBase.cs b/AutoTestMate.MsTest.Web/Core/WebTestBase.cs index 1fefa37..de14d27 100644 --- a/AutoTestMate.MsTest.Web/Core/WebTestBase.cs +++ b/AutoTestMate.MsTest.Web/Core/WebTestBase.cs @@ -1,4 +1,5 @@ -using System.Net.Http; +using System; +using System.Net.Http; using System.Runtime.CompilerServices; using AutoTestMate.MsTest.Infrastructure.Core.MethodManager; using AutoTestMate.MsTest.Services.Core; @@ -29,15 +30,12 @@ public override void OnTestInitialise() LoggingUtility.Error(Constants.Exceptions.ExceptionMsgSetupError + ex.Message); WebTestMethodManager.TestMethods.TryGetValue(testMethod, out ITestMethodBase testMethodBase); + var webTestMethod = (WebTestMethod)testMethodBase; if (webTestMethod?.WebDriver == null) throw; - - var outputScreenshotsDirectory = TestManager.ConfigurationReader.GetConfigurationValue("OutputScreenshotsDirectory"); - - var outputPath = !string.IsNullOrWhiteSpace(outputScreenshotsDirectory) ? outputScreenshotsDirectory : $"{TestContext.TestRunResultsDirectory}\\Screenshots"; - webTestMethod.WebDriver.ScreenShotSaveFile(outputPath, testMethod); + CaptureScreenshot(testMethod); throw; } @@ -48,9 +46,7 @@ public override void OnTestCleanUp() { var testMethod = TestMethod; TestManager = WebTestManager.Instance; - WebTestMethodManager.TestMethods.TryGetValue(testMethod, out ITestMethodBase testMethodBase); - var webTestMethod = (WebTestMethod)testMethodBase; - + try { CustomAttributesCleanup(testMethod); @@ -61,19 +57,9 @@ public override void OnTestCleanUp() if (LoggingUtility == null || TestManager.ConfigurationReader == null) return; - var outputPath = !string.IsNullOrWhiteSpace(TestManager.ConfigurationReader.GetConfigurationValue(Constants.Configuration.ConfigKeyOutputFileScreenshotsDirectory)) ? $"{TestManager.ConfigurationReader.GetConfigurationValue(Constants.Configuration.ConfigKeyOutputFileScreenshotsDirectory)}" : $"{TestContext.TestRunResultsDirectory}{Constants.Configuration.ScreenshotsDirectory}"; - - if (webTestMethod?.WebDriver == null) return; - - TestContext.WriteLine($"Attempting to capture screen shot to: {outputPath}"); - - var captureScreenShot = webTestMethod.WebDriver.ScreenShotSaveFile(outputPath, testMethod); - - if (string.IsNullOrWhiteSpace(captureScreenShot)) return; - - TestContext.AddResultFile(captureScreenShot); + var screenshotPath = CaptureScreenshot(testMethod); - LoggingUtility.Error(captureScreenShot); + LoggingUtility.Error(screenshotPath); } else { @@ -99,6 +85,44 @@ public virtual T GetPage([CallerMemberName] string testName = null) { return TestManager.Container.Resolve(new Arguments { { "testName", testName } }); } + + public virtual string CaptureScreenshot([CallerMemberName] string testMethod = null) + { + var screenshot = string.Empty; + TestManager = WebTestManager.Instance; + + if (string.IsNullOrWhiteSpace(testMethod)) return screenshot; + + WebTestMethodManager.TestMethods.TryGetValue(testMethod, out ITestMethodBase testMethodBase); + var webTestMethod = (WebTestMethod)testMethodBase; + + var outputPath = + !string.IsNullOrWhiteSpace( + TestManager.ConfigurationReader.GetConfigurationValue(Constants.Configuration + .ConfigKeyOutputFileScreenshotsDirectory)) + ? $"{TestManager.ConfigurationReader.GetConfigurationValue(Constants.Configuration.ConfigKeyOutputFileScreenshotsDirectory)}" + : $"{TestContext.TestRunResultsDirectory}{Constants.Configuration.ScreenshotsDirectory}"; + + if (!string.IsNullOrWhiteSpace(outputPath) && outputPath.Contains("~")) //handle home relative paths + { + var homeDirRoot = Environment.GetEnvironmentVariable("HOME") + "/"; + var outputDir = outputPath.Trim('~').Replace("\\", "/"); + var homeDir = homeDirRoot + outputDir; + outputPath = homeDir; + } + + if (webTestMethod?.WebDriver == null) return screenshot; + + TestContext.WriteLine($"Attempting to capture screen shot to: {outputPath}"); + + screenshot = webTestMethod.WebDriver.ScreenShotSaveFile(outputPath, testMethod); + + if (string.IsNullOrWhiteSpace(screenshot)) return string.Empty; + + TestContext.AddResultFile(screenshot); + + return screenshot; + } } } diff --git a/Test.runsettings b/Test.runsettings index 9780b98..fc4a519 100644 --- a/Test.runsettings +++ b/Test.runsettings @@ -1,24 +1,22 @@  - - - /home/sporty-turks/development/proDev/TestResults/ + + /home/sporty-turks/.local/share/autotestmate/logs/test-results/ x64 false 4 - - + - - + + @@ -28,12 +26,9 @@ - + - - - 3 From e80ba75359d13f1afbd0360551a5d1bd05d5251d Mon Sep 17 00:00:00 2001 From: sporty-turks Date: Mon, 17 Jun 2024 21:02:19 +1000 Subject: [PATCH 4/4] add git repo url --- .../AutoTestMate.MsTest.Infrastructure.csproj | 4 ++++ .../AutoTestMate.MsTest.Services.csproj | 4 ++++ AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/AutoTestMate.MsTest.Infrastructure/AutoTestMate.MsTest.Infrastructure.csproj b/AutoTestMate.MsTest.Infrastructure/AutoTestMate.MsTest.Infrastructure.csproj index aeceeea..2ab5f16 100644 --- a/AutoTestMate.MsTest.Infrastructure/AutoTestMate.MsTest.Infrastructure.csproj +++ b/AutoTestMate.MsTest.Infrastructure/AutoTestMate.MsTest.Infrastructure.csproj @@ -17,6 +17,10 @@ false + + https://github.com/sportyturks/AutoTestMate.MsTest + + diff --git a/AutoTestMate.MsTest.Services/AutoTestMate.MsTest.Services.csproj b/AutoTestMate.MsTest.Services/AutoTestMate.MsTest.Services.csproj index 006ada6..6a7fbbd 100644 --- a/AutoTestMate.MsTest.Services/AutoTestMate.MsTest.Services.csproj +++ b/AutoTestMate.MsTest.Services/AutoTestMate.MsTest.Services.csproj @@ -17,6 +17,10 @@ false + + https://github.com/sportyturks/AutoTestMate.MsTest + + diff --git a/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj b/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj index 00c9433..cecc151 100644 --- a/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj +++ b/AutoTestMate.MsTest.Web/AutoTestMate.MsTest.Web.csproj @@ -17,6 +17,10 @@ false + + https://github.com/sportyturks/AutoTestMate.MsTest + +