2020using OpenQA . Selenium . Internal ;
2121using System ;
2222using System . Collections . Generic ;
23+ using System . Diagnostics . CodeAnalysis ;
2324using System . IO ;
2425using System . IO . Compression ;
2526using System . Text . Json ;
2627
28+ #nullable enable
29+
2730namespace OpenQA . Selenium . Firefox
2831{
2932 /// <summary>
@@ -32,13 +35,10 @@ namespace OpenQA.Selenium.Firefox
3235 public class FirefoxProfile
3336 {
3437 private const string UserPreferencesFileName = "user.js" ;
35-
36- private string profileDir ;
37- private string sourceProfileDir ;
38- private bool deleteSource ;
39- private bool deleteOnClean = true ;
40- private Preferences profilePreferences ;
41- private Dictionary < string , FirefoxExtension > extensions = new Dictionary < string , FirefoxExtension > ( ) ;
38+ private readonly string ? sourceProfileDir ;
39+ private readonly bool deleteSource ;
40+ private readonly Preferences profilePreferences ;
41+ private readonly Dictionary < string , FirefoxExtension > extensions = new Dictionary < string , FirefoxExtension > ( ) ;
4242
4343 /// <summary>
4444 /// Initializes a new instance of the <see cref="FirefoxProfile"/> class.
@@ -53,7 +53,7 @@ public FirefoxProfile()
5353 /// specific profile directory.
5454 /// </summary>
5555 /// <param name="profileDirectory">The directory containing the profile.</param>
56- public FirefoxProfile ( string profileDirectory )
56+ public FirefoxProfile ( string ? profileDirectory )
5757 : this ( profileDirectory , false )
5858 {
5959 }
@@ -64,31 +64,24 @@ public FirefoxProfile(string profileDirectory)
6464 /// </summary>
6565 /// <param name="profileDirectory">The directory containing the profile.</param>
6666 /// <param name="deleteSourceOnClean">Delete the source directory of the profile upon cleaning.</param>
67- public FirefoxProfile ( string profileDirectory , bool deleteSourceOnClean )
67+ public FirefoxProfile ( string ? profileDirectory , bool deleteSourceOnClean )
6868 {
6969 this . sourceProfileDir = profileDirectory ;
7070 this . deleteSource = deleteSourceOnClean ;
71- this . ReadDefaultPreferences ( ) ;
71+ this . profilePreferences = this . ReadDefaultPreferences ( ) ;
7272 this . profilePreferences . AppendPreferences ( this . ReadExistingPreferences ( ) ) ;
7373 }
7474
7575 /// <summary>
7676 /// Gets the directory containing the profile.
7777 /// </summary>
78- public string ProfileDirectory
79- {
80- get { return this . profileDir ; }
81- }
78+ public string ? ProfileDirectory { get ; private set ; }
8279
8380 /// <summary>
8481 /// Gets or sets a value indicating whether to delete this profile after use with
8582 /// the <see cref="FirefoxDriver"/>.
8683 /// </summary>
87- public bool DeleteAfterUse
88- {
89- get { return this . deleteOnClean ; }
90- set { this . deleteOnClean = value ; }
91- }
84+ public bool DeleteAfterUse { get ; set ; } = true ;
9285
9386 /// <summary>
9487 /// Converts a base64-encoded string into a <see cref="FirefoxProfile"/>.
@@ -130,6 +123,7 @@ public void AddExtension(string extensionToInstall)
130123 /// </summary>
131124 /// <param name="name">The name of the preference to add.</param>
132125 /// <param name="value">A <see cref="string"/> value to add to the profile.</param>
126+ /// <exception cref="ArgumentNullException">If <paramref name="name"/> or <paramref name="value"/> are <see langword="null"/>.</exception>
133127 public void SetPreference ( string name , string value )
134128 {
135129 this . profilePreferences . SetPreference ( name , value ) ;
@@ -140,6 +134,7 @@ public void SetPreference(string name, string value)
140134 /// </summary>
141135 /// <param name="name">The name of the preference to add.</param>
142136 /// <param name="value">A <see cref="int"/> value to add to the profile.</param>
137+ /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langword="null"/>.</exception>
143138 public void SetPreference ( string name , int value )
144139 {
145140 this . profilePreferences . SetPreference ( name , value ) ;
@@ -150,6 +145,7 @@ public void SetPreference(string name, int value)
150145 /// </summary>
151146 /// <param name="name">The name of the preference to add.</param>
152147 /// <param name="value">A <see cref="bool"/> value to add to the profile.</param>
148+ /// <exception cref="ArgumentNullException">If <paramref name="name"/> is <see langword="null"/>.</exception>
153149 public void SetPreference ( string name , bool value )
154150 {
155151 this . profilePreferences . SetPreference ( name , value ) ;
@@ -158,22 +154,23 @@ public void SetPreference(string name, bool value)
158154 /// <summary>
159155 /// Writes this in-memory representation of a profile to disk.
160156 /// </summary>
157+ [ MemberNotNull ( nameof ( ProfileDirectory ) ) ]
161158 public void WriteToDisk ( )
162159 {
163- this . profileDir = GenerateProfileDirectoryName ( ) ;
160+ this . ProfileDirectory = GenerateProfileDirectoryName ( ) ;
164161 if ( ! string . IsNullOrEmpty ( this . sourceProfileDir ) )
165162 {
166- FileUtilities . CopyDirectory ( this . sourceProfileDir , this . profileDir ) ;
163+ FileUtilities . CopyDirectory ( this . sourceProfileDir , this . ProfileDirectory ) ;
167164 }
168165 else
169166 {
170- Directory . CreateDirectory ( this . profileDir ) ;
167+ Directory . CreateDirectory ( this . ProfileDirectory ) ;
171168 }
172169
173- this . InstallExtensions ( ) ;
174- this . DeleteLockFiles ( ) ;
175- this . DeleteExtensionsCache ( ) ;
176- this . UpdateUserPreferences ( ) ;
170+ this . InstallExtensions ( this . ProfileDirectory ) ;
171+ this . DeleteLockFiles ( this . ProfileDirectory ) ;
172+ this . DeleteExtensionsCache ( this . ProfileDirectory ) ;
173+ this . UpdateUserPreferences ( this . ProfileDirectory ) ;
177174 }
178175
179176 /// <summary>
@@ -185,9 +182,9 @@ public void WriteToDisk()
185182 /// is deleted.</remarks>
186183 public void Clean ( )
187184 {
188- if ( this . deleteOnClean && ! string . IsNullOrEmpty ( this . profileDir ) && Directory . Exists ( this . profileDir ) )
185+ if ( this . DeleteAfterUse && ! string . IsNullOrEmpty ( this . ProfileDirectory ) && Directory . Exists ( this . ProfileDirectory ) )
189186 {
190- FileUtilities . DeleteDirectory ( this . profileDir ) ;
187+ FileUtilities . DeleteDirectory ( this . ProfileDirectory ) ;
191188 }
192189
193190 if ( this . deleteSource && ! string . IsNullOrEmpty ( this . sourceProfileDir ) && Directory . Exists ( this . sourceProfileDir ) )
@@ -202,17 +199,17 @@ public void Clean()
202199 /// <returns>A base64-encoded string containing the contents of the profile.</returns>
203200 public string ToBase64String ( )
204201 {
205- string base64zip = string . Empty ;
202+ string base64zip ;
206203 this . WriteToDisk ( ) ;
207204
208205 using ( MemoryStream profileMemoryStream = new MemoryStream ( ) )
209206 {
210207 using ( ZipArchive profileZipArchive = new ZipArchive ( profileMemoryStream , ZipArchiveMode . Create , true ) )
211208 {
212- string [ ] files = Directory . GetFiles ( this . profileDir , "*.*" , SearchOption . AllDirectories ) ;
209+ string [ ] files = Directory . GetFiles ( this . ProfileDirectory , "*.*" , SearchOption . AllDirectories ) ;
213210 foreach ( string file in files )
214211 {
215- string fileNameInZip = file . Substring ( this . profileDir . Length + 1 ) . Replace ( Path . DirectorySeparatorChar , '/' ) ;
212+ string fileNameInZip = file . Substring ( this . ProfileDirectory . Length + 1 ) . Replace ( Path . DirectorySeparatorChar , '/' ) ;
216213 profileZipArchive . CreateEntryFromFile ( file , fileNameInZip ) ;
217214 }
218215 }
@@ -236,20 +233,20 @@ private static string GenerateProfileDirectoryName()
236233 /// <summary>
237234 /// Deletes the lock files for a profile.
238235 /// </summary>
239- private void DeleteLockFiles ( )
236+ private void DeleteLockFiles ( string profileDirectory )
240237 {
241- File . Delete ( Path . Combine ( this . profileDir , ".parentlock" ) ) ;
242- File . Delete ( Path . Combine ( this . profileDir , "parent.lock" ) ) ;
238+ File . Delete ( Path . Combine ( profileDirectory , ".parentlock" ) ) ;
239+ File . Delete ( Path . Combine ( profileDirectory , "parent.lock" ) ) ;
243240 }
244241
245242 /// <summary>
246243 /// Installs all extensions in the profile in the directory on disk.
247244 /// </summary>
248- private void InstallExtensions ( )
245+ private void InstallExtensions ( string profileDirectory )
249246 {
250247 foreach ( string extensionKey in this . extensions . Keys )
251248 {
252- this . extensions [ extensionKey ] . Install ( this . profileDir ) ;
249+ this . extensions [ extensionKey ] . Install ( profileDirectory ) ;
253250 }
254251 }
255252
@@ -259,10 +256,10 @@ private void InstallExtensions()
259256 /// <remarks>If the extensions cache does not exist for this profile, the
260257 /// <see cref="DeleteExtensionsCache"/> method performs no operations, but
261258 /// succeeds.</remarks>
262- private void DeleteExtensionsCache ( )
259+ private void DeleteExtensionsCache ( string profileDirectory )
263260 {
264- DirectoryInfo ex = new DirectoryInfo ( Path . Combine ( this . profileDir , "extensions" ) ) ;
265- string cacheFile = Path . Combine ( ex . Parent . FullName , "extensions.cache" ) ;
261+ DirectoryInfo ex = new DirectoryInfo ( Path . Combine ( profileDirectory , "extensions" ) ) ;
262+ string cacheFile = Path . Combine ( ex . Parent ! . FullName , "extensions.cache" ) ;
266263 if ( File . Exists ( cacheFile ) )
267264 {
268265 File . Delete ( cacheFile ) ;
@@ -272,9 +269,9 @@ private void DeleteExtensionsCache()
272269 /// <summary>
273270 /// Writes the user preferences to the profile.
274271 /// </summary>
275- private void UpdateUserPreferences ( )
272+ private void UpdateUserPreferences ( string profileDirectory )
276273 {
277- string userPrefs = Path . Combine ( this . profileDir , UserPreferencesFileName ) ;
274+ string userPrefs = Path . Combine ( profileDirectory , UserPreferencesFileName ) ;
278275 if ( File . Exists ( userPrefs ) )
279276 {
280277 try
@@ -300,7 +297,7 @@ private void UpdateUserPreferences()
300297 this . profilePreferences . WriteToFile ( userPrefs ) ;
301298 }
302299
303- private void ReadDefaultPreferences ( )
300+ private Preferences ReadDefaultPreferences ( )
304301 {
305302 using ( Stream defaultPrefsStream = ResourceUtilities . GetResourceStream ( "webdriver_prefs.json" , "webdriver_prefs.json" ) )
306303 {
@@ -309,7 +306,7 @@ private void ReadDefaultPreferences()
309306 JsonElement immutableDefaultPreferences = defaultPreferences . RootElement . GetProperty ( "frozen" ) ;
310307 JsonElement editableDefaultPreferences = defaultPreferences . RootElement . GetProperty ( "mutable" ) ;
311308
312- this . profilePreferences = new Preferences ( immutableDefaultPreferences , editableDefaultPreferences ) ;
309+ return new Preferences ( immutableDefaultPreferences , editableDefaultPreferences ) ;
313310 }
314311 }
315312
0 commit comments