Skip to content

Commit

Permalink
Merge pull request #21 from skbkontur/simonov/disposer
Browse files Browse the repository at this point in the history
Add IWebDriverDisposer
  • Loading branch information
callmekoo authored Apr 4, 2024
2 parents 5b28102 + f98a4aa commit 2442ca3
Show file tree
Hide file tree
Showing 9 changed files with 124 additions and 27 deletions.
29 changes: 19 additions & 10 deletions Selone.Tests/Browsers/BrowserPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,30 @@ namespace Kontur.Selone.Tests.Browsers
{
public static class BrowserPool
{
public static readonly ChromeDriverFactory ChromeDriverFactory = new ChromeDriverFactory(new ChromeDriverFactoryConfiguration
{
WindowSize = new WindowSize {Width = 1024, Height = 768}
});
public static readonly ChromeDriverFactory ChromeDriverFactory = new ChromeDriverFactory(
new ChromeDriverFactoryConfiguration
{
WindowSize = new WindowSize {Width = 1024, Height = 768}
});

public static readonly InternetExplorerDriverFactory InternetExplorerDriverFactory = new InternetExplorerDriverFactory(new InternetExplorerDriverFactoryConfiguration
{
DriverDirectoryPath = @"C:\browsers\IE"
});
public static readonly InternetExplorerDriverFactory InternetExplorerDriverFactory =
new InternetExplorerDriverFactory(new InternetExplorerDriverFactoryConfiguration
{
DriverDirectoryPath = @"C:\browsers\IE"
});

private static readonly DelegateWebDriverCleaner cleaner = new DelegateWebDriverCleaner(x => x.ResetWindows());

public static readonly IWebDriverDisposer DriverDisposer = new WebDriverDisposer(x =>
{
x.Close();
x.Quit();
x.Dispose();
});

public static readonly IWebDriverKeyedPool<Browser> Instance =
new WebDriverKeyedPool<Browser>()
.Register(Browser.Chrome, ChromeDriverFactory, cleaner)
.Register(Browser.Ie, InternetExplorerDriverFactory, cleaner);
.Register(Browser.Chrome, ChromeDriverFactory, cleaner, DriverDisposer)
.Register(Browser.Ie, InternetExplorerDriverFactory, cleaner, DriverDisposer);
}
}
4 changes: 3 additions & 1 deletion Selone.Tests/Selone.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netcoreapp3.1</TargetFrameworks>
<AssemblyName>Kontur.Selone.Tests</AssemblyName>
<Authors>Kontur</Authors>
<Company>Kontur</Company>
<Product>Kontur.Selone.Tests</Product>
<RootNamespace>Kontur.Selone.Tests</RootNamespace>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<LangVersion>latest</LangVersion>
<TargetFramework>net6.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>..\Build\Selone.Tests\</OutputPath>
Expand All @@ -20,6 +20,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Kontur.RetryableAssertions" Version="0.0.2-alpha" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.0" />
<PackageReference Include="NUnit" Version="3.10.1" />
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" />
Expand Down
68 changes: 60 additions & 8 deletions Selone.Tests/Tests/WebDrivers/WebDriverPoolTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System.Threading;
using System.Linq;
using System.Threading;
using Kontur.Selone.Extensions;
using Kontur.Selone.Tests.Browsers;
using Kontur.Selone.Tests.Browsers.Factories;
using Kontur.Selone.WebDrivers;
using Microsoft.Extensions.DependencyInjection;
using NUnit.Framework;
using OpenQA.Selenium;

Expand All @@ -12,7 +15,8 @@ public class WebDriverPoolTests
[Test]
public void Test()
{
var webDriverPool = new WebDriverPool(BrowserPool.ChromeDriverFactory, new DelegateWebDriverCleaner(x => x.ResetWindows()));
var webDriverPool = new WebDriverPool(BrowserPool.ChromeDriverFactory,
new DelegateWebDriverCleaner(x => x.ResetWindows()), BrowserPool.DriverDisposer);
using (var pooled = webDriverPool.AcquireWrapper())
{
var webDriver = pooled.WrappedDriver;
Expand All @@ -39,19 +43,67 @@ public void Create_New_WebDriver_Instance_When_Previous_Was_Disposed()
{
x.ResetWindows();
x.Quit();
}));
}), BrowserPool.DriverDisposer);

var webDriver = webDriverPool.Acquire();
var sessionId1 = ((IHasSessionId)webDriver).SessionId;
var sessionId1 = ((IHasSessionId) webDriver).SessionId;
webDriverPool.Release(webDriver);

webDriver = webDriverPool.Acquire();
var sessionId2 = ((IHasSessionId)webDriver).SessionId;
var sessionId2 = ((IHasSessionId) webDriver).SessionId;
webDriverPool.Release(webDriver);

Assert.AreNotEqual(sessionId1, sessionId2);

webDriverPool.Clear();
}

private IWebDriverPool InitWebDriverPool()
{
using var sp = new ServiceCollection()
.AddSingleton<IWebDriverPool, WebDriverPool>()
.AddSingleton<IWebDriverFactory, ChromeDriverFactory>()
.AddSingleton<ChromeDriverFactoryConfiguration>()
.AddSingleton<IWebDriverCleaner>(_ => new DelegateWebDriverCleaner(x => x.ResetWindows()))
.AddSingleton<IWebDriverDisposer, WebDriverDisposer>(_ => new WebDriverDisposer(x =>
{
x.Close();
x.Quit();
x.Dispose();
})).BuildServiceProvider();

return sp.GetRequiredService<IWebDriverPool>();
}

[Test]
public void CorrectReusedDrivers_AndDispose()
{
var driverPool = InitWebDriverPool();

var firstUsingDrivers = new[] {driverPool.Acquire(), driverPool.Acquire()};
foreach (var driver in firstUsingDrivers)
{
driver.Navigate().GoToUrl("https://kontur.ru");
driverPool.Release(driver);
}

var secondUsingDrivers = new[] {driverPool.Acquire(), driverPool.Acquire()};
foreach (var driver in secondUsingDrivers)
{
driver.Navigate().GoToUrl("https://kontur.ru/press/news");
driverPool.Release(driver);
}

Assert.Multiple(() =>
{
Assert.That(
firstUsingDrivers.Select(x => ((IHasSessionId) x).SessionId),
Is.EquivalentTo(
secondUsingDrivers.Select(x => ((IHasSessionId) x).SessionId))
);
Assert.DoesNotThrow(() => driverPool.Clear());
Assert.IsTrue(firstUsingDrivers.All(x=> ((IHasSessionId) x).SessionId is null));
});
}
}
}
2 changes: 1 addition & 1 deletion Selone/Selone.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net45;netstandard2.0</TargetFrameworks>
<TargetFrameworks>net45;net5.0;net6.0;net7.0;netstandard2.0</TargetFrameworks>
<AssemblyName>Kontur.Selone</AssemblyName>
<Authors>Kontur</Authors>
<Company>Kontur</Company>
Expand Down
8 changes: 8 additions & 0 deletions Selone/WebDrivers/IWebDriverDisposer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using OpenQA.Selenium;

namespace Kontur.Selone.WebDrivers;

public interface IWebDriverDisposer
{
void Dispose(IWebDriver webDriver);
}
2 changes: 1 addition & 1 deletion Selone/WebDrivers/IWebDriverKeyedPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Kontur.Selone.WebDrivers
{
public interface IWebDriverKeyedPool<TKey>
{
IWebDriverKeyedPool<TKey> Register(TKey key, IWebDriverFactory factory, IWebDriverCleaner cleaner);
IWebDriverKeyedPool<TKey> Register(TKey key, IWebDriverFactory factory, IWebDriverCleaner cleaner, IWebDriverDisposer disposer);
IWebDriver Acquire(TKey key);
IPooledWebDriver AcquireWrapper(TKey key);
void Release(IWebDriver webDriver);
Expand Down
19 changes: 19 additions & 0 deletions Selone/WebDrivers/WebDriverDisposer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System;
using OpenQA.Selenium;

namespace Kontur.Selone.WebDrivers;

public class WebDriverDisposer : IWebDriverDisposer
{
private readonly Action<IWebDriver> disposeAction;

public WebDriverDisposer(Action<IWebDriver> disposeAction)
{
this.disposeAction = disposeAction;
}

public void Dispose(IWebDriver webDriver)
{
disposeAction?.Invoke(webDriver);
}
}
4 changes: 2 additions & 2 deletions Selone/WebDrivers/WebDriverKeyedPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ public class WebDriverKeyedPool<TKey> : IWebDriverKeyedPool<TKey>
private readonly ConcurrentDictionary<TKey, IWebDriverPool> pools = new ConcurrentDictionary<TKey, IWebDriverPool>();
private readonly ConcurrentDictionary<IWebDriver, TKey> acquired = new ConcurrentDictionary<IWebDriver, TKey>();

public IWebDriverKeyedPool<TKey> Register(TKey key, IWebDriverFactory factory, IWebDriverCleaner cleaner)
public IWebDriverKeyedPool<TKey> Register(TKey key, IWebDriverFactory factory, IWebDriverCleaner cleaner, IWebDriverDisposer disposer)
{
if (!pools.TryAdd(key, new WebDriverPool(factory, cleaner)))
if (!pools.TryAdd(key, new WebDriverPool(factory, cleaner, disposer)))
{
throw new Exception($"WebDriverFactory for key '{key}' already registered");
}
Expand Down
15 changes: 11 additions & 4 deletions Selone/WebDrivers/WebDriverPool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,19 @@ public class WebDriverPool : IWebDriverPool
{
private readonly IWebDriverFactory factory;
private readonly IWebDriverCleaner cleaner;
private readonly IWebDriverDisposer driverDisposer;
private readonly ConcurrentQueue<IWebDriver> queue = new ConcurrentQueue<IWebDriver>();
private readonly ConcurrentDictionary<IWebDriver, bool> acquired = new ConcurrentDictionary<IWebDriver, bool>();

public WebDriverPool(IWebDriverFactory factory, IWebDriverCleaner cleaner)
public WebDriverPool(
IWebDriverFactory factory,
IWebDriverCleaner cleaner,
IWebDriverDisposer driverDisposer
)
{
this.factory = factory;
this.cleaner = cleaner;
this.driverDisposer = driverDisposer;
}

public IWebDriver Acquire()
Expand All @@ -36,7 +42,7 @@ public void Clear()
{
while (queue.TryDequeue(out var webDriver))
{
webDriver.Dispose();
driverDisposer.Dispose(webDriver);
}
}

Expand All @@ -51,12 +57,13 @@ private void ReleaseInternal(IWebDriver webDriver)
{
if (!acquired.TryRemove(webDriver, out var dummy))
{
throw new Exception($"WebDriver {webDriver.GetType().Name} was not taken from the pool or already released");
throw new Exception(
$"WebDriver {webDriver.GetType().Name} was not taken from the pool or already released");
}

cleaner?.Clear(webDriver);

if (((IHasSessionId)webDriver).SessionId != null)
if (((IHasSessionId) webDriver).SessionId != null)
{
queue.Enqueue(webDriver);
}
Expand Down

0 comments on commit 2442ca3

Please sign in to comment.