1919
2020using System ;
2121using System . Collections . Generic ;
22+ using System . Diagnostics . CodeAnalysis ;
2223using System . Globalization ;
2324using System . IO ;
2425using System . Text ;
2526
27+ #nullable enable
28+
2629namespace OpenQA . Selenium
2730{
2831 /// <summary>
@@ -31,17 +34,16 @@ namespace OpenQA.Selenium
3134 /// </summary>
3235 public class DriverFinder
3336 {
34- private DriverOptions options ;
37+ private readonly DriverOptions options ;
3538 private Dictionary < string , string > paths = new Dictionary < string , string > ( ) ;
36- private const string BrowserPathKey = "browser_path" ;
37- private const string DriverPathKey = "driver_path" ;
3839
3940 /// <summary>
4041 /// Initializes a new instance of the <see cref="DriverFinder"/> class.
4142 /// </summary>
43+ /// <exception cref="ArgumentNullException">If <paramref name="options"/> is <see langword="null"/>.</exception>
4244 public DriverFinder ( DriverOptions options )
4345 {
44- this . options = options ;
46+ this . options = options ?? throw new ArgumentNullException ( nameof ( options ) ) ;
4547 }
4648
4749 /// <summary>
@@ -52,7 +54,7 @@ public DriverFinder(DriverOptions options)
5254 /// </returns>
5355 public string GetBrowserPath ( )
5456 {
55- return BinaryPaths ( ) [ BrowserPathKey ] ;
57+ return BinaryPaths ( ) [ SeleniumManager . BrowserPathKey ] ;
5658 }
5759
5860 /// <summary>
@@ -63,14 +65,36 @@ public string GetBrowserPath()
6365 /// </returns>
6466 public string GetDriverPath ( )
6567 {
66- return BinaryPaths ( ) [ DriverPathKey ] ;
68+ return BinaryPaths ( ) [ SeleniumManager . DriverPathKey ] ;
6769 }
6870
71+ /// <summary>
72+ /// Gets whether there is a browser path for the given browser on this platform.
73+ /// </summary>
74+ /// <returns><see langword="true"/> if a browser path exists; otherwise, <see langword="false"/>.</returns>
6975 public bool HasBrowserPath ( )
7076 {
7177 return ! string . IsNullOrWhiteSpace ( GetBrowserPath ( ) ) ;
7278 }
7379
80+ /// <summary>
81+ /// Tries to get the browser path, as retrieved by Selenium Manager.
82+ /// </summary>
83+ /// <param name="browserPath">If the method returns <see langword="true"/>, the full browser path.</param>
84+ /// <returns><see langword="true"/> if a browser path exists; otherwise, <see langword="false"/>.</returns>
85+ public bool TryGetBrowserPath ( [ NotNullWhen ( true ) ] out string ? browserPath )
86+ {
87+ string ? path = GetBrowserPath ( ) ;
88+ if ( ! string . IsNullOrWhiteSpace ( path ) )
89+ {
90+ browserPath = path ;
91+ return true ;
92+ }
93+
94+ browserPath = null ;
95+ return false ;
96+ }
97+
7498 /// <summary>
7599 /// Invokes Selenium Manager to get the binaries paths and validates if they exist.
76100 /// </summary>
@@ -80,29 +104,33 @@ public bool HasBrowserPath()
80104 /// <exception cref="NoSuchDriverException">If one of the paths does not exist.</exception>
81105 private Dictionary < string , string > BinaryPaths ( )
82106 {
83- if ( paths . ContainsKey ( DriverPathKey ) && ! string . IsNullOrWhiteSpace ( paths [ DriverPathKey ] ) )
107+ if ( paths . ContainsKey ( SeleniumManager . DriverPathKey ) && ! string . IsNullOrWhiteSpace ( paths [ SeleniumManager . DriverPathKey ] ) )
84108 {
85109 return paths ;
86110 }
111+
87112 Dictionary < string , string > binaryPaths = SeleniumManager . BinaryPaths ( CreateArguments ( ) ) ;
88- string driverPath = binaryPaths [ DriverPathKey ] ;
89- string browserPath = binaryPaths [ BrowserPathKey ] ;
113+ string driverPath = binaryPaths [ SeleniumManager . DriverPathKey ] ;
114+ string browserPath = binaryPaths [ SeleniumManager . BrowserPathKey ] ;
115+
90116 if ( File . Exists ( driverPath ) )
91117 {
92- paths . Add ( DriverPathKey , driverPath ) ;
118+ paths . Add ( SeleniumManager . DriverPathKey , driverPath ) ;
93119 }
94120 else
95121 {
96122 throw new NoSuchDriverException ( $ "The driver path is not a valid file: { driverPath } ") ;
97123 }
124+
98125 if ( File . Exists ( browserPath ) )
99126 {
100- paths . Add ( BrowserPathKey , browserPath ) ;
127+ paths . Add ( SeleniumManager . BrowserPathKey , browserPath ) ;
101128 }
102129 else
103130 {
104131 throw new NoSuchDriverException ( $ "The browser path is not a valid file: { browserPath } ") ;
105132 }
133+
106134 return paths ;
107135 }
108136
@@ -123,7 +151,7 @@ private string CreateArguments()
123151 argsBuilder . AppendFormat ( CultureInfo . InvariantCulture , " --browser-version {0}" , options . BrowserVersion ) ;
124152 }
125153
126- string browserBinary = options . BinaryLocation ;
154+ string ? browserBinary = options . BinaryLocation ;
127155 if ( ! string . IsNullOrEmpty ( browserBinary ) )
128156 {
129157 argsBuilder . AppendFormat ( CultureInfo . InvariantCulture , " --browser-path \" {0}\" " , browserBinary ) ;
0 commit comments