diff --git a/dotnet/private/dotnet_nunit_test_suite.bzl b/dotnet/private/dotnet_nunit_test_suite.bzl
index 9c468eadb83f4..4fc22910d535d 100644
--- a/dotnet/private/dotnet_nunit_test_suite.bzl
+++ b/dotnet/private/dotnet_nunit_test_suite.bzl
@@ -88,7 +88,7 @@ _BROWSERS = {
"ActiveDriverConfig=IE",
],
"data": [],
- "tags": [],
+ "tags": ["exclusive-if-local"], # IE cannot run in parallel.
"target_compatible_with": ["@platforms//os:windows"],
},
"safari": {
@@ -97,7 +97,7 @@ _BROWSERS = {
"ActiveDriverConfig=Safari",
],
"data": [],
- "tags": [],
+ "tags": ["exclusive-if-local"], # Safari cannot run in parallel.
"target_compatible_with": ["@platforms//os:osx"],
},
"remote": {
diff --git a/dotnet/test/remote/AssemblyTeardown.cs b/dotnet/test/remote/AssemblyTeardown.cs
index a89860208fe92..3284a284871dd 100644
--- a/dotnet/test/remote/AssemblyTeardown.cs
+++ b/dotnet/test/remote/AssemblyTeardown.cs
@@ -20,6 +20,9 @@
using NUnit.Framework;
using OpenQA.Selenium.Testing.NUnit;
+[assembly: Parallelizable(ParallelScope.Fixtures)]
+[assembly: SingleSessionBrowser(Browser.Safari, Browser.IE)]
+
[SetUpFixture]
#pragma warning disable // Outside a namespace to affect the entire assembly
public class AssemblyTeardown : AssemblyFixtureBase
diff --git a/dotnet/test/remote/RemoteWebDriverSpecificTests.cs b/dotnet/test/remote/RemoteWebDriverSpecificTests.cs
index e7e1dc69cdc9e..bdba841af7909 100644
--- a/dotnet/test/remote/RemoteWebDriverSpecificTests.cs
+++ b/dotnet/test/remote/RemoteWebDriverSpecificTests.cs
@@ -52,7 +52,7 @@ public void Teardown()
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void ShouldBeAbleToCreateRemoteWebDriverWithNoSlashAtEndOfUri()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
+ CloseDriver();
DriverOptions options = OperatingSystem.IsWindows() ? new EdgeOptions() : new ChromeOptions();
RemoteWebDriver noSlashDriver = new RemoteWebDriver(RemoteSeleniumServer.ServerUri, options);
noSlashDriver.Url = Urls.JavascriptPage;
diff --git a/dotnet/test/support/AssemblyFixture.cs b/dotnet/test/support/AssemblyFixture.cs
index 1f945fec08ed5..9e5949162bda8 100644
--- a/dotnet/test/support/AssemblyFixture.cs
+++ b/dotnet/test/support/AssemblyFixture.cs
@@ -17,6 +17,9 @@
// under the License.
//
+[assembly: Parallelizable(ParallelScope.Fixtures)]
+[assembly: SingleSessionBrowser(Browser.Safari, Browser.IE)]
+
namespace OpenQA.Selenium.Support.Tests;
[SetUpFixture]
diff --git a/dotnet/test/testing.nunit/AssemblyFixtureBase.cs b/dotnet/test/testing.nunit/AssemblyFixtureBase.cs
index 3706d78dacb3b..d95add8664bbf 100644
--- a/dotnet/test/testing.nunit/AssemblyFixtureBase.cs
+++ b/dotnet/test/testing.nunit/AssemblyFixtureBase.cs
@@ -42,7 +42,6 @@ public async Task RunBeforeAnyTestAsync()
[OneTimeTearDown]
public async Task RunAfterAnyTestsAsync()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
await EnvironmentManager.Instance.WebServer.StopAsync();
if (StartRemoteServer)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/DefaultSafariDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/DefaultSafariDriver.cs
index c4f133390a1df..68610d8f414c4 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/DefaultSafariDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/DefaultSafariDriver.cs
@@ -26,7 +26,7 @@ namespace OpenQA.Selenium.Testing.NUnit.DriverConfigs;
// constructor.
public class DefaultSafariDriver : SafariDriver
{
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public DefaultSafariDriver(SafariOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/DevChannelChromeDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/DevChannelChromeDriver.cs
index 637aa71b82ca9..7edefa1e7b86f 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/DevChannelChromeDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/DevChannelChromeDriver.cs
@@ -48,7 +48,7 @@ public DevChannelChromeDriver()
{
}
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public DevChannelChromeDriver(ChromeOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/DevChannelEdgeDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/DevChannelEdgeDriver.cs
index 8de489ad0d674..3921acf557bf5 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/DevChannelEdgeDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/DevChannelEdgeDriver.cs
@@ -28,7 +28,7 @@ public DevChannelEdgeDriver()
{
}
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public DevChannelEdgeDriver(EdgeOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/EdgeInternetExplorerModeDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/EdgeInternetExplorerModeDriver.cs
index 07a8f4a56b93d..5da174e566e4a 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/EdgeInternetExplorerModeDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/EdgeInternetExplorerModeDriver.cs
@@ -31,7 +31,7 @@ public EdgeInternetExplorerModeDriver()
{
}
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public EdgeInternetExplorerModeDriver(InternetExplorerOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/NightlyChannelFirefoxDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/NightlyChannelFirefoxDriver.cs
index 494f50fc1b033..9601da30ebbd2 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/NightlyChannelFirefoxDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/NightlyChannelFirefoxDriver.cs
@@ -31,7 +31,7 @@ public NightlyChannelFirefoxDriver()
{
}
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public NightlyChannelFirefoxDriver(FirefoxOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/SafariTechnologyPreviewDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/SafariTechnologyPreviewDriver.cs
index e6ed775a2b08e..2d130dfb0ab5b 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/SafariTechnologyPreviewDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/SafariTechnologyPreviewDriver.cs
@@ -31,7 +31,7 @@ public SafariTechnologyPreviewDriver()
{
}
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public SafariTechnologyPreviewDriver(SafariOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/StableChannelChromeDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/StableChannelChromeDriver.cs
index b7752d779ab47..c883b62367065 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/StableChannelChromeDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/StableChannelChromeDriver.cs
@@ -28,7 +28,7 @@ public StableChannelChromeDriver()
{
}
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public StableChannelChromeDriver(ChromeOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/StableChannelEdgeDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/StableChannelEdgeDriver.cs
index cd2b6bd0244af..cd9c2b0feeff9 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/StableChannelEdgeDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/StableChannelEdgeDriver.cs
@@ -29,7 +29,7 @@ public StableChannelEdgeDriver()
{
}
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public StableChannelEdgeDriver(EdgeOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverConfigs/StableChannelFirefoxDriver.cs b/dotnet/test/testing.nunit/DriverConfigs/StableChannelFirefoxDriver.cs
index e60a868436168..20becc3d8cb39 100644
--- a/dotnet/test/testing.nunit/DriverConfigs/StableChannelFirefoxDriver.cs
+++ b/dotnet/test/testing.nunit/DriverConfigs/StableChannelFirefoxDriver.cs
@@ -31,7 +31,7 @@ public StableChannelFirefoxDriver()
{
}
- // Required for dynamic setting with `EnvironmentManager.Instance.CreateDriverInstance(options)`
+ // Required for dynamic setting with `DriverFactory.CreateDriver(options)`
public StableChannelFirefoxDriver(FirefoxOptions options)
: base(options)
{
diff --git a/dotnet/test/testing.nunit/DriverTestFixture.cs b/dotnet/test/testing.nunit/DriverTestFixture.cs
index f5483622f7c31..ab7f686194fb8 100644
--- a/dotnet/test/testing.nunit/DriverTestFixture.cs
+++ b/dotnet/test/testing.nunit/DriverTestFixture.cs
@@ -44,17 +44,20 @@ public bool IsNativeEventsEnabled
}
}
+ protected DriverFactory DriverFactory { get; private set; }
+
[OneTimeSetUp]
- public void SetUp()
+ public void InitFixtureDriver()
{
- Driver = EnvironmentManager.Instance.GetCurrentDriver();
+ DriverFactory = CreateDriverFactory();
+ Driver = CreateDriverInstance();
}
[OneTimeTearDown]
- public void TearDown()
+ public void DisposeFixtureDriver()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
Driver?.Dispose();
+ Driver = null;
}
[TearDown]
@@ -63,16 +66,30 @@ public void ResetOnError()
if (TestContext.CurrentContext.Result.Outcome == ResultState.Error)
{
Driver?.Dispose();
- Driver = EnvironmentManager.Instance.CreateFreshDriver();
+ Driver = CreateDriverInstance();
}
}
- ///
- /// Exists because a given test might require a fresh driver.
- ///
- protected void CreateFreshDriver()
+ protected virtual DriverFactory CreateDriverFactory()
+ {
+ return new DriverFactory(EnvironmentManager.Instance);
+ }
+
+ protected IWebDriver CreateDriverInstance(DriverOptions options = null)
+ {
+ return DriverFactory.CreateDriver(options);
+ }
+
+ protected internal void CloseDriver()
+ {
+ Driver?.Dispose();
+ Driver = null;
+ }
+
+ protected internal void CreateFreshDriver()
{
- Driver = EnvironmentManager.Instance.CreateFreshDriver();
+ CloseDriver();
+ Driver = CreateDriverInstance();
}
protected void WaitFor(Func waitFunction, string timeoutMessage)
@@ -87,17 +104,16 @@ protected T WaitFor(Func waitFunction, string timeoutMessage)
protected T WaitFor(Func waitFunction, TimeSpan timeout, string timeoutMessage)
{
- var waiter = new WebDriverWait(Driver, timeout)
+ // Not bound to Driver: callers may wait on a local driver while the fixture driver is closed.
+ var waiter = new DefaultWait>(waitFunction)
{
+ Timeout = timeout,
PollingInterval = TimeSpan.FromMilliseconds(100),
Message = $"Condition timed out: {timeoutMessage}",
};
waiter.IgnoreExceptionTypes(typeof(Exception));
- return waiter.Until((driver) =>
- {
- return waitFunction();
- });
+ return waiter.Until(func => func());
}
}
diff --git a/dotnet/test/testing.nunit/Environment/DriverFactory.cs b/dotnet/test/testing.nunit/Environment/DriverFactory.cs
index 2db7a8674422f..0a40012072b0c 100644
--- a/dotnet/test/testing.nunit/Environment/DriverFactory.cs
+++ b/dotnet/test/testing.nunit/Environment/DriverFactory.cs
@@ -17,6 +17,7 @@
// under the License.
//
+using System.Collections.Concurrent;
using System.IO;
using System.Reflection;
using OpenQA.Selenium.Chrome;
@@ -30,20 +31,37 @@ namespace OpenQA.Selenium.Testing.NUnit.Environment;
public class DriverFactory
{
+ private static readonly ConcurrentDictionary driverTypes = new();
+
+ private readonly Type driverType;
private readonly string driverPath;
private readonly string browserBinaryLocation;
+ private readonly bool headless;
private readonly Dictionary serviceTypes = new Dictionary();
private readonly Dictionary optionsTypes = new Dictionary();
- public DriverFactory(string driverPath, string browserBinaryLocation)
+ public DriverFactory(EnvironmentManager environment)
{
- this.driverPath = driverPath;
- this.browserBinaryLocation = browserBinaryLocation;
+ this.driverType = driverTypes.GetOrAdd(environment.DriverTypeName, ResolveDriverType);
+ this.driverPath = environment.DriverServiceLocation;
+ this.browserBinaryLocation = environment.BrowserLocation;
+ this.headless = environment.Headless;
this.PopulateServiceTypes();
this.PopulateOptionsTypes();
}
+ private static Type ResolveDriverType(string driverTypeName)
+ {
+ // Bazel uses unpredictable assembly names to execute tests, so search all loaded assemblies.
+ return AppDomain.CurrentDomain.GetAssemblies()
+ .AsEnumerable()
+ .Reverse()
+ .Select(assembly => assembly.GetType(driverTypeName))
+ .FirstOrDefault(t => t != null)
+ ?? throw new ArgumentOutOfRangeException(nameof(driverTypeName), $"Unable to find driver type {driverTypeName}");
+ }
+
private void PopulateOptionsTypes()
{
this.optionsTypes[Browser.Chrome] = typeof(ChromeOptions);
@@ -64,12 +82,7 @@ private void PopulateServiceTypes()
public event EventHandler DriverStarting;
- public IWebDriver CreateDriver(Type driverType, bool logging = false)
- {
- return CreateDriverWithOptions(driverType, null, logging);
- }
-
- public IWebDriver CreateDriverWithOptions(Type driverType, DriverOptions driverOptions, bool logging = false)
+ public IWebDriver CreateDriver(DriverOptions driverOptions = null, bool logging = false)
{
Browser browser = Browser.All;
DriverService service = null;
@@ -84,7 +97,7 @@ public IWebDriver CreateDriverWithOptions(Type driverType, DriverOptions driverO
var chromeOptions = (ChromeOptions)options;
chromeOptions.AddArguments("--no-sandbox", "--disable-dev-shm-usage");
- if (EnvironmentManager.Instance.Headless)
+ if (this.headless)
{
chromeOptions.AddArgument("--headless");
}
@@ -106,7 +119,7 @@ public IWebDriver CreateDriverWithOptions(Type driverType, DriverOptions driverO
var edgeOptions = (EdgeOptions)options;
edgeOptions.AddArguments("--no-sandbox", "--disable-dev-shm-usage");
- if (EnvironmentManager.Instance.Headless)
+ if (this.headless)
{
edgeOptions.AddArgument("--headless");
}
@@ -135,7 +148,7 @@ public IWebDriver CreateDriverWithOptions(Type driverType, DriverOptions driverO
{
browser = Browser.Firefox;
options = GetDriverOptions(driverType, driverOptions);
- if (EnvironmentManager.Instance.Headless)
+ if (this.headless)
{
((FirefoxOptions)options).AddArgument("-headless");
}
diff --git a/dotnet/test/testing.nunit/Environment/EnvironmentManager.cs b/dotnet/test/testing.nunit/Environment/EnvironmentManager.cs
index 1eb21d99b7d25..abee6831cfccc 100644
--- a/dotnet/test/testing.nunit/Environment/EnvironmentManager.cs
+++ b/dotnet/test/testing.nunit/Environment/EnvironmentManager.cs
@@ -26,10 +26,7 @@ namespace OpenQA.Selenium.Testing.NUnit.Environment;
public class EnvironmentManager
{
- private static EnvironmentManager instance;
- private readonly Type driverType;
- private IWebDriver driver;
- private readonly DriverFactory driverFactory;
+ private static readonly Lazy instance = new(() => new EnvironmentManager());
private EnvironmentManager()
{
@@ -69,22 +66,9 @@ private EnvironmentManager()
DriverConfig driverConfig = env.DriverConfigs[activeDriverConfig];
Headless = bool.TryParse(headless, out bool isHeadless) && isHeadless;
-
- this.driverFactory = new DriverFactory(driverServiceLocation, browserLocation);
- this.driverFactory.DriverStarting += OnDriverStarting;
-
- // Search for the driver type in the all assemblies,
- // bazel uses unpredictable assembly names to execute tests
- driverType = AppDomain.CurrentDomain.GetAssemblies()
- .AsEnumerable()
- .Reverse()
- .Select(assembly => assembly.GetType(driverConfig.DriverTypeName))
- .FirstOrDefault(t => t != null);
-
- if (driverType == null)
- {
- throw new ArgumentOutOfRangeException($"Unable to find driver type {driverConfig.DriverTypeName}");
- }
+ DriverServiceLocation = driverServiceLocation;
+ BrowserLocation = browserLocation;
+ DriverTypeName = driverConfig.DriverTypeName;
Browser = driverConfig.BrowserValue;
RemoteCapabilities = driverConfig.RemoteCapabilities;
@@ -142,17 +126,20 @@ private EnvironmentManager()
{
RemoteServer?.StopAsync().Wait();
WebServer?.StopAsync().Wait();
- CloseCurrentDriver();
}
- public event EventHandler DriverStarting;
-
- public static EnvironmentManager Instance => instance ??= new EnvironmentManager();
+ public static EnvironmentManager Instance => instance.Value;
public Browser Browser { get; }
public bool Headless { get; }
+ public string DriverTypeName { get; }
+
+ public string DriverServiceLocation { get; }
+
+ public string BrowserLocation { get; }
+
public string CurrentDirectory
{
get
@@ -173,39 +160,6 @@ public string CurrentDirectory
public string RemoteCapabilities { get; }
- public IWebDriver GetCurrentDriver()
- {
- return driver ?? CreateFreshDriver();
- }
-
- public IWebDriver CreateDriverInstance()
- {
- return driverFactory.CreateDriver(driverType);
- }
-
- public IWebDriver CreateDriverInstance(DriverOptions options)
- {
- return driverFactory.CreateDriverWithOptions(driverType, options);
- }
-
- public IWebDriver CreateFreshDriver()
- {
- CloseCurrentDriver();
- driver = CreateDriverInstance();
- return driver;
- }
-
- public void CloseCurrentDriver()
- {
- driver?.Quit();
- driver = null;
- }
-
- protected void OnDriverStarting(object sender, DriverStartingEventArgs e)
- {
- this.DriverStarting?.Invoke(sender, e);
- }
-
private static string FindProjectRoot(string startDirectory)
{
// Walk up until we find a directory containing common/ and dotnet/
diff --git a/dotnet/test/testing.nunit/NeedsFreshDriverAttribute.cs b/dotnet/test/testing.nunit/NeedsFreshDriverAttribute.cs
index 7a376c7555559..dfaebebdb0d4d 100644
--- a/dotnet/test/testing.nunit/NeedsFreshDriverAttribute.cs
+++ b/dotnet/test/testing.nunit/NeedsFreshDriverAttribute.cs
@@ -18,7 +18,6 @@
//
using NUnit.Framework.Interfaces;
-using OpenQA.Selenium.Testing.NUnit.Environment;
namespace OpenQA.Selenium.Testing.NUnit;
@@ -32,8 +31,7 @@ public override void BeforeTest(ITest test)
{
if (test.Fixture is DriverTestFixture fixtureInstance && this.IsCreatedBeforeTest)
{
- EnvironmentManager.Instance.CreateFreshDriver();
- fixtureInstance.Driver = EnvironmentManager.Instance.GetCurrentDriver();
+ fixtureInstance.CreateFreshDriver();
}
base.BeforeTest(test);
@@ -43,8 +41,7 @@ public override void AfterTest(ITest test)
{
if (test.Fixture is DriverTestFixture fixtureInstance && this.IsCreatedAfterTest)
{
- EnvironmentManager.Instance.CreateFreshDriver();
- fixtureInstance.Driver = EnvironmentManager.Instance.GetCurrentDriver();
+ fixtureInstance.CreateFreshDriver();
}
base.AfterTest(test);
diff --git a/dotnet/test/testing.nunit/SingleSessionBrowserAttribute.cs b/dotnet/test/testing.nunit/SingleSessionBrowserAttribute.cs
new file mode 100644
index 0000000000000..383eb12887a0e
--- /dev/null
+++ b/dotnet/test/testing.nunit/SingleSessionBrowserAttribute.cs
@@ -0,0 +1,45 @@
+//
+// Licensed to the Software Freedom Conservancy (SFC) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The SFC licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+using NUnit.Framework.Interfaces;
+using NUnit.Framework.Internal;
+using OpenQA.Selenium.Testing.NUnit.Environment;
+
+namespace OpenQA.Selenium.Testing.NUnit;
+
+///
+/// Runs the whole assembly sequentially when the active browser supports only one session at a time.
+///
+///
+/// An explicit NumberOfTestWorkers run setting takes precedence over this attribute.
+///
+[AttributeUsage(AttributeTargets.Assembly)]
+public sealed class SingleSessionBrowserAttribute(params Browser[] browsers) : NUnitAttribute, IApplyToTest
+{
+ public IReadOnlyList Browsers { get; } = browsers;
+
+ public void ApplyToTest(Test test)
+ {
+ if (Browsers.Contains(EnvironmentManager.Instance.Browser))
+ {
+ // Zero workers makes NUnit use the sequential dispatcher, ignoring [Parallelizable].
+ test.Properties.Set(PropertyNames.LevelOfParallelism, 0);
+ }
+ }
+}
diff --git a/dotnet/test/webdriver/AlertsTests.cs b/dotnet/test/webdriver/AlertsTests.cs
index 7b868033b18fc..d43f339fb9526 100644
--- a/dotnet/test/webdriver/AlertsTests.cs
+++ b/dotnet/test/webdriver/AlertsTests.cs
@@ -17,7 +17,6 @@
// under the License.
//
-using OpenQA.Selenium.Testing.NUnit.Environment;
namespace OpenQA.Selenium.Tests;
@@ -451,7 +450,7 @@ public void CanQuitWhenAnAlertIsPresent()
Driver.Url = CreateAlertPage("cheese");
Driver.FindElement(By.Id("alert")).Click();
IAlert alert = WaitFor(AlertToBePresent, "No alert found");
- EnvironmentManager.Instance.CloseCurrentDriver();
+ CloseDriver();
}
[Test]
diff --git a/dotnet/test/webdriver/AssemblyFixture.cs b/dotnet/test/webdriver/AssemblyFixture.cs
index 98b77c84ed2be..f3147eabd77da 100644
--- a/dotnet/test/webdriver/AssemblyFixture.cs
+++ b/dotnet/test/webdriver/AssemblyFixture.cs
@@ -17,6 +17,9 @@
// under the License.
//
+[assembly: Parallelizable(ParallelScope.Fixtures)]
+[assembly: SingleSessionBrowser(Browser.Safari, Browser.IE)]
+
namespace OpenQA.Selenium.Tests;
[SetUpFixture]
diff --git a/dotnet/test/webdriver/BiDi/BiDiFixture.cs b/dotnet/test/webdriver/BiDi/BiDiFixture.cs
index ba706cfd9b11f..fac2364a5dc34 100644
--- a/dotnet/test/webdriver/BiDi/BiDiFixture.cs
+++ b/dotnet/test/webdriver/BiDi/BiDiFixture.cs
@@ -42,7 +42,7 @@ public async Task BiDiSetUp()
UnhandledPromptBehavior = UnhandledPromptBehavior.Ignore,
};
- driver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ driver = new DriverFactory(EnvironmentManager.Instance).CreateDriver(options);
bidi = await driver.AsBiDiAsync();
diff --git a/dotnet/test/webdriver/CookieImplementationTests.cs b/dotnet/test/webdriver/CookieImplementationTests.cs
index 4890d614a442d..0327935581c3c 100644
--- a/dotnet/test/webdriver/CookieImplementationTests.cs
+++ b/dotnet/test/webdriver/CookieImplementationTests.cs
@@ -21,7 +21,6 @@
using System.Text;
using System.Text.RegularExpressions;
using OpenQA.Selenium.Internal;
-using OpenQA.Selenium.Testing.NUnit.Environment;
namespace OpenQA.Selenium.Tests;
@@ -874,7 +873,7 @@ private void GotoValidDomainAndClearCookies(string page)
// This may mask some errors, where DeleteAllCookies doesn't fully
// delete all it should, but that's a tradeoff we need to be willing
// to make.
- Driver = EnvironmentManager.Instance.CreateFreshDriver();
+ CreateFreshDriver();
GoToPage(page);
}
}
diff --git a/dotnet/test/webdriver/CorrectEventFiringTests.cs b/dotnet/test/webdriver/CorrectEventFiringTests.cs
index 1d6e49d76103a..5f84e65c6ff07 100644
--- a/dotnet/test/webdriver/CorrectEventFiringTests.cs
+++ b/dotnet/test/webdriver/CorrectEventFiringTests.cs
@@ -42,7 +42,7 @@ public void ShouldFireFocusEventWhenClicking()
[IgnoreBrowser(Browser.Safari, "Safari driver does not support multiple instances")]
public void ShouldFireFocusEventInNonTopmostWindow()
{
- IWebDriver driver2 = EnvironmentManager.Instance.CreateDriverInstance();
+ IWebDriver driver2 = CreateDriverInstance();
try
{
// topmost
@@ -283,7 +283,7 @@ public void SendingKeysToAnotherElementShouldCauseTheBlurEventToFire()
[IgnoreBrowser(Browser.Safari, "Safari driver does not support multiple instances")]
public void SendingKeysToAnotherElementShouldCauseTheBlurEventToFireInNonTopmostWindow()
{
- IWebDriver driver2 = EnvironmentManager.Instance.CreateDriverInstance();
+ IWebDriver driver2 = CreateDriverInstance();
IWebElement element;
IWebElement element2;
try
diff --git a/dotnet/test/webdriver/DevTools/DevToolsTestFixture.cs b/dotnet/test/webdriver/DevTools/DevToolsTestFixture.cs
index bfc28c2befbab..485e7277c2bad 100644
--- a/dotnet/test/webdriver/DevTools/DevToolsTestFixture.cs
+++ b/dotnet/test/webdriver/DevTools/DevToolsTestFixture.cs
@@ -34,7 +34,11 @@ public abstract class DevToolsTestFixture : DriverTestFixture
[SetUp]
public void Setup()
{
- Driver = EnvironmentManager.Instance.GetCurrentDriver();
+ if (Driver is null)
+ {
+ CreateFreshDriver();
+ }
+
devTools = Driver as IDevTools;
if (devTools == null)
{
@@ -51,9 +55,8 @@ public void Teardown()
if (session != null)
{
session.Dispose();
- EnvironmentManager.Instance.CloseCurrentDriver();
+ CloseDriver();
session = null;
- Driver = null;
}
}
}
diff --git a/dotnet/test/webdriver/DownloadsTests.cs b/dotnet/test/webdriver/DownloadsTests.cs
index ea51c12f81859..0cb96e35079dc 100644
--- a/dotnet/test/webdriver/DownloadsTests.cs
+++ b/dotnet/test/webdriver/DownloadsTests.cs
@@ -20,7 +20,6 @@
using System.IO;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;
-using OpenQA.Selenium.Testing.NUnit.Environment;
namespace OpenQA.Selenium.Tests;
@@ -32,7 +31,7 @@ public class DownloadsTests : DriverTestFixture
[SetUp]
public void ResetDriver()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
+ CloseDriver();
InitLocalDriver();
}
@@ -45,7 +44,7 @@ public void QuitAdditionalDriver()
localDriver = null;
}
- EnvironmentManager.Instance.CreateFreshDriver();
+ CreateFreshDriver();
}
[Test]
@@ -105,7 +104,7 @@ private void InitLocalDriver()
DownloadableFilesOptions options = new DownloadableFilesOptions();
options.EnableDownloads = true;
- localDriver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ localDriver = CreateDriverInstance(options);
}
public class DownloadableFilesOptions : DriverOptions
diff --git a/dotnet/test/webdriver/Firefox/FirefoxDriverServiceTests.cs b/dotnet/test/webdriver/Firefox/FirefoxDriverServiceTests.cs
index 6629eb9194910..fbc3d20038a38 100644
--- a/dotnet/test/webdriver/Firefox/FirefoxDriverServiceTests.cs
+++ b/dotnet/test/webdriver/Firefox/FirefoxDriverServiceTests.cs
@@ -24,6 +24,7 @@
namespace OpenQA.Selenium.Tests.Firefox;
[TestFixture]
+[NonParallelizable]
[IgnoreBrowser(Browser.Chrome)]
[IgnoreBrowser(Browser.Edge)]
[IgnoreBrowser(Browser.Safari)]
diff --git a/dotnet/test/webdriver/Internal/Logging/LogTests.cs b/dotnet/test/webdriver/Internal/Logging/LogTests.cs
index 1a1e7c59578e6..7689cf4acf454 100644
--- a/dotnet/test/webdriver/Internal/Logging/LogTests.cs
+++ b/dotnet/test/webdriver/Internal/Logging/LogTests.cs
@@ -21,6 +21,7 @@
namespace OpenQA.Selenium.Tests.Internal.Logging;
+[NonParallelizable]
public class LogTests
{
private TestLogHandler testLogHandler;
diff --git a/dotnet/test/webdriver/PageLoadingTests.cs b/dotnet/test/webdriver/PageLoadingTests.cs
index 162570f7ae924..6a450c70a85b3 100644
--- a/dotnet/test/webdriver/PageLoadingTests.cs
+++ b/dotnet/test/webdriver/PageLoadingTests.cs
@@ -17,7 +17,6 @@
// under the License.
//
-using OpenQA.Selenium.Testing.NUnit.Environment;
namespace OpenQA.Selenium.Tests;
@@ -29,7 +28,10 @@ public class PageLoadingTests : DriverTestFixture
[SetUp]
public void RestartOriginalDriver()
{
- Driver = EnvironmentManager.Instance.GetCurrentDriver();
+ if (Driver is null)
+ {
+ CreateFreshDriver();
+ }
}
[TearDown]
@@ -459,7 +461,7 @@ private void AssertPageLoadTimeoutIsEnforced(Action action, long webDriverPageLo
private void InitLocalDriver(PageLoadStrategy strategy)
{
- EnvironmentManager.Instance.CloseCurrentDriver();
+ CloseDriver();
if (localDriver != null)
{
localDriver.Quit();
@@ -467,7 +469,7 @@ private void InitLocalDriver(PageLoadStrategy strategy)
PageLoadStrategyOptions options = new PageLoadStrategyOptions();
options.PageLoadStrategy = strategy;
- localDriver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ localDriver = CreateDriverInstance(options);
}
private class PageLoadStrategyOptions : DriverOptions
diff --git a/dotnet/test/webdriver/ProxySettingTests.cs b/dotnet/test/webdriver/ProxySettingTests.cs
index 7058d67dea365..0fdedc09c77d8 100644
--- a/dotnet/test/webdriver/ProxySettingTests.cs
+++ b/dotnet/test/webdriver/ProxySettingTests.cs
@@ -38,9 +38,7 @@ public class ProxySettingTests : DriverTestFixture
[SetUp]
public void RestartOriginalDriver()
{
- Driver = EnvironmentManager.Instance.GetCurrentDriver();
proxyServer = new ProxyServer();
- EnvironmentManager.Instance.DriverStarting += EnvironmentManagerDriverStarting;
}
[TearDown]
@@ -57,8 +55,6 @@ public void QuitAdditionalDriver()
proxyServer.Quit();
proxyServer = null;
}
-
- EnvironmentManager.Instance.DriverStarting -= EnvironmentManagerDriverStarting;
}
[Test]
@@ -143,7 +139,14 @@ public void CanUseAutoConfigFileThatOnlyProxiesCertainHosts()
}
}
- private void EnvironmentManagerDriverStarting(object sender, DriverStartingEventArgs e)
+ protected override DriverFactory CreateDriverFactory()
+ {
+ DriverFactory factory = base.CreateDriverFactory();
+ factory.DriverStarting += DriverFactoryDriverStarting;
+ return factory;
+ }
+
+ private void DriverFactoryDriverStarting(object sender, DriverStartingEventArgs e)
{
if (e.Options is InternetExplorerOptions ieOptions)
{
@@ -153,7 +156,7 @@ private void EnvironmentManagerDriverStarting(object sender, DriverStartingEvent
private void InitLocalDriver(Proxy proxy)
{
- EnvironmentManager.Instance.CloseCurrentDriver();
+ CloseDriver();
if (localDriver != null)
{
localDriver.Quit();
@@ -161,7 +164,7 @@ private void InitLocalDriver(Proxy proxy)
ProxyOptions options = new ProxyOptions();
options.Proxy = proxy;
- localDriver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ localDriver = CreateDriverInstance(options);
}
private class ProxyOptions : DriverOptions
diff --git a/dotnet/test/webdriver/SessionHandlingTests.cs b/dotnet/test/webdriver/SessionHandlingTests.cs
index 4c344e29bfafc..53dba670d5fe6 100644
--- a/dotnet/test/webdriver/SessionHandlingTests.cs
+++ b/dotnet/test/webdriver/SessionHandlingTests.cs
@@ -17,7 +17,6 @@
// under the License.
//
-using OpenQA.Selenium.Testing.NUnit.Environment;
namespace OpenQA.Selenium.Tests;
@@ -31,7 +30,7 @@ public void CallingQuitMoreThanOnceOnASessionIsANoOp()
Driver.Url = Urls.SimpleTestPage;
Driver.Quit();
Driver.Quit();
- Driver = EnvironmentManager.Instance.CreateDriverInstance();
+ Driver = CreateDriverInstance();
Driver.Url = Urls.XhtmlTestPage;
Driver.Quit();
}
@@ -40,12 +39,12 @@ public void CallingQuitMoreThanOnceOnASessionIsANoOp()
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void CallingQuitAfterClosingTheLastWindowIsANoOp()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
- IWebDriver testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ CloseDriver();
+ IWebDriver testDriver = CreateDriverInstance();
testDriver.Url = Urls.SimpleTestPage;
testDriver.Close();
testDriver.Quit();
- testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ testDriver = CreateDriverInstance();
testDriver.Url = Urls.XhtmlTestPage;
Assert.That(testDriver.Title, Is.EqualTo("XHTML Test Page"));
testDriver.Quit();
@@ -56,8 +55,8 @@ public void CallingQuitAfterClosingTheLastWindowIsANoOp()
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void CallingAnyOperationAfterClosingTheLastWindowShouldThrowAnException()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
- IWebDriver testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ CloseDriver();
+ IWebDriver testDriver = CreateDriverInstance();
try
{
string url = string.Empty;
@@ -75,8 +74,8 @@ public void CallingAnyOperationAfterClosingTheLastWindowShouldThrowAnException()
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void CallingAnyOperationAfterQuitShouldThrowAnException()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
- IWebDriver testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ CloseDriver();
+ IWebDriver testDriver = CreateDriverInstance();
try
{
string url = string.Empty;
@@ -97,12 +96,12 @@ public void CallingAnyOperationAfterQuitShouldThrowAnException()
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void ShouldBeAbleToStartNewDriverAfterCallingCloseOnOnlyOpenWindow()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
- IWebDriver testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ CloseDriver();
+ IWebDriver testDriver = CreateDriverInstance();
testDriver.Url = Urls.SimpleTestPage;
testDriver.Close();
testDriver.Dispose();
- testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ testDriver = CreateDriverInstance();
testDriver.Url = Urls.XhtmlTestPage;
Assert.That(testDriver.Title, Is.EqualTo("XHTML Test Page"));
testDriver.Close();
@@ -113,8 +112,8 @@ public void ShouldBeAbleToStartNewDriverAfterCallingCloseOnOnlyOpenWindow()
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void ShouldBeAbleToDisposeOfDriver()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
- IWebDriver testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ CloseDriver();
+ IWebDriver testDriver = CreateDriverInstance();
testDriver.Url = Urls.SimpleTestPage;
testDriver.Dispose();
}
@@ -123,8 +122,8 @@ public void ShouldBeAbleToDisposeOfDriver()
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void ShouldBeAbleToCallDisposeConsecutively()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
- IWebDriver testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ CloseDriver();
+ IWebDriver testDriver = CreateDriverInstance();
testDriver.Url = Urls.SimpleTestPage;
testDriver.Dispose();
testDriver.Dispose();
@@ -134,12 +133,12 @@ public void ShouldBeAbleToCallDisposeConsecutively()
[NeedsFreshDriver(IsCreatedAfterTest = true)]
public void ShouldBeAbleToCallDisposeAfterQuit()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
- IWebDriver testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ CloseDriver();
+ IWebDriver testDriver = CreateDriverInstance();
testDriver.Url = Urls.SimpleTestPage;
testDriver.Quit();
testDriver.Dispose();
- testDriver = EnvironmentManager.Instance.CreateDriverInstance();
+ testDriver = CreateDriverInstance();
testDriver.Url = Urls.XhtmlTestPage;
Assert.That(testDriver.Title, Is.EqualTo("XHTML Test Page"));
testDriver.Quit();
@@ -150,7 +149,6 @@ public void ShouldOpenAndCloseBrowserRepeatedly()
{
for (int i = 0; i < 5; i++)
{
- EnvironmentManager.Instance.CloseCurrentDriver();
CreateFreshDriver();
Driver.Url = Urls.SimpleTestPage;
Assert.That(Driver.Title, Is.EqualTo("Hello WebDriver"));
diff --git a/dotnet/test/webdriver/TimeoutDriverOptionsTests.cs b/dotnet/test/webdriver/TimeoutDriverOptionsTests.cs
index 755f4404bc52d..6299b3d3e33bd 100644
--- a/dotnet/test/webdriver/TimeoutDriverOptionsTests.cs
+++ b/dotnet/test/webdriver/TimeoutDriverOptionsTests.cs
@@ -24,6 +24,7 @@ namespace OpenQA.Selenium.Tests;
[TestFixture]
public class TimeoutDriverOptionsTests
{
+ private readonly DriverFactory driverFactory = new(EnvironmentManager.Instance);
private IWebDriver driver;
private readonly TimeSpan defaultScriptTimeout = TimeSpan.FromMilliseconds(30_000);
@@ -50,7 +51,7 @@ public void CanSetScriptTimeout()
Assert.That(options.PageLoadTimeout, Is.Null);
Assert.That(options.ImplicitWaitTimeout, Is.Null);
- driver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ driver = driverFactory.CreateDriver(options);
Assert.That(driver.Manage().Timeouts().AsynchronousJavaScript, Is.EqualTo(expectedScriptTimeout));
@@ -73,7 +74,7 @@ public void CanSetPageLoadTimeout()
Assert.That(options.ScriptTimeout, Is.Null);
Assert.That(options.ImplicitWaitTimeout, Is.Null);
- driver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ driver = driverFactory.CreateDriver(options);
Assert.That(driver.Manage().Timeouts().PageLoad, Is.EqualTo(expectedPageLoadTimeout));
@@ -96,7 +97,7 @@ public void CanSetImplicitWaitTimeout()
Assert.That(options.ScriptTimeout, Is.Null);
Assert.That(options.PageLoadTimeout, Is.Null);
- driver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ driver = driverFactory.CreateDriver(options);
Assert.That(driver.Manage().Timeouts().ImplicitWait, Is.EqualTo(expectedImplicitWaitTimeout));
@@ -122,7 +123,7 @@ public void CanSetTimeout()
Assert.That(options.PageLoadTimeout, Is.EqualTo(expectedPageLoadTimeout));
Assert.That(options.ImplicitWaitTimeout, Is.EqualTo(expectedImplicitWaitTimeout));
- driver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ driver = driverFactory.CreateDriver(options);
Assert.That(driver.Manage().Timeouts().AsynchronousJavaScript, Is.EqualTo(expectedScriptTimeout));
Assert.That(driver.Manage().Timeouts().PageLoad, Is.EqualTo(expectedPageLoadTimeout));
diff --git a/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs b/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
index 585559a5982a9..f753796097301 100644
--- a/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
+++ b/dotnet/test/webdriver/UnexpectedAlertBehaviorTests.cs
@@ -17,8 +17,6 @@
// under the License.
//
-using OpenQA.Selenium.Testing.NUnit.Environment;
-
namespace OpenQA.Selenium.Tests;
[TestFixture]
@@ -29,7 +27,7 @@ public class UnexpectedAlertBehaviorTests : DriverTestFixture
[SetUp]
public void RestartOriginalDriver()
{
- EnvironmentManager.Instance.CloseCurrentDriver();
+ CloseDriver();
}
[TearDown]
@@ -41,7 +39,7 @@ public void QuitDriver()
localDriver = null;
}
- EnvironmentManager.Instance.CreateFreshDriver();
+ CreateFreshDriver();
}
[Test]
@@ -106,7 +104,7 @@ private void ExecuteTestWithUnhandledPrompt(UserPromptHandler behavior, string e
UnhandledPromptBehavior = behavior,
};
- localDriver = EnvironmentManager.Instance.CreateDriverInstance(options);
+ localDriver = CreateDriverInstance(options);
localDriver.Url = Urls.AlertsPage;
IWebElement resultElement = localDriver.FindElement(By.Id("text"));
localDriver.FindElement(By.Id("prompt-with-default")).Click();