diff --git a/dotnet/src/support/BUILD.bazel b/dotnet/src/support/BUILD.bazel
index b4251681c8452..19d8a5d896384 100644
--- a/dotnet/src/support/BUILD.bazel
+++ b/dotnet/src/support/BUILD.bazel
@@ -3,6 +3,7 @@ load(
"csharp_library",
"generated_assembly_info",
"nuget_pack",
+ "nuget_package",
)
load(
"//dotnet:selenium-dotnet-version.bzl",
@@ -44,6 +45,8 @@ csharp_library(
],
deps = [
"//dotnet/src/webdriver:webdriver-netstandard2.0",
+ nuget_package("Microsoft.Bcl.AsyncInterfaces"),
+ nuget_package("System.Threading.Tasks.Extensions"),
],
)
@@ -84,6 +87,8 @@ csharp_library(
],
deps = [
"//dotnet/src/webdriver:webdriver-netstandard2.0-strongnamed",
+ nuget_package("Microsoft.Bcl.AsyncInterfaces"),
+ nuget_package("System.Threading.Tasks.Extensions"),
],
)
diff --git a/dotnet/src/support/Events/EventFiringWebDriver.cs b/dotnet/src/support/Events/EventFiringWebDriver.cs
index 70b69589f7500..9933064e8871f 100644
--- a/dotnet/src/support/Events/EventFiringWebDriver.cs
+++ b/dotnet/src/support/Events/EventFiringWebDriver.cs
@@ -405,6 +405,38 @@ public void Dispose()
GC.SuppressFinalize(this);
}
+ ///
+ /// Asynchronously disposes this instance.
+ ///
+ /// A task representing the asynchronous dispose operation.
+ public async ValueTask DisposeAsync()
+ {
+ await this.DisposeAsyncCore().ConfigureAwait(false);
+ this.Dispose(false);
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Stops the client from running.
+ ///
+ /// If , managed resources are disposed.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ WrappedDriver.Dispose();
+ }
+ }
+
+ ///
+ /// Asynchronously performs the core dispose logic.
+ ///
+ /// A task representing the asynchronous dispose operation.
+ protected virtual async ValueTask DisposeAsyncCore()
+ {
+ await WrappedDriver.DisposeAsync().ConfigureAwait(false);
+ }
+
///
/// Executes JavaScript in the context of the currently selected frame or window.
///
@@ -580,19 +612,6 @@ public Screenshot GetScreenshot()
return screenshotDriver.GetScreenshot();
}
- ///
- /// Frees all managed and, optionally, unmanaged resources used by this instance.
- ///
- /// to dispose of only managed resources;
- /// to dispose of managed and unmanaged resources.
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- this.WrappedDriver.Dispose();
- }
- }
-
///
/// Raises the event.
///
diff --git a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
index 8857f5229b254..71f864f771513 100644
--- a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
+++ b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs
@@ -480,9 +480,9 @@ public void StopCasting(string deviceName)
}
///
- /// Stops the driver from running
+ /// Disposes of the resources used by the instance, including any active DevTools session.
///
- /// if its in the process of disposing
+ /// Indicates whether the method is being called from a Dispose method (true) or from a finalizer (false).
protected override void Dispose(bool disposing)
{
if (disposing)
@@ -497,6 +497,21 @@ protected override void Dispose(bool disposing)
base.Dispose(disposing);
}
+ ///
+ /// Asynchronously disposes of the resources used by the instance, including any active DevTools session.
+ ///
+ /// A task representing the asynchronous dispose operation.
+ protected override async ValueTask DisposeAsyncCore()
+ {
+ if (this.devToolsSession != null)
+ {
+ this.devToolsSession.Dispose();
+ this.devToolsSession = null;
+ }
+
+ await base.DisposeAsyncCore().ConfigureAwait(false);
+ }
+
private static ICapabilities ConvertOptionsToCapabilities(ChromiumOptions options)
{
if (options == null)
diff --git a/dotnet/src/webdriver/Firefox/FirefoxDriver.cs b/dotnet/src/webdriver/Firefox/FirefoxDriver.cs
index 0573d2ed368e7..fd4d58c049eb5 100644
--- a/dotnet/src/webdriver/Firefox/FirefoxDriver.cs
+++ b/dotnet/src/webdriver/Firefox/FirefoxDriver.cs
@@ -414,17 +414,6 @@ protected virtual void PrepareEnvironment()
// Does nothing, but provides a hook for subclasses to do "stuff"
}
- ///
- /// Disposes of the FirefoxDriver and frees all resources.
- ///
- /// A value indicating whether the user initiated the
- /// disposal of the object. Pass if the user is actively
- /// disposing the object; otherwise .
- protected override void Dispose(bool disposing)
- {
- base.Dispose(disposing);
- }
-
private static ICapabilities ConvertOptionsToCapabilities(FirefoxOptions options)
{
if (options == null)
diff --git a/dotnet/src/webdriver/IWebDriver.cs b/dotnet/src/webdriver/IWebDriver.cs
index 7a92363acbaa3..9177ae81098a1 100644
--- a/dotnet/src/webdriver/IWebDriver.cs
+++ b/dotnet/src/webdriver/IWebDriver.cs
@@ -43,7 +43,7 @@ namespace OpenQA.Selenium;
/// more fully featured browser when there is a requirement for one.
///
///
-public interface IWebDriver : ISearchContext, IDisposable
+public interface IWebDriver : ISearchContext, IDisposable, IAsyncDisposable
{
///
/// Gets or sets the URL the browser is currently displaying.
diff --git a/dotnet/src/webdriver/WebDriver.cs b/dotnet/src/webdriver/WebDriver.cs
index 78c76f08ebadb..0df8343313859 100644
--- a/dotnet/src/webdriver/WebDriver.cs
+++ b/dotnet/src/webdriver/WebDriver.cs
@@ -223,6 +223,17 @@ public void Dispose()
GC.SuppressFinalize(this);
}
+ ///
+ /// Asynchronously disposes the WebDriver Instance
+ ///
+ /// A task representing the asynchronous dispose operation.
+ public async ValueTask DisposeAsync()
+ {
+ await this.DisposeAsyncCore().ConfigureAwait(false);
+ this.Dispose(false);
+ GC.SuppressFinalize(this);
+ }
+
///
/// Executes JavaScript "asynchronously" in the context of the currently selected frame or window,
/// executing the callback function specified as the last argument in the list of arguments.
@@ -672,25 +683,60 @@ protected bool RegisterInternalDriverCommand(string commandName, [NotNullWhen(tr
/// if its in the process of disposing
protected virtual void Dispose(bool disposing)
{
- try
+ if (disposing)
{
if (this.SessionId is not null)
{
- this.Execute(DriverCommand.Quit, null);
+ try
+ {
+
+ this.Execute(DriverCommand.Quit, null);
+
+ }
+ catch (NotImplementedException)
+ {
+ }
+ catch (InvalidOperationException)
+ {
+ }
+ catch (WebDriverException)
+ {
+ }
+ finally
+ {
+ this.SessionId = null!;
+ }
}
+
+ this.CommandExecutor.Dispose();
}
- catch (NotImplementedException)
- {
- }
- catch (InvalidOperationException)
- {
- }
- catch (WebDriverException)
- {
- }
- finally
+ }
+
+ ///
+ /// Asynchronously performs the core dispose logic.
+ ///
+ /// A task representing the asynchronous dispose operation.
+ protected virtual async ValueTask DisposeAsyncCore()
+ {
+ if (this.SessionId is not null)
{
- this.SessionId = null!;
+ try
+ {
+ await this.ExecuteAsync(DriverCommand.Quit, null).ConfigureAwait(false);
+ }
+ catch (NotImplementedException)
+ {
+ }
+ catch (InvalidOperationException)
+ {
+ }
+ catch (WebDriverException)
+ {
+ }
+ finally
+ {
+ this.SessionId = null!;
+ }
}
this.CommandExecutor.Dispose();
diff --git a/dotnet/src/webdriver/assets/nuget/README.md b/dotnet/src/webdriver/assets/nuget/README.md
index e780243d3445b..e05cb38ab350b 100644
--- a/dotnet/src/webdriver/assets/nuget/README.md
+++ b/dotnet/src/webdriver/assets/nuget/README.md
@@ -6,7 +6,7 @@ Selenium is a set of different software tools each with a different approach to
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium;
-using var driver = new ChromeDriver();
+await using var driver = new ChromeDriver();
driver.Url = "https://www.google.com";
driver.FindElement(By.Name("q")).SendKeys("webdriver" + Keys.Return);
diff --git a/dotnet/test/common/StubDriver.cs b/dotnet/test/common/StubDriver.cs
index 9f14206c40196..64d6cfa821fa4 100644
--- a/dotnet/test/common/StubDriver.cs
+++ b/dotnet/test/common/StubDriver.cs
@@ -19,6 +19,7 @@
using System;
using System.Collections.ObjectModel;
+using System.Threading.Tasks;
namespace OpenQA.Selenium;
@@ -101,4 +102,13 @@ public void Dispose()
}
#endregion
+
+ #region IAsyncDisposable Members
+
+ public ValueTask DisposeAsync()
+ {
+ throw new NotImplementedException();
+ }
+
+ #endregion
}
diff --git a/dotnet/test/support/Events/BUILD.bazel b/dotnet/test/support/Events/BUILD.bazel
index 060534a69a7bc..593314776f691 100644
--- a/dotnet/test/support/Events/BUILD.bazel
+++ b/dotnet/test/support/Events/BUILD.bazel
@@ -13,6 +13,7 @@ dotnet_nunit_test_suite(
"//dotnet/src/support",
"//dotnet/src/webdriver:webdriver-net8.0",
"//dotnet/test/common:fixtures",
+ nuget_package("Microsoft.Bcl.AsyncInterfaces"),
nuget_package("NUnit"),
nuget_package("Moq"),
],
diff --git a/dotnet/test/support/Selenium.WebDriver.Support.Tests.csproj b/dotnet/test/support/Selenium.WebDriver.Support.Tests.csproj
index be6aaef57a009..036e08d4bfd77 100644
--- a/dotnet/test/support/Selenium.WebDriver.Support.Tests.csproj
+++ b/dotnet/test/support/Selenium.WebDriver.Support.Tests.csproj
@@ -6,6 +6,7 @@
+
@@ -13,7 +14,6 @@
-