Skip to content

Commit f36b334

Browse files
authored
[dotnet] Making SeleniumManager a thin wrapper (#13833)
* [dotnet] Making SeleniumManager a thin wrapper Also moving things to the driver classes and DriverFinder. Logging warnings from Selenium Manager as well, and debug messages when that level is enabled. * [dotnet] Addressing PR comments
1 parent aa62f10 commit f36b334

File tree

7 files changed

+154
-67
lines changed

7 files changed

+154
-67
lines changed

dotnet/src/webdriver/Chromium/ChromiumDriver.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,15 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi
151151
{
152152
if (service.DriverServicePath == null)
153153
{
154-
string fullServicePath = DriverFinder.FullPath(options);
154+
DriverFinder finder = new DriverFinder(options);
155+
string fullServicePath = finder.DriverPath();
155156
service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
156157
service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
158+
if (finder.HasBrowserPath())
159+
{
160+
options.BinaryLocation = finder.BrowserPath();
161+
options.BrowserVersion = null;
162+
}
157163
}
158164
return new DriverServiceCommandExecutor(service, commandTimeout);
159165
}

dotnet/src/webdriver/DriverFinder.cs

Lines changed: 100 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,51 +17,131 @@
1717
// </copyright>
1818

1919
using System;
20+
using System.Collections.Generic;
21+
using System.Globalization;
2022
using System.IO;
23+
using System.Text;
2124

2225
namespace OpenQA.Selenium
2326
{
2427
/// <summary>
2528
/// Finds a driver, checks if the provided path exists, if not, Selenium Manager is used.
26-
/// This implementation is still in beta, and may change.
29+
/// This implementation is still in beta and may change.
2730
/// </summary>
28-
public static class DriverFinder
31+
public class DriverFinder
2932
{
33+
private DriverOptions options;
34+
private Dictionary<string, string> paths = new Dictionary<string, string>();
35+
private const string BrowserPathKey = "browser_path";
36+
private const string DriverPathKey = "driver_path";
37+
38+
/// <summary>
39+
/// Initializes a new instance of the <see cref="DriverFinder"/> class.
40+
/// </summary>
41+
public DriverFinder(DriverOptions options)
42+
{
43+
this.options = options;
44+
}
45+
3046
/// <summary>
31-
/// Use Selenium Manager to locate the driver
47+
/// Gets the browser path retrieved by Selenium Manager
3248
/// </summary>
33-
/// <param name="options">DriverOptions with the current browser options.</param>
3449
/// <returns>
35-
/// The full path and name of the driver
50+
/// The full browser path
3651
/// </returns>
37-
/// <exception cref="NoSuchDriverException"></exception>
38-
public static string FullPath(DriverOptions options)
52+
public string BrowserPath()
53+
{
54+
return BinaryPaths()[BrowserPathKey];
55+
}
56+
57+
/// <summary>
58+
/// Gets the driver path retrieved by Selenium Manager
59+
/// </summary>
60+
/// <returns>
61+
/// The full driver path
62+
/// </returns>
63+
public string DriverPath()
64+
{
65+
return BinaryPaths()[DriverPathKey];
66+
}
67+
68+
public bool HasBrowserPath()
69+
{
70+
return !string.IsNullOrWhiteSpace(BrowserPath());
71+
}
72+
73+
/// <summary>
74+
/// Invokes Selenium Manager to get the binaries paths and validates if they exist.
75+
/// </summary>
76+
/// <returns>
77+
/// A Dictionary with the validated browser and driver path.
78+
/// </returns>
79+
/// <exception cref="NoSuchDriverException">If one of the paths does not exist.</exception>
80+
private Dictionary<string, string> BinaryPaths()
3981
{
40-
string executablePath;
41-
try
82+
if (paths.ContainsKey(DriverPathKey) && !string.IsNullOrWhiteSpace(paths[DriverPathKey]))
4283
{
43-
executablePath = SeleniumManager.DriverPath(options);
84+
return paths;
4485
}
45-
catch (Exception e)
86+
Dictionary<string, string> binaryPaths = SeleniumManager.BinaryPaths(CreateArguments());
87+
string driverPath = binaryPaths[DriverPathKey];
88+
string browserPath = binaryPaths[BrowserPathKey];
89+
if (File.Exists(driverPath))
4690
{
47-
throw new NoSuchDriverException($"Unable to obtain {options.BrowserName} using Selenium Manager", e);
91+
paths.Add(DriverPathKey, driverPath);
4892
}
49-
50-
string message;
51-
if (executablePath == null)
93+
else
5294
{
53-
message = $"Unable to locate or obtain {options.BrowserName} driver";
95+
throw new NoSuchDriverException($"The driver path is not a valid file: {driverPath}");
5496
}
55-
else if (!File.Exists(executablePath))
97+
if (File.Exists(browserPath))
5698
{
57-
message = $"{options.BrowserName} driver located at {executablePath}, but invalid";
99+
paths.Add(BrowserPathKey, browserPath);
58100
}
59101
else
60102
{
61-
return executablePath;
103+
throw new NoSuchDriverException($"The browser path is not a valid file: {browserPath}");
104+
}
105+
return paths;
106+
}
107+
108+
/// <summary>
109+
/// Create arguments to invoke Selenium Manager
110+
/// </summary>
111+
/// <returns>
112+
/// A string with all arguments to invoke Selenium Manager
113+
/// </returns>
114+
/// <exception cref="NoSuchDriverException"></exception>
115+
private string CreateArguments()
116+
{
117+
StringBuilder argsBuilder = new StringBuilder();
118+
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --browser \"{0}\"", options.BrowserName);
119+
120+
if (!string.IsNullOrEmpty(options.BrowserVersion))
121+
{
122+
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --browser-version {0}", options.BrowserVersion);
62123
}
63124

64-
throw new NoSuchDriverException(message);
125+
string browserBinary = options.BinaryLocation;
126+
if (!string.IsNullOrEmpty(browserBinary))
127+
{
128+
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --browser-path \"{0}\"", browserBinary);
129+
}
130+
131+
if (options.Proxy != null)
132+
{
133+
if (options.Proxy.SslProxy != null)
134+
{
135+
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --proxy \"{0}\"", options.Proxy.SslProxy);
136+
}
137+
else if (options.Proxy.HttpProxy != null)
138+
{
139+
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --proxy \"{0}\"", options.Proxy.HttpProxy);
140+
}
141+
}
142+
143+
return argsBuilder.ToString();
65144
}
145+
66146
}
67147
}

dotnet/src/webdriver/DriverService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ public void Start()
275275
}
276276
else
277277
{
278-
this.driverServiceProcess.StartInfo.FileName = DriverFinder.FullPath(this.GetDefaultDriverOptions());
278+
this.driverServiceProcess.StartInfo.FileName = new DriverFinder(this.GetDefaultDriverOptions()).DriverPath();
279279
}
280280

281281
this.driverServiceProcess.StartInfo.Arguments = this.CommandLineArguments;

dotnet/src/webdriver/Firefox/FirefoxDriver.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,15 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi
204204
{
205205
if (service.DriverServicePath == null)
206206
{
207-
string fullServicePath = DriverFinder.FullPath(options);
207+
DriverFinder finder = new DriverFinder(options);
208+
string fullServicePath = finder.DriverPath();
208209
service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
209210
service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
211+
if (finder.HasBrowserPath())
212+
{
213+
options.BinaryLocation = finder.BrowserPath();
214+
options.BrowserVersion = null;
215+
}
210216
}
211217
return new DriverServiceCommandExecutor(service, commandTimeout);
212218
}

dotnet/src/webdriver/IE/InternetExplorerDriver.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi
156156
{
157157
if (service.DriverServicePath == null)
158158
{
159-
string fullServicePath = DriverFinder.FullPath(options);
159+
DriverFinder finder = new DriverFinder(options);
160+
string fullServicePath = finder.DriverPath();
160161
service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
161162
service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
162163
}

dotnet/src/webdriver/Safari/SafariDriver.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ private static ICommandExecutor GenerateDriverServiceCommandExecutor(DriverServi
162162
{
163163
if (service.DriverServicePath == null)
164164
{
165-
string fullServicePath = DriverFinder.FullPath(options);
165+
DriverFinder finder = new DriverFinder(options);
166+
string fullServicePath = finder.DriverPath();
166167
service.DriverServicePath = Path.GetDirectoryName(fullServicePath);
167168
service.DriverServiceExecutableName = Path.GetFileName(fullServicePath);
168169
}

dotnet/src/webdriver/SeleniumManager.cs

Lines changed: 35 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -71,62 +71,34 @@ static SeleniumManager()
7171
}
7272

7373
/// <summary>
74-
/// Determines the location of the correct driver.
74+
/// Determines the location of the browser and driver binaries.
7575
/// </summary>
76-
/// <param name="options">The correct path depends on which options are being used.</param>
76+
/// <param name="arguments">List of arguments to use when invoking Selenium Manager.</param>
7777
/// <returns>
78-
/// The location of the driver.
78+
/// An array with two entries, one for the driver path, and another one for the browser path.
7979
/// </returns>
80-
public static string DriverPath(DriverOptions options)
80+
public static Dictionary<string, string> BinaryPaths(string arguments)
8181
{
82-
StringBuilder argsBuilder = new StringBuilder();
83-
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --browser \"{0}\"", options.BrowserName);
82+
StringBuilder argsBuilder = new StringBuilder(arguments);
8483
argsBuilder.Append(" --language-binding csharp");
8584
argsBuilder.Append(" --output json");
86-
87-
if (!string.IsNullOrEmpty(options.BrowserVersion))
88-
{
89-
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --browser-version {0}", options.BrowserVersion);
90-
}
91-
92-
string browserBinary = options.BinaryLocation;
93-
if (!string.IsNullOrEmpty(browserBinary))
85+
if (_logger.IsEnabled(LogEventLevel.Debug))
9486
{
95-
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --browser-path \"{0}\"", browserBinary);
96-
}
97-
98-
if (options.Proxy != null)
99-
{
100-
if (options.Proxy.SslProxy != null)
101-
{
102-
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --proxy \"{0}\"", options.Proxy.SslProxy);
103-
}
104-
else if (options.Proxy.HttpProxy != null)
105-
{
106-
argsBuilder.AppendFormat(CultureInfo.InvariantCulture, " --proxy \"{0}\"", options.Proxy.HttpProxy);
107-
}
87+
argsBuilder.Append(" --debug");
10888
}
10989

11090
Dictionary<string, object> output = RunCommand(BinaryFullPath, argsBuilder.ToString());
111-
112-
try
113-
{
114-
options.BinaryLocation = (string)output["browser_path"] == "" ? null : (string)output["browser_path"];
115-
options.BrowserVersion = null;
116-
}
117-
catch (NotImplementedException)
118-
{
119-
// Cannot set Browser Location for this driver and that is ok
120-
}
121-
122-
var driverPath = (string)output["driver_path"];
91+
Dictionary<string, string> binaryPaths = new Dictionary<string, string>();
92+
binaryPaths.Add("browser_path", (string)output["browser_path"]);
93+
binaryPaths.Add("driver_path", (string)output["driver_path"]);
12394

12495
if (_logger.IsEnabled(LogEventLevel.Trace))
12596
{
126-
_logger.Trace($"Driver path: {driverPath}");
97+
_logger.Trace($"Driver path: {binaryPaths["driver_path"]}");
98+
_logger.Trace($"Browser path: {binaryPaths["browser_path"]}");
12799
}
128100

129-
return driverPath;
101+
return binaryPaths;
130102
}
131103

132104
/// <summary>
@@ -169,7 +141,7 @@ private static Dictionary<string, object> RunCommand(string fileName, string arg
169141

170142
if (process.ExitCode != 0)
171143
{
172-
// We do not log any warnings coming from Selenium Manager like the other bindings as we don't have any logging in the .NET bindings
144+
// We do not log any warnings coming from Selenium Manager like the other bindings, as we don't have any logging in the .NET bindings
173145

174146
var exceptionMessageBuilder = new StringBuilder($"Selenium Manager process exited abnormally with {process.ExitCode} code: {fileName} {arguments}");
175147

@@ -214,6 +186,27 @@ private static Dictionary<string, object> RunCommand(string fileName, string arg
214186
throw new WebDriverException($"Error deserializing Selenium Manager's response: {output}", ex);
215187
}
216188

189+
if (result.ContainsKey("logs"))
190+
{
191+
Dictionary<string, string> logs = result["logs"] as Dictionary<string, string>;
192+
foreach (KeyValuePair<string, string> entry in logs)
193+
{
194+
switch (entry.Key)
195+
{
196+
case "WARN":
197+
_logger.Warn(entry.Value);
198+
break;
199+
case "DEBUG":
200+
case "INFO":
201+
if (_logger.IsEnabled(LogEventLevel.Debug) && (entry.Key == "DEBUG" || entry.Key == "INFO"))
202+
{
203+
_logger.Debug(entry.Value);
204+
}
205+
break;
206+
}
207+
}
208+
}
209+
217210
return result;
218211
}
219212
}

0 commit comments

Comments
 (0)