Skip to content

Commit 2e4b09c

Browse files
authored
override default container (#154)
* added possibility to override default container with services added unit tests * set ParallelScope.None for CustomConfigurationTests * fixed parallel run for Custom Configuration * removed cast Startup to BrowserStartup * added dot * removed reduntant empty line * updated registration of BrowserFactory
1 parent 81fe09f commit 2e4b09c

File tree

5 files changed

+138
-46
lines changed

5 files changed

+138
-46
lines changed

Aquality.Selenium/src/Aquality.Selenium/Aquality.Selenium.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
</ItemGroup>
6060

6161
<ItemGroup>
62-
<PackageReference Include="Aquality.Selenium.Core" Version="0.2.2" />
62+
<PackageReference Include="Aquality.Selenium.Core" Version="0.2.5" />
6363
<PackageReference Include="NLog" Version="4.6.6" />
6464
<PackageReference Include="Selenium.Support" Version="3.141.0" />
6565
<PackageReference Include="Selenium.WebDriver" Version="3.141.0" />
Lines changed: 25 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,8 @@
1-
using Aquality.Selenium.Elements;
2-
using Aquality.Selenium.Elements.Interfaces;
3-
using Microsoft.Extensions.DependencyInjection;
1+
using Microsoft.Extensions.DependencyInjection;
42
using System;
53
using System.Threading;
6-
using Aquality.Selenium.Core.Localization;
7-
using Aquality.Selenium.Core.Logging;
8-
using System.Reflection;
94
using Aquality.Selenium.Core.Applications;
105
using Aquality.Selenium.Configurations;
11-
using CoreElementFactory = Aquality.Selenium.Core.Elements.Interfaces.IElementFactory;
12-
using CoreTimeoutConfiguration = Aquality.Selenium.Core.Configurations.ITimeoutConfiguration;
13-
using ILoggerConfiguration = Aquality.Selenium.Core.Configurations.ILoggerConfiguration;
146

157
namespace Aquality.Selenium.Browsers
168
{
@@ -19,6 +11,7 @@ namespace Aquality.Selenium.Browsers
1911
/// </summary>
2012
public class BrowserManager : ApplicationManager<Browser>
2113
{
14+
private static readonly ThreadLocal<BrowserStartup> BrowserStartupContainer = new ThreadLocal<BrowserStartup>(() => new BrowserStartup());
2215
private static readonly ThreadLocal<IBrowserFactory> BrowserFactoryContainer = new ThreadLocal<IBrowserFactory>();
2316

2417
/// <summary>
@@ -27,27 +20,28 @@ public class BrowserManager : ApplicationManager<Browser>
2720
/// <value>Instance of desired browser.</value>
2821
public static Browser Browser
2922
{
30-
get
31-
{
32-
return GetApplication(StartBrowserFunction, () => RegisterServices(services => Browser));
33-
}
34-
set
35-
{
36-
SetApplication(value);
37-
}
23+
get => GetApplication(StartBrowserFunction, ConfigureServices);
24+
set => SetApplication(value);
3825
}
3926

4027
private static Func<IServiceProvider, Browser> StartBrowserFunction => services => BrowserFactory.Browser;
4128

4229
public static IServiceProvider ServiceProvider
4330
{
44-
get
45-
{
46-
return GetServiceProvider(services => Browser, () => RegisterServices(services => Browser));
47-
}
48-
set
31+
get => GetServiceProvider(services => Browser, ConfigureServices);
32+
set => SetServiceProvider(value);
33+
}
34+
35+
/// <summary>
36+
/// Method which allow user to override or add custom services.
37+
/// </summary>
38+
/// <param name="startup"><see cref="BrowserStartup"/>> object with custom or overriden services.</param>
39+
public static void SetStartup(BrowserStartup startup)
40+
{
41+
if (startup != null)
4942
{
50-
SetServiceProvider(value);
43+
BrowserStartupContainer.Value = startup;
44+
SetServiceProvider(ConfigureServices().BuildServiceProvider());
5145
}
5246
}
5347

@@ -62,30 +56,12 @@ public static IBrowserFactory BrowserFactory
6256
{
6357
SetDefaultFactory();
6458
}
59+
6560
return BrowserFactoryContainer.Value;
6661
}
67-
set
68-
{
69-
BrowserFactoryContainer.Value = value;
70-
}
62+
set => BrowserFactoryContainer.Value = value;
7163
}
7264

73-
private static IServiceCollection RegisterServices(Func<IServiceProvider, Browser> browserSupplier)
74-
{
75-
var services = new ServiceCollection();
76-
var startup = new Startup();
77-
var settingsFile = startup.GetSettings();
78-
startup.ConfigureServices(services, browserSupplier, settingsFile);
79-
services.AddTransient<IElementFactory, ElementFactory>();
80-
services.AddTransient<CoreElementFactory, ElementFactory>();
81-
services.AddSingleton<ITimeoutConfiguration>(serviceProvider => new TimeoutConfiguration(settingsFile));
82-
services.AddSingleton<CoreTimeoutConfiguration>(serviceProvider => new TimeoutConfiguration(settingsFile));
83-
services.AddSingleton<IBrowserProfile>(serviceProvider => new BrowserProfile(settingsFile));
84-
services.AddSingleton(serviceProvider => new LocalizationManager(serviceProvider.GetRequiredService<ILoggerConfiguration>(), serviceProvider.GetRequiredService<Logger>(), Assembly.GetExecutingAssembly()));
85-
services.AddTransient(serviceProvider => BrowserFactory);
86-
return services;
87-
}
88-
8965
/// <summary>
9066
/// Sets default factory responsible for browser creation.
9167
/// RemoteBrowserFactory if value set in configuration and LocalBrowserFactory otherwise.
@@ -109,12 +85,17 @@ public static void SetDefaultFactory()
10985
/// <summary>
11086
/// Resolves required service from <see cref="ServiceProvider"/>
11187
/// </summary>
112-
/// <typeparam name="T">type of required service</typeparam>
88+
/// <typeparam name="T">type of required service.</typeparam>
11389
/// <exception cref="InvalidOperationException">Thrown if there is no service of the required type.</exception>
11490
/// <returns></returns>
11591
public static T GetRequiredService<T>()
11692
{
11793
return ServiceProvider.GetRequiredService<T>();
11894
}
95+
96+
private static IServiceCollection ConfigureServices()
97+
{
98+
return BrowserStartupContainer.Value.ConfigureServices(new ServiceCollection(), services => Browser);
99+
}
119100
}
120101
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using Aquality.Selenium.Elements;
2+
using Aquality.Selenium.Elements.Interfaces;
3+
using Microsoft.Extensions.DependencyInjection;
4+
using System;
5+
using Aquality.Selenium.Core.Localization;
6+
using Aquality.Selenium.Core.Logging;
7+
using System.Reflection;
8+
using Aquality.Selenium.Core.Applications;
9+
using Aquality.Selenium.Configurations;
10+
using Aquality.Selenium.Core.Configurations;
11+
using CoreElementFactory = Aquality.Selenium.Core.Elements.Interfaces.IElementFactory;
12+
using CoreTimeoutConfiguration = Aquality.Selenium.Core.Configurations.ITimeoutConfiguration;
13+
using ILoggerConfiguration = Aquality.Selenium.Core.Configurations.ILoggerConfiguration;
14+
using ITimeoutConfiguration = Aquality.Selenium.Configurations.ITimeoutConfiguration;
15+
using TimeoutConfiguration = Aquality.Selenium.Configurations.TimeoutConfiguration;
16+
17+
namespace Aquality.Selenium.Browsers
18+
{
19+
public class BrowserStartup : Startup
20+
{
21+
public override IServiceCollection ConfigureServices(IServiceCollection services, Func<IServiceProvider, IApplication> applicationProvider,
22+
ISettingsFile settings = null)
23+
{
24+
settings = settings ?? GetSettings();
25+
base.ConfigureServices(services, applicationProvider, settings);
26+
services.AddTransient<IElementFactory, ElementFactory>();
27+
services.AddTransient<CoreElementFactory, ElementFactory>();
28+
services.AddSingleton<ITimeoutConfiguration>(serviceProvider => new TimeoutConfiguration(settings));
29+
services.AddSingleton<CoreTimeoutConfiguration>(serviceProvider => new TimeoutConfiguration(settings));
30+
services.AddSingleton<IBrowserProfile>(serviceProvider => new BrowserProfile(settings));
31+
services.AddSingleton(serviceProvider => new LocalizationManager(serviceProvider.GetRequiredService<ILoggerConfiguration>(), serviceProvider.GetRequiredService<Logger>(), Assembly.GetExecutingAssembly()));
32+
services.AddTransient(serviceProvider => BrowserManager.BrowserFactory);
33+
return services;
34+
}
35+
}
36+
}

Aquality.Selenium/tests/Aquality.Selenium.Tests/Integration/UITest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace Aquality.Selenium.Tests.Integration
77
[TestFixture]
88
[Parallelizable(ParallelScope.All)]
99
internal class UITest
10-
{
10+
{
1111
[TearDown]
1212
public void CleanUp()
1313
{
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using System;
2+
using Aquality.Selenium.Browsers;
3+
using Aquality.Selenium.Core.Applications;
4+
using Aquality.Selenium.Core.Configurations;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using NUnit.Framework;
7+
8+
namespace Aquality.Selenium.Tests.Unit.Configuration
9+
{
10+
[TestFixture]
11+
[Parallelizable(ParallelScope.All)]
12+
internal class CustomConfigurationTests
13+
{
14+
private const string SpecialLoggerLanguage = "SpecialLoggerLanguage";
15+
private const string SpecialCustomValue = "SpecialCustomValue";
16+
private static readonly TimeSpan DefaultCommandTimeout = TimeSpan.FromSeconds(60);
17+
18+
[SetUp]
19+
public static void Before()
20+
{
21+
BrowserManager.SetStartup(new CustomStartup());
22+
}
23+
24+
[Test]
25+
public void Should_BeAbleOverrideDependencies_AndGetCustomService()
26+
{
27+
Assert.AreEqual(SpecialLoggerLanguage, BrowserManager.GetRequiredService<ILoggerConfiguration>().Language, "Configuration value should be overriden.");
28+
}
29+
30+
[Test]
31+
public void Should_BeAbleAdd_CustomService()
32+
{
33+
Assert.AreEqual(SpecialCustomValue, BrowserManager.GetRequiredService<ICustomService>().CustomValue, "Custom service should have value");
34+
}
35+
36+
[Test]
37+
public void Should_BeAbleGet_DefaultService()
38+
{
39+
Assert.AreEqual(DefaultCommandTimeout, BrowserManager.GetRequiredService<ITimeoutConfiguration>().Command, "Default service value should have default value");
40+
}
41+
42+
[TearDown]
43+
public static void After()
44+
{
45+
BrowserManager.SetStartup(new BrowserStartup());
46+
}
47+
48+
private class CustomLoggerConfiguration : ILoggerConfiguration
49+
{
50+
public string Language { get; } = SpecialLoggerLanguage;
51+
}
52+
53+
private interface ICustomService
54+
{
55+
string CustomValue { get; }
56+
}
57+
58+
private class CustomService : ICustomService
59+
{
60+
public string CustomValue { get; } = SpecialCustomValue;
61+
}
62+
63+
private class CustomStartup : BrowserStartup
64+
{
65+
public override IServiceCollection ConfigureServices(IServiceCollection services, Func<IServiceProvider, IApplication> applicationProvider, ISettingsFile settings = null)
66+
{
67+
settings = GetSettings();
68+
base.ConfigureServices(services, applicationProvider, settings);
69+
services.AddSingleton<ILoggerConfiguration>(new CustomLoggerConfiguration());
70+
services.AddTransient<ICustomService, CustomService>();
71+
return services;
72+
}
73+
}
74+
}
75+
}

0 commit comments

Comments
 (0)