1818// </copyright>
1919
2020using System ;
21- using System . Collections . Generic ;
21+ using System . Diagnostics . CodeAnalysis ;
2222using System . Globalization ;
2323using System . IO ;
2424using System . Text ;
2525
26+ #nullable enable
27+
2628namespace OpenQA . Selenium
2729{
2830 /// <summary>
@@ -31,17 +33,18 @@ namespace OpenQA.Selenium
3133 /// </summary>
3234 public class DriverFinder
3335 {
34- private DriverOptions options ;
35- private Dictionary < string , string > paths = new Dictionary < string , string > ( ) ;
36+ private readonly DriverOptions options ;
37+ private SeleniumManagerPaths ? paths ;
3638 private const string BrowserPathKey = "browser_path" ;
3739 private const string DriverPathKey = "driver_path" ;
3840
3941 /// <summary>
4042 /// Initializes a new instance of the <see cref="DriverFinder"/> class.
4143 /// </summary>
44+ /// <exception cref="ArgumentNullException">If <paramref name="options"/> is <see langword="null"/>.</exception>
4245 public DriverFinder ( DriverOptions options )
4346 {
44- this . options = options ;
47+ this . options = options ?? throw new ArgumentNullException ( nameof ( options ) ) ;
4548 }
4649
4750 /// <summary>
@@ -52,7 +55,7 @@ public DriverFinder(DriverOptions options)
5255 /// </returns>
5356 public string GetBrowserPath ( )
5457 {
55- return BinaryPaths ( ) [ BrowserPathKey ] ;
58+ return BinaryPaths ( ) . BrowserPath ;
5659 }
5760
5861 /// <summary>
@@ -63,47 +66,62 @@ public string GetBrowserPath()
6366 /// </returns>
6467 public string GetDriverPath ( )
6568 {
66- return BinaryPaths ( ) [ DriverPathKey ] ;
69+ return BinaryPaths ( ) . DriverPath ;
6770 }
6871
72+ /// <summary>
73+ /// Gets whether there is a browser path for the given browser on this platform.
74+ /// </summary>
75+ /// <returns><see langword="true"/> if a browser path exists; otherwise, <see langword="false"/>.</returns>
6976 public bool HasBrowserPath ( )
7077 {
7178 return ! string . IsNullOrWhiteSpace ( GetBrowserPath ( ) ) ;
7279 }
7380
81+ /// <summary>
82+ /// Tries to get the browser path, as retrieved by Selenium Manager.
83+ /// </summary>
84+ /// <param name="browserPath">If the method returns <see langword="true"/>, the full browser path.</param>
85+ /// <returns><see langword="true"/> if a browser path exists; otherwise, <see langword="false"/>.</returns>
86+ public bool TryGetBrowserPath ( [ NotNullWhen ( true ) ] out string ? browserPath )
87+ {
88+ string ? path = GetBrowserPath ( ) ;
89+ if ( ! string . IsNullOrWhiteSpace ( path ) )
90+ {
91+ browserPath = path ;
92+ return true ;
93+ }
94+
95+ browserPath = null ;
96+ return false ;
97+ }
98+
7499 /// <summary>
75100 /// Invokes Selenium Manager to get the binaries paths and validates if they exist.
76101 /// </summary>
77102 /// <returns>
78103 /// A Dictionary with the validated browser and driver path.
79104 /// </returns>
80105 /// <exception cref="NoSuchDriverException">If one of the paths does not exist.</exception>
81- private Dictionary < string , string > BinaryPaths ( )
106+ private SeleniumManagerPaths BinaryPaths ( )
82107 {
83- if ( paths . ContainsKey ( DriverPathKey ) && ! string . IsNullOrWhiteSpace ( paths [ DriverPathKey ] ) )
108+ if ( paths is not null )
84109 {
85110 return paths ;
86111 }
87- Dictionary < string , string > binaryPaths = SeleniumManager . BinaryPaths ( CreateArguments ( ) ) ;
88- string driverPath = binaryPaths [ DriverPathKey ] ;
89- string browserPath = binaryPaths [ BrowserPathKey ] ;
90- if ( File . Exists ( driverPath ) )
91- {
92- paths . Add ( DriverPathKey , driverPath ) ;
93- }
94- else
95- {
96- throw new NoSuchDriverException ( $ "The driver path is not a valid file: { driverPath } ") ;
97- }
98- if ( File . Exists ( browserPath ) )
112+
113+ SeleniumManagerPaths binaryPaths = SeleniumManager . BinaryPaths ( CreateArguments ( ) ) ;
114+ if ( ! File . Exists ( binaryPaths . DriverPath ) )
99115 {
100- paths . Add ( BrowserPathKey , browserPath ) ;
116+ throw new NoSuchDriverException ( $ "The driver path is not a valid file: { binaryPaths . DriverPath } " ) ;
101117 }
102- else
118+
119+ if ( ! File . Exists ( binaryPaths . BrowserPath ) )
103120 {
104- throw new NoSuchDriverException ( $ "The browser path is not a valid file: { browserPath } ") ;
121+ throw new NoSuchDriverException ( $ "The browser path is not a valid file: { binaryPaths . BrowserPath } ") ;
105122 }
106- return paths ;
123+
124+ return paths = binaryPaths ;
107125 }
108126
109127 /// <summary>
@@ -123,7 +141,7 @@ private string CreateArguments()
123141 argsBuilder . AppendFormat ( CultureInfo . InvariantCulture , " --browser-version {0}" , options . BrowserVersion ) ;
124142 }
125143
126- string browserBinary = options . BinaryLocation ;
144+ string ? browserBinary = options . BinaryLocation ;
127145 if ( ! string . IsNullOrEmpty ( browserBinary ) )
128146 {
129147 argsBuilder . AppendFormat ( CultureInfo . InvariantCulture , " --browser-path \" {0}\" " , browserBinary ) ;
0 commit comments