Skip to content

Commit 6a48692

Browse files
titusfortnerdiemol
andauthored
[dotnet] Use Selenium Manager to locate drivers on PATH (#12344)
* [dotnet] use Selenium Manager to locate drivers on PATH * [dotnet] allow user to pass in full path to driver in Service class --------- Co-authored-by: Diego Molina <[email protected]>
1 parent 6176d7e commit 6a48692

11 files changed

+75
-77
lines changed

dotnet/src/webdriver/Chrome/ChromeDriverService.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@
1616
// limitations under the License.
1717
// </copyright>
1818

19-
using System;
20-
using OpenQA.Selenium.Internal;
19+
using System.IO;
2120
using OpenQA.Selenium.Chromium;
21+
using OpenQA.Selenium.Internal;
2222

2323
namespace OpenQA.Selenium.Chrome
2424
{
@@ -29,16 +29,14 @@ public sealed class ChromeDriverService : ChromiumDriverService
2929
{
3030
private const string DefaultChromeDriverServiceExecutableName = "chromedriver";
3131

32-
private static readonly Uri ChromeDriverDownloadUrl = new Uri("http://chromedriver.storage.googleapis.com/index.html");
33-
3432
/// <summary>
3533
/// Initializes a new instance of the <see cref="ChromeDriverService"/> class.
3634
/// </summary>
3735
/// <param name="executablePath">The full path to the ChromeDriver executable.</param>
3836
/// <param name="executableFileName">The file name of the ChromeDriver executable.</param>
3937
/// <param name="port">The port on which the ChromeDriver executable should listen.</param>
4038
private ChromeDriverService(string executablePath, string executableFileName, int port)
41-
: base(executablePath, executableFileName, port, ChromeDriverDownloadUrl)
39+
: base(executablePath, executableFileName, port)
4240
{
4341
}
4442

@@ -58,10 +56,8 @@ public static ChromeDriverService CreateDefaultService()
5856
/// <returns>A ChromeDriverService that implements default settings.</returns>
5957
public static ChromeDriverService CreateDefaultService(ChromeOptions options)
6058
{
61-
string serviceDirectory = DriverService.FindDriverServiceExecutable(ChromiumDriverServiceFileName(DefaultChromeDriverServiceExecutableName),
62-
ChromeDriverDownloadUrl);
63-
ChromeDriverService service = CreateDefaultService(serviceDirectory);
64-
return DriverFinder.VerifyDriverServicePath(service, options) as ChromeDriverService;;
59+
string fullServicePath = DriverFinder.FullPath(options);
60+
return CreateDefaultService(Path.GetDirectoryName(fullServicePath), Path.GetFileName(fullServicePath));
6561
}
6662

6763
/// <summary>
@@ -71,6 +67,11 @@ public static ChromeDriverService CreateDefaultService(ChromeOptions options)
7167
/// <returns>A ChromeDriverService using a random port.</returns>
7268
public static ChromeDriverService CreateDefaultService(string driverPath)
7369
{
70+
if (Path.GetFileName(driverPath).Contains(DefaultChromeDriverServiceExecutableName))
71+
{
72+
driverPath = Path.GetDirectoryName(driverPath);
73+
}
74+
7475
return CreateDefaultService(driverPath, ChromiumDriverServiceFileName(DefaultChromeDriverServiceExecutableName));
7576
}
7677

dotnet/src/webdriver/Chromium/ChromiumDriver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public class ChromiumDriver : WebDriver, ISupportsLogs, IDevTools
125125
/// <param name="options">The <see cref="ChromiumOptions"/> to be used with the ChromiumDriver.</param>
126126
/// <param name="commandTimeout">The maximum amount of time to wait for each command.</param>
127127
protected ChromiumDriver(ChromiumDriverService service, ChromiumOptions options, TimeSpan commandTimeout)
128-
: base(new DriverServiceCommandExecutor(DriverFinder.VerifyDriverServicePath(service, options), commandTimeout), ConvertOptionsToCapabilities(options))
128+
: base(new DriverServiceCommandExecutor(service, commandTimeout), ConvertOptionsToCapabilities(options))
129129
{
130130
this.optionsCapabilityName = options.CapabilityName;
131131
}

dotnet/src/webdriver/Chromium/ChromiumDriverService.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,8 @@ public abstract class ChromiumDriverService : DriverService
4545
/// <param name="executablePath">The full path to the ChromeDriver executable.</param>
4646
/// <param name="executableFileName">The file name of the ChromeDriver executable.</param>
4747
/// <param name="port">The port on which the ChromeDriver executable should listen.</param>
48-
/// <param name="downloadUrl">The url that ChromiumDriver should be downloaded from.</param>
49-
protected ChromiumDriverService(string executablePath, string executableFileName, int port, Uri downloadUrl)
50-
: base(executablePath, port, executableFileName, downloadUrl)
48+
protected ChromiumDriverService(string executablePath, string executableFileName, int port, Uri downloadUrl = null)
49+
: base(executablePath, port, executableFileName)
5150
{
5251
}
5352

dotnet/src/webdriver/DriverFinder.cs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,31 +28,39 @@ namespace OpenQA.Selenium
2828
public static class DriverFinder
2929
{
3030
/// <summary>
31-
/// Checks if the driver path exists, else uses Selenium Manager to return it.
31+
/// Use Selenium Manager to locate the driver
3232
/// </summary>
33-
/// <param name="service">DriverService with the current path.</param>
3433
/// <param name="options">DriverOptions with the current browser options.</param>
3534
/// <returns>
36-
/// The service with a verified driver executable path.
35+
/// The full path and name of the driver
3736
/// </returns>
38-
public static DriverService VerifyDriverServicePath(DriverService service, DriverOptions options)
37+
/// <exception cref="NoSuchDriverException"></exception>
38+
public static string FullPath(DriverOptions options)
3939
{
40-
string executablePath = Path.Combine(service.DriverServicePath, service.DriverServiceExecutableName);
41-
if (File.Exists(executablePath)) return service;
40+
string executablePath;
4241
try
4342
{
4443
executablePath = SeleniumManager.DriverPath(options);
45-
service.DriverServicePath = Path.GetDirectoryName(executablePath);
46-
service.DriverServiceExecutableName = Path.GetFileName(executablePath);
4744
}
4845
catch (Exception e)
4946
{
50-
throw new NoSuchDriverException($"Unable to obtain {service.DriverServiceExecutableName} using Selenium Manager", e);
47+
throw new NoSuchDriverException($"Unable to obtain {options.BrowserName} using Selenium Manager", e);
5148
}
5249

53-
if (File.Exists(executablePath)) return service;
50+
string message;
51+
if (executablePath == null)
52+
{
53+
message = $"Unable to locate or obtain {options.BrowserName} driver";
54+
} else if (!File.Exists(executablePath))
55+
{
56+
message = $"{options.BrowserName} driver located at {executablePath}, but invalid";
57+
}
58+
else
59+
{
60+
return executablePath;
61+
}
5462

55-
throw new NoSuchDriverException($"Unable to locate or obtain {service.DriverServiceExecutableName}");
63+
throw new NoSuchDriverException(message);
5664
}
5765
}
5866
}

dotnet/src/webdriver/DriverService.cs

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,14 @@ public abstract class DriverService : ICommandServer
4949
/// <param name="servicePath">The full path to the directory containing the executable providing the service to drive the browser.</param>
5050
/// <param name="port">The port on which the driver executable should listen.</param>
5151
/// <param name="driverServiceExecutableName">The file name of the driver service executable.</param>
52-
/// <param name="driverServiceDownloadUrl">A URL at which the driver service executable may be downloaded.</param>
52+
/// <param name="driverServiceDownloadUrl">This parameter is no longer used; kept for backwards compatibility.</param>
5353
/// <exception cref="ArgumentException">
5454
/// If the path specified is <see langword="null"/> or an empty string.
5555
/// </exception>
5656
/// <exception cref="DriverServiceNotFoundException">
5757
/// If the specified driver service executable does not exist in the specified directory.
5858
/// </exception>
59-
protected DriverService(string servicePath, int port, string driverServiceExecutableName, Uri driverServiceDownloadUrl)
59+
protected DriverService(string servicePath, int port, string driverServiceExecutableName, Uri driverServiceDownloadUrl = null)
6060
{
6161
this.driverServicePath = servicePath;
6262
this.driverServiceExecutableName = driverServiceExecutableName;
@@ -284,20 +284,6 @@ public void Start()
284284
}
285285
}
286286

287-
/// <summary>
288-
/// Finds the specified driver service executable.
289-
/// </summary>
290-
/// <param name="executableName">The file name of the executable to find.</param>
291-
/// <param name="downloadUrl">A URL at which the driver service executable may be downloaded.</param>
292-
/// <returns>The directory containing the driver service executable.</returns>
293-
/// <exception cref="DriverServiceNotFoundException">
294-
/// If the specified driver service executable does not exist in the current directory or in a directory on the system path.
295-
/// </exception>
296-
protected static string FindDriverServiceExecutable(string executableName, Uri downloadUrl)
297-
{
298-
return FileUtilities.FindFile(executableName);
299-
}
300-
301287
/// <summary>
302288
/// Releases all resources associated with this <see cref="DriverService"/>.
303289
/// </summary>

dotnet/src/webdriver/Edge/EdgeDriverService.cs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,9 @@
1616
// limitations under the License.
1717
// </copyright>
1818

19-
using System;
20-
using System.Globalization;
21-
using System.Text;
22-
using OpenQA.Selenium.Internal;
19+
using System.IO;
2320
using OpenQA.Selenium.Chromium;
21+
using OpenQA.Selenium.Internal;
2422

2523
namespace OpenQA.Selenium.Edge
2624
{
@@ -31,16 +29,14 @@ public sealed class EdgeDriverService : ChromiumDriverService
3129
{
3230
private const string MSEdgeDriverServiceFileName = "msedgedriver";
3331

34-
private static readonly Uri MicrosoftWebDriverDownloadUrl = new Uri("https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/");
35-
3632
/// <summary>
3733
/// Initializes a new instance of the <see cref="EdgeDriverService"/> class.
3834
/// </summary>
3935
/// <param name="executablePath">The full path to the EdgeDriver executable.</param>
4036
/// <param name="executableFileName">The file name of the EdgeDriver executable.</param>
4137
/// <param name="port">The port on which the EdgeDriver executable should listen.</param>
4238
private EdgeDriverService(string executablePath, string executableFileName, int port)
43-
: base(executablePath, executableFileName, port, MicrosoftWebDriverDownloadUrl)
39+
: base(executablePath, executableFileName, port)
4440
{
4541
}
4642

@@ -69,10 +65,8 @@ public static EdgeDriverService CreateDefaultService()
6965
/// <returns>A EdgeDriverService that implements default settings.</returns>
7066
public static EdgeDriverService CreateDefaultService(EdgeOptions options)
7167
{
72-
string serviceDirectory = DriverService.FindDriverServiceExecutable(ChromiumDriverServiceFileName(MSEdgeDriverServiceFileName),
73-
MicrosoftWebDriverDownloadUrl);
74-
EdgeDriverService service = CreateDefaultService(serviceDirectory);
75-
return DriverFinder.VerifyDriverServicePath(service, options) as EdgeDriverService;
68+
string fullServicePath = DriverFinder.FullPath(options);
69+
return CreateDefaultService(Path.GetDirectoryName(fullServicePath), Path.GetFileName(fullServicePath));
7670
}
7771

7872
/// <summary>
@@ -82,6 +76,11 @@ public static EdgeDriverService CreateDefaultService(EdgeOptions options)
8276
/// <returns>An EdgeDriverService using a random port.</returns>
8377
public static EdgeDriverService CreateDefaultService(string driverPath)
8478
{
79+
if (Path.GetFileName(driverPath).Contains(MSEdgeDriverServiceFileName))
80+
{
81+
driverPath = Path.GetDirectoryName(driverPath);
82+
}
83+
8584
return CreateDefaultService(driverPath, ChromiumDriverServiceFileName(MSEdgeDriverServiceFileName));
8685
}
8786

dotnet/src/webdriver/Firefox/FirefoxDriver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ public FirefoxDriver(FirefoxDriverService service, FirefoxOptions options)
186186
/// <param name="options">The <see cref="FirefoxOptions"/> to be used with the Firefox driver.</param>
187187
/// <param name="commandTimeout">The maximum amount of time to wait for each command.</param>
188188
public FirefoxDriver(FirefoxDriverService service, FirefoxOptions options, TimeSpan commandTimeout)
189-
: base(new DriverServiceCommandExecutor(DriverFinder.VerifyDriverServicePath(service, options), commandTimeout), ConvertOptionsToCapabilities(options))
189+
: base(new DriverServiceCommandExecutor(service, commandTimeout), ConvertOptionsToCapabilities(options))
190190
{
191191
// Add the custom commands unique to Firefox
192192
this.AddCustomFirefoxCommands();

dotnet/src/webdriver/Firefox/FirefoxDriverService.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
using System;
2020
using System.Globalization;
21-
using System.Net;
21+
using System.IO;
2222
using System.Text;
2323
using OpenQA.Selenium.Internal;
2424

@@ -30,7 +30,6 @@ namespace OpenQA.Selenium.Firefox
3030
public sealed class FirefoxDriverService : DriverService
3131
{
3232
private const string DefaultFirefoxDriverServiceFileName = "geckodriver";
33-
private static readonly Uri FirefoxDriverDownloadUrl = new Uri("https://github.com/mozilla/geckodriver/releases");
3433

3534
private bool connectToRunningBrowser;
3635
private bool openBrowserToolbox;
@@ -47,7 +46,7 @@ public sealed class FirefoxDriverService : DriverService
4746
/// <param name="executableFileName">The file name of the Firefox driver executable.</param>
4847
/// <param name="port">The port on which the Firefox driver executable should listen.</param>
4948
private FirefoxDriverService(string executablePath, string executableFileName, int port)
50-
: base(executablePath, port, executableFileName, FirefoxDriverDownloadUrl)
49+
: base(executablePath, port, executableFileName)
5150
{
5251
}
5352

@@ -220,9 +219,8 @@ public static FirefoxDriverService CreateDefaultService()
220219
/// <returns>A FirefoxDriverService that implements default settings.</returns>
221220
public static FirefoxDriverService CreateDefaultService(FirefoxOptions options)
222221
{
223-
string serviceDirectory = DriverService.FindDriverServiceExecutable(FirefoxDriverServiceFileName(), FirefoxDriverDownloadUrl);
224-
FirefoxDriverService service = CreateDefaultService(serviceDirectory);
225-
return DriverFinder.VerifyDriverServicePath(service, options) as FirefoxDriverService;
222+
string fullServicePath = DriverFinder.FullPath(options);
223+
return CreateDefaultService(Path.GetDirectoryName(fullServicePath), Path.GetFileName(fullServicePath));
226224
}
227225

228226
/// <summary>
@@ -232,6 +230,11 @@ public static FirefoxDriverService CreateDefaultService(FirefoxOptions options)
232230
/// <returns>A FirefoxDriverService using a random port.</returns>
233231
public static FirefoxDriverService CreateDefaultService(string driverPath)
234232
{
233+
if (Path.GetFileName(driverPath) == FirefoxDriverServiceFileName())
234+
{
235+
driverPath = Path.GetDirectoryName(driverPath);
236+
}
237+
235238
return CreateDefaultService(driverPath, FirefoxDriverServiceFileName());
236239
}
237240

dotnet/src/webdriver/IE/InternetExplorerDriver.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ public InternetExplorerDriver(InternetExplorerDriverService service, InternetExp
140140
/// <param name="options">The <see cref="InternetExplorerOptions"/> used to initialize the driver.</param>
141141
/// <param name="commandTimeout">The maximum amount of time to wait for each command.</param>
142142
public InternetExplorerDriver(InternetExplorerDriverService service, InternetExplorerOptions options, TimeSpan commandTimeout)
143-
: base(new DriverServiceCommandExecutor(DriverFinder.VerifyDriverServicePath(service, options), commandTimeout), ConvertOptionsToCapabilities(options))
143+
: base(new DriverServiceCommandExecutor(service, commandTimeout), ConvertOptionsToCapabilities(options))
144144
{
145145
}
146146

dotnet/src/webdriver/IE/InternetExplorerDriverService.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616
// limitations under the License.
1717
// </copyright>
1818

19-
using System;
2019
using System.Globalization;
20+
using System.IO;
2121
using System.Text;
2222
using OpenQA.Selenium.Internal;
2323

@@ -29,7 +29,6 @@ namespace OpenQA.Selenium.IE
2929
public sealed class InternetExplorerDriverService : DriverService
3030
{
3131
private const string InternetExplorerDriverServiceFileName = "IEDriverServer.exe";
32-
private static readonly Uri InternetExplorerDriverDownloadUrl = new Uri("https://www.selenium.dev/downloads/");
3332

3433
private InternetExplorerDriverLogLevel loggingLevel = InternetExplorerDriverLogLevel.Fatal;
3534
private string host = string.Empty;
@@ -44,7 +43,7 @@ public sealed class InternetExplorerDriverService : DriverService
4443
/// <param name="executableFileName">The file name of the IEDriverServer executable.</param>
4544
/// <param name="port">The port on which the IEDriverServer executable should listen.</param>
4645
private InternetExplorerDriverService(string executablePath, string executableFileName, int port)
47-
: base(executablePath, port, executableFileName, InternetExplorerDriverDownloadUrl)
46+
: base(executablePath, port, executableFileName)
4847
{
4948
}
5049

@@ -159,9 +158,8 @@ public static InternetExplorerDriverService CreateDefaultService()
159158
/// <returns>A InternetExplorerDriverService that implements default settings.</returns>
160159
public static InternetExplorerDriverService CreateDefaultService(InternetExplorerOptions options)
161160
{
162-
string serviceDirectory = DriverService.FindDriverServiceExecutable(InternetExplorerDriverServiceFileName, InternetExplorerDriverDownloadUrl);
163-
InternetExplorerDriverService service = CreateDefaultService(serviceDirectory);
164-
return DriverFinder.VerifyDriverServicePath(service, options) as InternetExplorerDriverService;
161+
string fullServicePath = DriverFinder.FullPath(options);
162+
return CreateDefaultService(Path.GetDirectoryName(fullServicePath), Path.GetFileName(fullServicePath));
165163
}
166164

167165
/// <summary>
@@ -171,6 +169,11 @@ public static InternetExplorerDriverService CreateDefaultService(InternetExplore
171169
/// <returns>A InternetExplorerDriverService using a random port.</returns>
172170
public static InternetExplorerDriverService CreateDefaultService(string driverPath)
173171
{
172+
if (Path.GetFileName(driverPath) == InternetExplorerDriverServiceFileName)
173+
{
174+
driverPath = Path.GetDirectoryName(driverPath);
175+
}
176+
174177
return CreateDefaultService(driverPath, InternetExplorerDriverServiceFileName);
175178
}
176179

0 commit comments

Comments
 (0)