diff --git a/dotnet/src/webdriver/Chrome/ChromeDriver.cs b/dotnet/src/webdriver/Chrome/ChromeDriver.cs index 520bbf8aa80b5..c43f86a7742da 100644 --- a/dotnet/src/webdriver/Chrome/ChromeDriver.cs +++ b/dotnet/src/webdriver/Chrome/ChromeDriver.cs @@ -125,7 +125,7 @@ public ChromeDriver(string chromeDriverDirectory, ChromeOptions options) /// The to be used with the Chrome driver. /// The maximum amount of time to wait for each command. public ChromeDriver(string chromeDriverDirectory, ChromeOptions options, TimeSpan commandTimeout) - : this(ChromeDriverService.CreateDefaultService(chromeDriverDirectory), options, commandTimeout) + : this(ChromeDriverService.CreateDefaultService(chromeDriverDirectory), options, commandTimeout, disposeService: true) { } @@ -136,7 +136,12 @@ public ChromeDriver(string chromeDriverDirectory, ChromeOptions options, TimeSpa /// The to use. /// The used to initialize the driver. public ChromeDriver(ChromeDriverService service, ChromeOptions options) - : this(service, options, RemoteWebDriver.DefaultCommandTimeout) + : this(service, options, RemoteWebDriver.DefaultCommandTimeout, disposeService: true) + { + } + + public ChromeDriver(ChromeDriverService service, ChromeOptions options, bool disposeService) + : this(service, options, RemoteWebDriver.DefaultCommandTimeout, disposeService) { } @@ -147,7 +152,13 @@ public ChromeDriver(ChromeDriverService service, ChromeOptions options) /// The to be used with the Chrome driver. /// The maximum amount of time to wait for each command. public ChromeDriver(ChromeDriverService service, ChromeOptions options, TimeSpan commandTimeout) - : base(service, options, commandTimeout) + : base(service, options, commandTimeout, disposeService: true) + { + this.AddCustomChromeCommands(); + } + + public ChromeDriver(ChromeDriverService service, ChromeOptions options, TimeSpan commandTimeout, bool disposeService) + : base(service, options, commandTimeout, disposeService) { this.AddCustomChromeCommands(); } diff --git a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs index d4e3306053215..d2be432407d23 100644 --- a/dotnet/src/webdriver/Chromium/ChromiumDriver.cs +++ b/dotnet/src/webdriver/Chromium/ChromiumDriver.cs @@ -106,6 +106,8 @@ public class ChromiumDriver : WebDriver, ISupportsLogs, IDevTools /// public static readonly string SetPermissionCommand = "setPermission"; + private readonly ChromiumDriverService driverService; + private readonly bool disposeDriverService; private readonly string optionsCapabilityName; private DevToolsSession devToolsSession; @@ -126,9 +128,11 @@ public class ChromiumDriver : WebDriver, ISupportsLogs, IDevTools /// The to use. /// The to be used with the ChromiumDriver. /// The maximum amount of time to wait for each command. - protected ChromiumDriver(ChromiumDriverService service, ChromiumOptions options, TimeSpan commandTimeout) - : base(GenerateDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options)) + protected ChromiumDriver(ChromiumDriverService service, ChromiumOptions options, TimeSpan commandTimeout, bool disposeService) + : base(StartDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options)) { + this.driverService = service; + this.disposeDriverService = disposeService; this.optionsCapabilityName = options.CapabilityName; } @@ -140,14 +144,7 @@ protected static IReadOnlyDictionary ChromiumCustomCommands get { return new ReadOnlyDictionary(chromiumCustomCommands); } } - /// - /// Uses DriverFinder to set Service attributes if necessary when creating the command executor - /// - /// - /// - /// - /// - private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) + private static ICommandExecutor StartDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) { if (service.DriverServicePath == null) { @@ -161,7 +158,10 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi options.BrowserVersion = null; } } - return new DriverServiceCommandExecutor(service, commandTimeout); + + service.Start(); + + return new HttpCommandExecutor(service.ServiceUrl, commandTimeout); } /// @@ -471,6 +471,11 @@ protected override void Dispose(bool disposing) } base.Dispose(disposing); + + if (this.disposeDriverService) + { + this.driverService?.Dispose(); + } } private static ICapabilities ConvertOptionsToCapabilities(ChromiumOptions options) diff --git a/dotnet/src/webdriver/Edge/EdgeDriver.cs b/dotnet/src/webdriver/Edge/EdgeDriver.cs index 3a55752489455..5cb20b0f90c34 100644 --- a/dotnet/src/webdriver/Edge/EdgeDriver.cs +++ b/dotnet/src/webdriver/Edge/EdgeDriver.cs @@ -117,7 +117,7 @@ public EdgeDriver(EdgeDriverService service, EdgeOptions options) /// The to be used with the Edge driver. /// The maximum amount of time to wait for each command. public EdgeDriver(EdgeDriverService service, EdgeOptions options, TimeSpan commandTimeout) - : base(service, options, commandTimeout) + : base(service, options, commandTimeout, disposeService: false) { this.AddCustomEdgeCommands(); } diff --git a/dotnet/src/webdriver/Firefox/FirefoxDriver.cs b/dotnet/src/webdriver/Firefox/FirefoxDriver.cs index 53452e02a917a..c3ecb5699008c 100644 --- a/dotnet/src/webdriver/Firefox/FirefoxDriver.cs +++ b/dotnet/src/webdriver/Firefox/FirefoxDriver.cs @@ -187,7 +187,7 @@ public FirefoxDriver(FirefoxDriverService service, FirefoxOptions options) /// The to be used with the Firefox driver. /// The maximum amount of time to wait for each command. public FirefoxDriver(FirefoxDriverService service, FirefoxOptions options, TimeSpan commandTimeout) - : base(GenerateDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options)) + : base(StartDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options)) { // Add the custom commands unique to Firefox this.AddCustomFirefoxCommands(); @@ -200,7 +200,7 @@ public FirefoxDriver(FirefoxDriverService service, FirefoxOptions options, TimeS /// /// /// - private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) + private static ICommandExecutor StartDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) { if (service.DriverServicePath == null) { @@ -214,7 +214,10 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi options.BrowserVersion = null; } } - return new DriverServiceCommandExecutor(service, commandTimeout); + + service.Start(); + + return new HttpCommandExecutor(service.ServiceUrl, commandTimeout); } /// diff --git a/dotnet/src/webdriver/IE/InternetExplorerDriver.cs b/dotnet/src/webdriver/IE/InternetExplorerDriver.cs index 48391331d4f0d..dc42d0588086b 100644 --- a/dotnet/src/webdriver/IE/InternetExplorerDriver.cs +++ b/dotnet/src/webdriver/IE/InternetExplorerDriver.cs @@ -141,7 +141,7 @@ public InternetExplorerDriver(InternetExplorerDriverService service, InternetExp /// The used to initialize the driver. /// The maximum amount of time to wait for each command. public InternetExplorerDriver(InternetExplorerDriverService service, InternetExplorerOptions options, TimeSpan commandTimeout) - : base(GenerateDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options)) + : base(StartDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options)) { } @@ -152,7 +152,7 @@ public InternetExplorerDriver(InternetExplorerDriverService service, InternetExp /// /// /// - private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) + private static ICommandExecutor StartDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) { if (service.DriverServicePath == null) { @@ -161,7 +161,10 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi service.DriverServicePath = Path.GetDirectoryName(fullServicePath); service.DriverServiceExecutableName = Path.GetFileName(fullServicePath); } - return new DriverServiceCommandExecutor(service, commandTimeout); + + service.Start(); + + return new HttpCommandExecutor(service.ServiceUrl, commandTimeout); } /// diff --git a/dotnet/src/webdriver/Remote/DriverServiceCommandExecutor.cs b/dotnet/src/webdriver/Remote/DriverServiceCommandExecutor.cs deleted file mode 100644 index 1e486ad96f98d..0000000000000 --- a/dotnet/src/webdriver/Remote/DriverServiceCommandExecutor.cs +++ /dev/null @@ -1,163 +0,0 @@ -// -// 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 System; -using System.Threading.Tasks; - -namespace OpenQA.Selenium.Remote -{ - /// - /// Provides a mechanism to execute commands on the browser - /// - public class DriverServiceCommandExecutor : ICommandExecutor - { - private DriverService service; - private HttpCommandExecutor internalExecutor; - private bool isDisposed; - - /// - /// Initializes a new instance of the class. - /// - /// The that drives the browser. - /// The maximum amount of time to wait for each command. - public DriverServiceCommandExecutor(DriverService driverService, TimeSpan commandTimeout) - : this(driverService, commandTimeout, true) - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The that drives the browser. - /// The maximum amount of time to wait for each command. - /// if the KeepAlive header should be sent - /// with HTTP requests; otherwise, . - public DriverServiceCommandExecutor(DriverService driverService, TimeSpan commandTimeout, bool enableKeepAlive) - { - this.service = driverService; - this.internalExecutor = new HttpCommandExecutor(driverService.ServiceUrl, commandTimeout, enableKeepAlive); - } - - /// - /// Initializes a new instance of the class. - /// - /// The that drives the browser. - /// The object used to execute commands, - /// communicating with the service via HTTP. - public DriverServiceCommandExecutor(DriverService service, HttpCommandExecutor commandExecutor) - { - this.service = service; - this.internalExecutor = commandExecutor; - } - - /// - /// Gets the object associated with this executor. - /// - //public CommandInfoRepository CommandInfoRepository - //{ - // get { return this.internalExecutor.CommandInfoRepository; } - //} - - public bool TryAddCommand(string commandName, CommandInfo info) - { - return this.internalExecutor.TryAddCommand(commandName, info); - } - - /// - /// Gets the that sends commands to the remote - /// end WebDriver implementation. - /// - public HttpCommandExecutor HttpExecutor - { - get { return this.internalExecutor; } - } - - /// - /// Executes a command - /// - /// The command you wish to execute - /// A response from the browser - public Response Execute(Command commandToExecute) - { - return Task.Run(() => this.ExecuteAsync(commandToExecute)).GetAwaiter().GetResult(); - } - - /// - /// Executes a command as an asynchronous task. - /// - /// The command you wish to execute - /// A task object representing the asynchronous operation - public async Task ExecuteAsync(Command commandToExecute) - { - if (commandToExecute == null) - { - throw new ArgumentNullException(nameof(commandToExecute), "Command to execute cannot be null"); - } - - Response toReturn = null; - if (commandToExecute.Name == DriverCommand.NewSession) - { - this.service.Start(); - } - - // Use a try-catch block to catch exceptions for the Quit - // command, so that we can get the finally block. - try - { - toReturn = await this.internalExecutor.ExecuteAsync(commandToExecute).ConfigureAwait(false); - } - finally - { - if (commandToExecute.Name == DriverCommand.Quit) - { - this.Dispose(); - } - } - - return toReturn; - } - - /// - /// Releases all resources used by the . - /// - public void Dispose() - { - this.Dispose(true); - } - - /// - /// Releases the unmanaged resources used by the and - /// optionally releases the managed resources. - /// - /// to release managed and resources; - /// to only release unmanaged resources. - protected virtual void Dispose(bool disposing) - { - if (!this.isDisposed) - { - if (disposing) - { - this.internalExecutor.Dispose(); - this.service.Dispose(); - } - - this.isDisposed = true; - } - } - } -} diff --git a/dotnet/src/webdriver/Safari/SafariDriver.cs b/dotnet/src/webdriver/Safari/SafariDriver.cs index 4c88e90685f55..636bf7c294ace 100644 --- a/dotnet/src/webdriver/Safari/SafariDriver.cs +++ b/dotnet/src/webdriver/Safari/SafariDriver.cs @@ -144,7 +144,7 @@ public SafariDriver(SafariDriverService service, SafariOptions options) /// The to be used with the Safari driver. /// The maximum amount of time to wait for each command. public SafariDriver(SafariDriverService service, SafariOptions options, TimeSpan commandTimeout) - : base(GenerateDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options)) + : base(StartDriverServiceCommandExecutor(service, options, commandTimeout), ConvertOptionsToCapabilities(options)) { this.AddCustomSafariCommand(AttachDebuggerCommand, HttpCommandInfo.PostCommand, "/session/{sessionId}/apple/attach_debugger"); this.AddCustomSafariCommand(GetPermissionsCommand, HttpCommandInfo.GetCommand, "/session/{sessionId}/apple/permissions"); @@ -158,7 +158,7 @@ public SafariDriver(SafariDriverService service, SafariOptions options, TimeSpan /// /// /// - private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) + private static ICommandExecutor StartDriverServiceCommandExecutor(DriverService service, DriverOptions options, TimeSpan commandTimeout) { if (service.DriverServicePath == null) { @@ -167,7 +167,10 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi service.DriverServicePath = Path.GetDirectoryName(fullServicePath); service.DriverServiceExecutableName = Path.GetFileName(fullServicePath); } - return new DriverServiceCommandExecutor(service, commandTimeout); + + service.Start(); + + return new HttpCommandExecutor(service.ServiceUrl, commandTimeout); } /// diff --git a/dotnet/src/webdriver/WebDriver.cs b/dotnet/src/webdriver/WebDriver.cs index 6125490529a39..21335318dd88d 100644 --- a/dotnet/src/webdriver/WebDriver.cs +++ b/dotnet/src/webdriver/WebDriver.cs @@ -728,6 +728,7 @@ protected virtual void Dispose(bool disposing) { this.sessionId = null; } + this.executor.Dispose(); } diff --git a/dotnet/test/common/Environment/DriverFactory.cs b/dotnet/test/common/Environment/DriverFactory.cs index 8ce615235dc7d..e367224a736db 100644 --- a/dotnet/test/common/Environment/DriverFactory.cs +++ b/dotnet/test/common/Environment/DriverFactory.cs @@ -155,7 +155,7 @@ public IWebDriver CreateDriverWithOptions(Type driverType, DriverOptions driverO } } - driver = (IWebDriver)Activator.CreateInstance(driverType); + driver = (IWebDriver)Activator.CreateInstance(driverType, service, true); return driver; } @@ -193,7 +193,6 @@ protected void OnDriverLaunching(DriverService service, DriverOptions options) return options; } - private T MergeOptions(object baseOptions, DriverOptions overriddenOptions) where T : DriverOptions, new() { // If the driver type has a static DefaultOptions property,