diff --git a/dotnet/src/webdriver/Firefox/FirefoxProfile.cs b/dotnet/src/webdriver/Firefox/FirefoxProfile.cs
index 0998cb436ea94..1814e35b0ca7a 100644
--- a/dotnet/src/webdriver/Firefox/FirefoxProfile.cs
+++ b/dotnet/src/webdriver/Firefox/FirefoxProfile.cs
@@ -20,10 +20,13 @@
using OpenQA.Selenium.Internal;
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.IO.Compression;
using System.Text.Json;
+#nullable enable
+
namespace OpenQA.Selenium.Firefox
{
///
@@ -32,13 +35,10 @@ namespace OpenQA.Selenium.Firefox
public class FirefoxProfile
{
private const string UserPreferencesFileName = "user.js";
-
- private string profileDir;
- private string sourceProfileDir;
- private bool deleteSource;
- private bool deleteOnClean = true;
- private Preferences profilePreferences;
- private Dictionary extensions = new Dictionary();
+ private readonly string? sourceProfileDir;
+ private readonly bool deleteSource;
+ private readonly Preferences profilePreferences;
+ private readonly Dictionary extensions = new Dictionary();
///
/// Initializes a new instance of the class.
@@ -53,7 +53,7 @@ public FirefoxProfile()
/// specific profile directory.
///
/// The directory containing the profile.
- public FirefoxProfile(string profileDirectory)
+ public FirefoxProfile(string? profileDirectory)
: this(profileDirectory, false)
{
}
@@ -64,31 +64,24 @@ public FirefoxProfile(string profileDirectory)
///
/// The directory containing the profile.
/// Delete the source directory of the profile upon cleaning.
- public FirefoxProfile(string profileDirectory, bool deleteSourceOnClean)
+ public FirefoxProfile(string? profileDirectory, bool deleteSourceOnClean)
{
this.sourceProfileDir = profileDirectory;
this.deleteSource = deleteSourceOnClean;
- this.ReadDefaultPreferences();
+ this.profilePreferences = this.ReadDefaultPreferences();
this.profilePreferences.AppendPreferences(this.ReadExistingPreferences());
}
///
/// Gets the directory containing the profile.
///
- public string ProfileDirectory
- {
- get { return this.profileDir; }
- }
+ public string? ProfileDirectory { get; private set; }
///
/// Gets or sets a value indicating whether to delete this profile after use with
/// the .
///
- public bool DeleteAfterUse
- {
- get { return this.deleteOnClean; }
- set { this.deleteOnClean = value; }
- }
+ public bool DeleteAfterUse { get; set; } = true;
///
/// Converts a base64-encoded string into a .
@@ -130,6 +123,7 @@ public void AddExtension(string extensionToInstall)
///
/// The name of the preference to add.
/// A value to add to the profile.
+ /// If or are .
public void SetPreference(string name, string value)
{
this.profilePreferences.SetPreference(name, value);
@@ -140,6 +134,7 @@ public void SetPreference(string name, string value)
///
/// The name of the preference to add.
/// A value to add to the profile.
+ /// If is .
public void SetPreference(string name, int value)
{
this.profilePreferences.SetPreference(name, value);
@@ -150,6 +145,7 @@ public void SetPreference(string name, int value)
///
/// The name of the preference to add.
/// A value to add to the profile.
+ /// If is .
public void SetPreference(string name, bool value)
{
this.profilePreferences.SetPreference(name, value);
@@ -158,22 +154,23 @@ public void SetPreference(string name, bool value)
///
/// Writes this in-memory representation of a profile to disk.
///
+ [MemberNotNull(nameof(ProfileDirectory))]
public void WriteToDisk()
{
- this.profileDir = GenerateProfileDirectoryName();
+ this.ProfileDirectory = GenerateProfileDirectoryName();
if (!string.IsNullOrEmpty(this.sourceProfileDir))
{
- FileUtilities.CopyDirectory(this.sourceProfileDir, this.profileDir);
+ FileUtilities.CopyDirectory(this.sourceProfileDir, this.ProfileDirectory);
}
else
{
- Directory.CreateDirectory(this.profileDir);
+ Directory.CreateDirectory(this.ProfileDirectory);
}
- this.InstallExtensions();
- this.DeleteLockFiles();
- this.DeleteExtensionsCache();
- this.UpdateUserPreferences();
+ this.InstallExtensions(this.ProfileDirectory);
+ this.DeleteLockFiles(this.ProfileDirectory);
+ this.DeleteExtensionsCache(this.ProfileDirectory);
+ this.UpdateUserPreferences(this.ProfileDirectory);
}
///
@@ -185,9 +182,9 @@ public void WriteToDisk()
/// is deleted.
public void Clean()
{
- if (this.deleteOnClean && !string.IsNullOrEmpty(this.profileDir) && Directory.Exists(this.profileDir))
+ if (this.DeleteAfterUse && !string.IsNullOrEmpty(this.ProfileDirectory) && Directory.Exists(this.ProfileDirectory))
{
- FileUtilities.DeleteDirectory(this.profileDir);
+ FileUtilities.DeleteDirectory(this.ProfileDirectory);
}
if (this.deleteSource && !string.IsNullOrEmpty(this.sourceProfileDir) && Directory.Exists(this.sourceProfileDir))
@@ -202,17 +199,17 @@ public void Clean()
/// A base64-encoded string containing the contents of the profile.
public string ToBase64String()
{
- string base64zip = string.Empty;
+ string base64zip;
this.WriteToDisk();
using (MemoryStream profileMemoryStream = new MemoryStream())
{
using (ZipArchive profileZipArchive = new ZipArchive(profileMemoryStream, ZipArchiveMode.Create, true))
{
- string[] files = Directory.GetFiles(this.profileDir, "*.*", SearchOption.AllDirectories);
+ string[] files = Directory.GetFiles(this.ProfileDirectory, "*.*", SearchOption.AllDirectories);
foreach (string file in files)
{
- string fileNameInZip = file.Substring(this.profileDir.Length + 1).Replace(Path.DirectorySeparatorChar, '/');
+ string fileNameInZip = file.Substring(this.ProfileDirectory.Length + 1).Replace(Path.DirectorySeparatorChar, '/');
profileZipArchive.CreateEntryFromFile(file, fileNameInZip);
}
}
@@ -236,20 +233,20 @@ private static string GenerateProfileDirectoryName()
///
/// Deletes the lock files for a profile.
///
- private void DeleteLockFiles()
+ private void DeleteLockFiles(string profileDirectory)
{
- File.Delete(Path.Combine(this.profileDir, ".parentlock"));
- File.Delete(Path.Combine(this.profileDir, "parent.lock"));
+ File.Delete(Path.Combine(profileDirectory, ".parentlock"));
+ File.Delete(Path.Combine(profileDirectory, "parent.lock"));
}
///
/// Installs all extensions in the profile in the directory on disk.
///
- private void InstallExtensions()
+ private void InstallExtensions(string profileDirectory)
{
foreach (string extensionKey in this.extensions.Keys)
{
- this.extensions[extensionKey].Install(this.profileDir);
+ this.extensions[extensionKey].Install(profileDirectory);
}
}
@@ -259,10 +256,10 @@ private void InstallExtensions()
/// If the extensions cache does not exist for this profile, the
/// method performs no operations, but
/// succeeds.
- private void DeleteExtensionsCache()
+ private void DeleteExtensionsCache(string profileDirectory)
{
- DirectoryInfo ex = new DirectoryInfo(Path.Combine(this.profileDir, "extensions"));
- string cacheFile = Path.Combine(ex.Parent.FullName, "extensions.cache");
+ DirectoryInfo ex = new DirectoryInfo(Path.Combine(profileDirectory, "extensions"));
+ string cacheFile = Path.Combine(ex.Parent!.FullName, "extensions.cache");
if (File.Exists(cacheFile))
{
File.Delete(cacheFile);
@@ -272,9 +269,9 @@ private void DeleteExtensionsCache()
///
/// Writes the user preferences to the profile.
///
- private void UpdateUserPreferences()
+ private void UpdateUserPreferences(string profileDirectory)
{
- string userPrefs = Path.Combine(this.profileDir, UserPreferencesFileName);
+ string userPrefs = Path.Combine(profileDirectory, UserPreferencesFileName);
if (File.Exists(userPrefs))
{
try
@@ -300,7 +297,7 @@ private void UpdateUserPreferences()
this.profilePreferences.WriteToFile(userPrefs);
}
- private void ReadDefaultPreferences()
+ private Preferences ReadDefaultPreferences()
{
using (Stream defaultPrefsStream = ResourceUtilities.GetResourceStream("webdriver_prefs.json", "webdriver_prefs.json"))
{
@@ -309,7 +306,7 @@ private void ReadDefaultPreferences()
JsonElement immutableDefaultPreferences = defaultPreferences.RootElement.GetProperty("frozen");
JsonElement editableDefaultPreferences = defaultPreferences.RootElement.GetProperty("mutable");
- this.profilePreferences = new Preferences(immutableDefaultPreferences, editableDefaultPreferences);
+ return new Preferences(immutableDefaultPreferences, editableDefaultPreferences);
}
}
diff --git a/dotnet/src/webdriver/Firefox/FirefoxProfileManager.cs b/dotnet/src/webdriver/Firefox/FirefoxProfileManager.cs
index f53ea800e3249..601c784e946ec 100644
--- a/dotnet/src/webdriver/Firefox/FirefoxProfileManager.cs
+++ b/dotnet/src/webdriver/Firefox/FirefoxProfileManager.cs
@@ -23,6 +23,8 @@
using System.Collections.ObjectModel;
using System.IO;
+#nullable enable
+
namespace OpenQA.Selenium.Firefox
{
///
@@ -45,14 +47,7 @@ public FirefoxProfileManager()
/// Gets a containing FirefoxProfiles
/// representing the existing named profiles for Firefox.
///
- public ReadOnlyCollection ExistingProfiles
- {
- get
- {
- List profileList = new List(this.profiles.Keys);
- return profileList.AsReadOnly();
- }
- }
+ public ReadOnlyCollection ExistingProfiles => new List(this.profiles.Keys).AsReadOnly();
///
/// Gets a with a given name.
@@ -60,37 +55,24 @@ public ReadOnlyCollection ExistingProfiles
/// The name of the profile to get.
/// A with a given name.
/// Returns if no profile with the given name exists.
- public FirefoxProfile GetProfile(string profileName)
+ public FirefoxProfile? GetProfile(string? profileName)
{
- FirefoxProfile profile = null;
- if (!string.IsNullOrEmpty(profileName))
+ if (profileName is not null && this.profiles.TryGetValue(profileName, out string? profile))
{
- if (this.profiles.ContainsKey(profileName))
- {
- profile = new FirefoxProfile(this.profiles[profileName]);
- }
+ return new FirefoxProfile(profile);
}
- return profile;
+ return null;
}
private static string GetApplicationDataDirectory()
{
- string appDataDirectory = string.Empty;
- switch (Environment.OSVersion.Platform)
+ string appDataDirectory = Environment.OSVersion.Platform switch
{
- case PlatformID.Unix:
- appDataDirectory = Path.Combine(".mozilla", "firefox");
- break;
-
- case PlatformID.MacOSX:
- appDataDirectory = Path.Combine("Library", Path.Combine("Application Support", "Firefox"));
- break;
-
- default:
- appDataDirectory = Path.Combine("Mozilla", "Firefox");
- break;
- }
+ PlatformID.Unix => Path.Combine(".mozilla", "firefox"),
+ PlatformID.MacOSX => Path.Combine("Library", Path.Combine("Application Support", "Firefox")),
+ _ => Path.Combine("Mozilla", "Firefox"),
+ };
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), appDataDirectory);
}
@@ -109,7 +91,7 @@ private void ReadProfiles(string appDataDirectory)
string name = reader.GetValue(sectionName, "name");
bool isRelative = reader.GetValue(sectionName, "isrelative") == "1";
string profilePath = reader.GetValue(sectionName, "path");
- string fullPath = string.Empty;
+ string fullPath;
if (isRelative)
{
fullPath = Path.Combine(appDataDirectory, profilePath);
diff --git a/dotnet/src/webdriver/Internal/FileUtilities.cs b/dotnet/src/webdriver/Internal/FileUtilities.cs
index ff23a34a1cf86..b925da2c359a3 100644
--- a/dotnet/src/webdriver/Internal/FileUtilities.cs
+++ b/dotnet/src/webdriver/Internal/FileUtilities.cs
@@ -76,7 +76,7 @@ public static bool CopyDirectory(string sourceDirectory, string destinationDirec
///
/// The directory to delete.
/// This method does not throw an exception if the delete fails.
- public static void DeleteDirectory(string directoryToDelete)
+ public static void DeleteDirectory(string? directoryToDelete)
{
int numberOfRetries = 0;
while (Directory.Exists(directoryToDelete) && numberOfRetries < 10)
@@ -210,7 +210,11 @@ public static string GetCurrentDirectory()
/// The pattern to use in creating the directory name, following standard
/// .NET string replacement tokens.
/// The full path to the random directory name in the temporary directory.
- public static string GenerateRandomTempDirectoryName(string directoryPattern)
+ public static string GenerateRandomTempDirectoryName(
+#if NET8_0_OR_GREATER
+ [System.Diagnostics.CodeAnalysis.StringSyntax(System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.CompositeFormat)]
+#endif
+ string directoryPattern)
{
string directoryName = string.Format(CultureInfo.InvariantCulture, directoryPattern, Guid.NewGuid().ToString("N"));
return Path.Combine(Path.GetTempPath(), directoryName);