Skip to content

Commit 339f39a

Browse files
committed
Updating .NET bindings to use webdriver.json for default Firefox profile.
Other language bindings have been using a common JSON file containing the default profile setting for the anonymous Firefox profile used by the Firefox driver. The .NET bindings now do the same.
1 parent 9c4dca7 commit 339f39a

File tree

6 files changed

+192
-139
lines changed

6 files changed

+192
-139
lines changed

dotnet/src/webdriver/Firefox/FirefoxDriver.cs

+5
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ public class FirefoxDriver : RemoteWebDriver, ITakesScreenshot
102102
/// </summary>
103103
public static readonly bool AcceptUntrustedCertificates = true;
104104

105+
/// <summary>
106+
/// Indicates whether the driver assume the issuer of untrusted certificates is untrusted.
107+
/// </summary>
108+
public static readonly bool AssumeUntrustedCertificateIssuer = true;
109+
105110
private FirefoxBinary binary;
106111

107112
private FirefoxProfile profile;

dotnet/src/webdriver/Firefox/FirefoxProfile.cs

+68-117
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,13 @@
2020
using System.Collections.Generic;
2121
using System.Globalization;
2222
using System.IO;
23-
using System.Reflection;
2423
using System.Text;
2524
using System.Xml;
2625
using System.Xml.XPath;
2726
using Ionic.Zip;
27+
using Newtonsoft.Json;
2828
using OpenQA.Selenium.Internal;
29+
using OpenQA.Selenium.Remote;
2930

3031
namespace OpenQA.Selenium.Firefox
3132
{
@@ -38,6 +39,11 @@ public class FirefoxProfile
3839
private const string ExtensionFileName = "webdriver.xpi";
3940
private const string ExtensionResourceId = "WebDriver.FirefoxExt.zip";
4041
private const string UserPreferencesFileName = "user.js";
42+
43+
private const string WebDriverPortPreferenceName = "webdriver_firefox_port";
44+
private const string EnableNativeEventsPreferenceName = "webdriver_enable_native_events";
45+
private const string AcceptUntrustedCertificatesPreferenceName = "webdriver_accept_untrusted_certs";
46+
private const string AssumeUntrustedCertificateIssuerPreferenceName = "webdriver_assume_untrusted_issuer";
4147
#endregion
4248

4349
#region Private members
@@ -47,8 +53,9 @@ public class FirefoxProfile
4753
private bool enableNativeEvents;
4854
private bool loadNoFocusLibrary;
4955
private bool acceptUntrustedCerts;
56+
private bool assumeUntrustedIssuer;
5057
private bool deleteSource;
51-
private Preferences profileAdditionalPrefs = new Preferences();
58+
private Preferences profilePreferences;
5259
private Dictionary<string, FirefoxExtension> extensions = new Dictionary<string, FirefoxExtension>();
5360
#endregion
5461

@@ -83,7 +90,10 @@ public FirefoxProfile(string profileDirectory, bool deleteSourceOnClean)
8390
this.profilePort = FirefoxDriver.DefaultPort;
8491
this.enableNativeEvents = FirefoxDriver.DefaultEnableNativeEvents;
8592
this.acceptUntrustedCerts = FirefoxDriver.AcceptUntrustedCertificates;
93+
this.assumeUntrustedIssuer = FirefoxDriver.AssumeUntrustedCertificateIssuer;
8694
this.deleteSource = deleteSourceOnClean;
95+
this.ReadDefaultPreferences();
96+
this.profilePreferences.AppendPreferences(this.ReadExistingPreferences());
8797
}
8898
#endregion
8999

@@ -126,13 +136,39 @@ public bool AlwaysLoadNoFocusLibrary
126136
}
127137

128138
/// <summary>
129-
/// Gets or sets a value indicating whether Firefox should accept untrusted certificates.
139+
/// Gets or sets a value indicating whether Firefox should accept SSL certificates which have
140+
/// expired, signed by an unknown authority or are generally untrusted. Set to true
141+
/// by default.
130142
/// </summary>
131143
public bool AcceptUntrustedCertificates
132144
{
133145
get { return this.acceptUntrustedCerts; }
134146
set { this.acceptUntrustedCerts = value; }
135147
}
148+
149+
/// <summary>
150+
/// Gets or sets a value indicating whether Firefox assume untrusted SSL certificates
151+
/// come from an untrusted issuer or are self-signed. Set to true by default.
152+
/// </summary>
153+
/// <remarks>
154+
/// <para>
155+
/// Due to limitations within Firefox, it is easy to find out if a certificate has expired
156+
/// or does not match the host it was served for, but hard to find out if the issuer of the
157+
/// certificate is untrusted. By default, it is assumed that the certificates were not
158+
/// issued from a trusted certificate authority.
159+
/// </para>
160+
/// <para>
161+
/// If you receive an "untrusted site" prompt it Firefox when using a certificate that was
162+
/// issued by valid issuer, but the certificate has expired or is being served served for
163+
/// a different host (e.g. production certificate served in a testing environment) set this
164+
/// to false.
165+
/// </para>
166+
/// </remarks>
167+
public bool AssumeUntrustedCertificateIssuer
168+
{
169+
get { return this.assumeUntrustedIssuer; }
170+
set { this.assumeUntrustedIssuer = value; }
171+
}
136172
#endregion
137173

138174
#region Public methods
@@ -173,7 +209,7 @@ public void AddExtension(string extensionToInstall)
173209
/// <param name="value">A <see cref="System.String"/> value to add to the profile.</param>
174210
public void SetPreference(string name, string value)
175211
{
176-
this.profileAdditionalPrefs.SetPreference(name, value);
212+
this.profilePreferences.SetPreference(name, value);
177213
}
178214

179215
/// <summary>
@@ -183,7 +219,7 @@ public void SetPreference(string name, string value)
183219
/// <param name="value">A <see cref="System.Int32"/> value to add to the profile.</param>
184220
public void SetPreference(string name, int value)
185221
{
186-
this.profileAdditionalPrefs.SetPreference(name, value);
222+
this.profilePreferences.SetPreference(name, value);
187223
}
188224

189225
/// <summary>
@@ -193,7 +229,7 @@ public void SetPreference(string name, int value)
193229
/// <param name="value">A <see cref="System.Boolean"/> value to add to the profile.</param>
194230
public void SetPreference(string name, bool value)
195231
{
196-
this.profileAdditionalPrefs.SetPreference(name, value);
232+
this.profilePreferences.SetPreference(name, value);
197233
}
198234

199235
/// <summary>
@@ -313,22 +349,6 @@ internal void AddWebDriverExtension()
313349
}
314350
}
315351

316-
/// <summary>
317-
/// Adds a preference to the profile.
318-
/// </summary>
319-
/// <param name="preferences">The preferences dictionary.</param>
320-
/// <param name="name">The name of the preference.</param>
321-
/// <param name="value">The value of the preference.</param>
322-
private static void AddDefaultPreference(Dictionary<string, string> preferences, string name, string value)
323-
{
324-
// The user must be able to override the default preferences in the profile,
325-
// so only add them if they don't already exist.
326-
if (!preferences.ContainsKey(name))
327-
{
328-
preferences.Add(name, value);
329-
}
330-
}
331-
332352
/// <summary>
333353
/// Generates a random directory name for the profile.
334354
/// </summary>
@@ -384,8 +404,6 @@ private void UpdateUserPreferences()
384404
throw new WebDriverException("You must set the port to listen on before updating user.js");
385405
}
386406

387-
Dictionary<string, string> prefs = this.ReadExistingPreferences();
388-
389407
string userPrefs = Path.Combine(this.profileDir, UserPreferencesFileName);
390408
if (File.Exists(userPrefs))
391409
{
@@ -399,88 +417,37 @@ private void UpdateUserPreferences()
399417
}
400418
}
401419

402-
this.profileAdditionalPrefs.AppendPreferencesTo(prefs);
403-
404-
// Normal settings to facilitate testing
405-
AddDefaultPreference(prefs, "app.update.auto", "false");
406-
AddDefaultPreference(prefs, "app.update.enabled", "false");
407-
AddDefaultPreference(prefs, "browser.download.manager.showWhenStarting", "false");
408-
AddDefaultPreference(prefs, "browser.EULA.override", "true");
409-
AddDefaultPreference(prefs, "browser.EULA.3.accepted", "true");
410-
AddDefaultPreference(prefs, "browser.link.open_external", "2");
411-
AddDefaultPreference(prefs, "browser.link.open_newwindow", "2");
412-
AddDefaultPreference(prefs, "browser.offline", "false");
413-
AddDefaultPreference(prefs, "browser.safebrowsing.enabled", "false");
414-
AddDefaultPreference(prefs, "browser.safebrowsing.malware.enabled", "false");
415-
AddDefaultPreference(prefs, "browser.search.update", "false");
416-
AddDefaultPreference(prefs, "extensions.blocklist.enabled", "false");
417-
AddDefaultPreference(prefs, "browser.sessionstore.resume_from_crash", "false");
418-
AddDefaultPreference(prefs, "browser.shell.checkDefaultBrowser", "false");
419-
AddDefaultPreference(prefs, "browser.startup.page", "0");
420-
AddDefaultPreference(prefs, "browser.tabs.warnOnClose", "false");
421-
AddDefaultPreference(prefs, "browser.tabs.warnOnOpen", "false");
422-
AddDefaultPreference(prefs, "devtools.errorconsole.enabled", "true");
423-
AddDefaultPreference(prefs, "dom.disable_open_during_load", "false");
424-
AddDefaultPreference(prefs, "dom.max_script_run_time", "30");
425-
AddDefaultPreference(prefs, "extensions.autoDisableScopes", "10");
426-
AddDefaultPreference(prefs, "extensions.logging.enabled", "true");
427-
AddDefaultPreference(prefs, "extensions.update.enabled", "false");
428-
AddDefaultPreference(prefs, "extensions.update.notifyUser", "false");
429-
AddDefaultPreference(prefs, "network.manage-offline-status", "false");
430-
AddDefaultPreference(prefs, "network.http.max-connections-per-server", "10");
431-
AddDefaultPreference(prefs, "network.http.phishy-userpass-length", "255");
432-
AddDefaultPreference(prefs, "offline-apps.allow_by_default", "true");
433-
AddDefaultPreference(prefs, "prompts.tab_modal.enabled", "false");
434-
AddDefaultPreference(prefs, "security.fileuri.origin_policy", "3");
435-
AddDefaultPreference(prefs, "security.fileuri.strict_origin_policy", "false");
436-
AddDefaultPreference(prefs, "security.warn_entering_secure", "false");
437-
AddDefaultPreference(prefs, "security.warn_submit_insecure", "false");
438-
AddDefaultPreference(prefs, "security.warn_entering_secure.show_once", "false");
439-
AddDefaultPreference(prefs, "security.warn_entering_weak", "false");
440-
AddDefaultPreference(prefs, "security.warn_entering_weak.show_once", "false");
441-
AddDefaultPreference(prefs, "security.warn_leaving_secure", "false");
442-
AddDefaultPreference(prefs, "security.warn_leaving_secure.show_once", "false");
443-
AddDefaultPreference(prefs, "security.warn_submit_insecure", "false");
444-
AddDefaultPreference(prefs, "security.warn_viewing_mixed", "false");
445-
AddDefaultPreference(prefs, "security.warn_viewing_mixed.show_once", "false");
446-
AddDefaultPreference(prefs, "signon.rememberSignons", "false");
447-
AddDefaultPreference(prefs, "startup.homepage_welcome_url", "\"about:blank\"");
448-
AddDefaultPreference(prefs, "toolkit.networkmanager.disable", "true");
449-
AddDefaultPreference(prefs, "toolkit.telemetry.enabled", "false");
450-
AddDefaultPreference(prefs, "toolkit.telemetry.prompted", "2");
451-
AddDefaultPreference(prefs, "toolkit.telemetry.rejected", "true");
452-
453-
// Which port should we listen on?
454-
AddDefaultPreference(prefs, "webdriver_firefox_port", this.profilePort.ToString(CultureInfo.InvariantCulture));
455-
456-
// Should we use native events?
457-
AddDefaultPreference(prefs, "webdriver_enable_native_events", this.enableNativeEvents.ToString().ToLowerInvariant());
458-
459-
// Should we accept untrusted certificates or not?
460-
AddDefaultPreference(prefs, "webdriver_accept_untrusted_certs", this.acceptUntrustedCerts.ToString().ToLowerInvariant());
461-
462-
// Settings to facilitate debugging the driver
463-
// Logs errors in chrome files to the Error Console.
464-
AddDefaultPreference(prefs, "javascript.options.showInConsole", "true"); // Logs errors in chrome files to the Error Console.
465-
466-
// Enables the use of the dump() statement
467-
AddDefaultPreference(prefs, "browser.dom.window.dump.enabled", "true"); // Enables the use of the dump() statement
468-
469-
// Log exceptions from inner frames (i.e. setTimeout)
470-
AddDefaultPreference(prefs, "dom.report_all_js_exceptions", "true");
471-
472-
// If the user sets the home page, we should also start up there
473-
string userHomePage = string.Empty;
474-
if (prefs.TryGetValue("browser.startup.homepage", out userHomePage))
420+
this.profilePreferences.SetPreference(WebDriverPortPreferenceName, this.profilePort);
421+
this.profilePreferences.SetPreference(EnableNativeEventsPreferenceName, this.enableNativeEvents);
422+
this.profilePreferences.SetPreference(AcceptUntrustedCertificatesPreferenceName, this.acceptUntrustedCerts);
423+
this.profilePreferences.SetPreference(AssumeUntrustedCertificateIssuerPreferenceName, this.assumeUntrustedIssuer);
424+
425+
string homePage = this.profilePreferences.GetPreference("browser.startup.homepage");
426+
if (!string.IsNullOrEmpty(homePage))
475427
{
476-
AddDefaultPreference(prefs, "startup.homepage_welcome_url", userHomePage);
477-
if (userHomePage != "about:blank")
428+
this.profilePreferences.SetPreference("startup.homepage_welcome_url", string.Empty);
429+
if (homePage != "about:blank")
478430
{
479-
AddDefaultPreference(prefs, "browser.startup.page", "1");
431+
this.profilePreferences.SetPreference("browser.startup.page", 1);
480432
}
481433
}
482434

483-
this.WriteNewPreferences(prefs);
435+
this.profilePreferences.WriteToFile(userPrefs);
436+
}
437+
438+
private void ReadDefaultPreferences()
439+
{
440+
using (Stream defaultPrefsStream = ResourceUtilities.GetResourceStream("webdriver.json", "WebDriver.FirefoxPreferences"))
441+
{
442+
using (StreamReader reader = new StreamReader(defaultPrefsStream))
443+
{
444+
string defaultPreferences = reader.ReadToEnd();
445+
Dictionary<string, object> deserializedPreferences = JsonConvert.DeserializeObject<Dictionary<string, object>>(defaultPreferences, new ResponseValueJsonConverter());
446+
Dictionary<string, object> immutableDefaultPreferences = deserializedPreferences["frozen"] as Dictionary<string, object>;
447+
Dictionary<string, object> editableDefaultPreferences = deserializedPreferences["mutable"] as Dictionary<string, object>;
448+
this.profilePreferences = new Preferences(immutableDefaultPreferences, editableDefaultPreferences);
449+
}
450+
}
484451
}
485452

486453
/// <summary>
@@ -522,22 +489,6 @@ private Dictionary<string, string> ReadExistingPreferences()
522489
return prefs;
523490
}
524491

525-
/// <summary>
526-
/// Writes the specified preferences to the user preferences file.
527-
/// </summary>
528-
/// <param name="preferences">A <see cref="Dictionary{K, V}"/> containing key-value pairs
529-
/// representing the preferences to write.</param>
530-
private void WriteNewPreferences(Dictionary<string, string> preferences)
531-
{
532-
using (TextWriter writer = File.CreateText(Path.Combine(this.profileDir, UserPreferencesFileName)))
533-
{
534-
foreach (string prefKey in preferences.Keys)
535-
{
536-
writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "user_pref(\"{0}\", {1});", prefKey, preferences[prefKey]));
537-
}
538-
}
539-
}
540-
541492
/// <summary>
542493
/// Sets a preference for a manually specified proxy.
543494
/// </summary>

0 commit comments

Comments
 (0)