Skip to content

Commit 5c5ee6e

Browse files
committed
Updating .NET Options classes to better support W3C Capabilities
1 parent 3440b61 commit 5c5ee6e

File tree

9 files changed

+419
-254
lines changed

9 files changed

+419
-254
lines changed

dotnet/src/webdriver/Chrome/ChromeOptions.cs

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ public class ChromeOptions : DriverOptions
5858
/// </summary>
5959
public static readonly string Capability = "goog:chromeOptions";
6060

61+
private const string BrowserNameValue = "chrome";
62+
6163
private const string ArgumentsChromeOption = "args";
6264
private const string BinaryChromeOption = "binary";
6365
private const string ExtensionsChromeOption = "extensions";
@@ -89,7 +91,24 @@ public class ChromeOptions : DriverOptions
8991
private ChromeMobileEmulationDeviceSettings mobileEmulationDeviceSettings;
9092
private ChromePerformanceLoggingPreferences perfLoggingPreferences;
9193

92-
private Proxy proxy;
94+
public ChromeOptions() : base()
95+
{
96+
this.BrowserName = BrowserNameValue;
97+
this.AddKnownCapabilityName(ChromeOptions.Capability, "current ChromeOptions class instance");
98+
this.AddKnownCapabilityName(CapabilityType.LoggingPreferences, "SetLoggingPreference method");
99+
this.AddKnownCapabilityName(ChromeOptions.ArgumentsChromeOption, "AddArguments method");
100+
this.AddKnownCapabilityName(ChromeOptions.BinaryChromeOption, "BinaryLocation property");
101+
this.AddKnownCapabilityName(ChromeOptions.ExtensionsChromeOption, "AddExtensions method");
102+
this.AddKnownCapabilityName(ChromeOptions.LocalStateChromeOption, "AddLocalStatePreference method");
103+
this.AddKnownCapabilityName(ChromeOptions.PreferencesChromeOption, "AddUserProfilePreference method");
104+
this.AddKnownCapabilityName(ChromeOptions.DetachChromeOption, "LeaveBrowserRunning property");
105+
this.AddKnownCapabilityName(ChromeOptions.DebuggerAddressChromeOption, "DebuggerAddress property");
106+
this.AddKnownCapabilityName(ChromeOptions.ExcludeSwitchesChromeOption, "AddExcludedArgument property");
107+
this.AddKnownCapabilityName(ChromeOptions.MinidumpPathChromeOption, "MinidumpPath property");
108+
this.AddKnownCapabilityName(ChromeOptions.MobileEmulationChromeOption, "EnableMobileEmulation method");
109+
this.AddKnownCapabilityName(ChromeOptions.PerformanceLoggingPreferencesChromeOption, "PerformanceLoggingPreferences property");
110+
this.AddKnownCapabilityName(ChromeOptions.WindowTypesChromeOption, "AddWindowTypes method");
111+
}
93112

94113
/// <summary>
95114
/// Gets or sets the location of the Chrome browser's binary executable file.
@@ -110,15 +129,6 @@ public bool LeaveBrowserRunning
110129
set { this.leaveBrowserRunning = value; }
111130
}
112131

113-
/// <summary>
114-
/// Gets or sets the proxy to use with this instance of Chrome.
115-
/// </summary>
116-
public Proxy Proxy
117-
{
118-
get { return this.proxy; }
119-
set { this.proxy = value; }
120-
}
121-
122132
/// <summary>
123133
/// Gets the list of arguments appended to the Chrome command line as a string array.
124134
/// </summary>
@@ -503,24 +513,10 @@ public override void AddAdditionalCapability(string capabilityName, object capab
503513
/// existing value with the new value in <paramref name="capabilityValue"/></remarks>
504514
public void AddAdditionalCapability(string capabilityName, object capabilityValue, bool isGlobalCapability)
505515
{
506-
if (capabilityName == ChromeOptions.Capability ||
507-
capabilityName == CapabilityType.Proxy ||
508-
capabilityName == CapabilityType.LoggingPreferences ||
509-
capabilityName == ChromeOptions.ArgumentsChromeOption ||
510-
capabilityName == ChromeOptions.BinaryChromeOption ||
511-
capabilityName == ChromeOptions.ExtensionsChromeOption ||
512-
capabilityName == ChromeOptions.LocalStateChromeOption ||
513-
capabilityName == ChromeOptions.PreferencesChromeOption ||
514-
capabilityName == ChromeOptions.DetachChromeOption ||
515-
capabilityName == ChromeOptions.DebuggerAddressChromeOption ||
516-
capabilityName == ChromeOptions.ExtensionsChromeOption ||
517-
capabilityName == ChromeOptions.ExcludeSwitchesChromeOption ||
518-
capabilityName == ChromeOptions.MinidumpPathChromeOption ||
519-
capabilityName == ChromeOptions.MobileEmulationChromeOption ||
520-
capabilityName == ChromeOptions.PerformanceLoggingPreferencesChromeOption ||
521-
capabilityName == ChromeOptions.WindowTypesChromeOption)
522-
{
523-
string message = string.Format(CultureInfo.InvariantCulture, "There is already an option for the {0} capability. Please use that instead.", capabilityName);
516+
if (this.IsKnownCapabilityName(capabilityName))
517+
{
518+
string typeSafeOptionName = this.GetTypeSafeOptionName(capabilityName);
519+
string message = string.Format(CultureInfo.InvariantCulture, "There is already an option for the {0} capability. Please use the {1} instead.", capabilityName, typeSafeOptionName);
524520
throw new ArgumentException(message, "capabilityName");
525521
}
526522

@@ -549,14 +545,9 @@ public override ICapabilities ToCapabilities()
549545
{
550546
Dictionary<string, object> chromeOptions = this.BuildChromeOptionsDictionary();
551547

552-
DesiredCapabilities capabilities = new DesiredCapabilities("chrome", string.Empty, new Platform(PlatformType.Any), false);
548+
DesiredCapabilities capabilities = this.GenerateDesiredCapabilities(false);
553549
capabilities.SetCapability(ChromeOptions.Capability, chromeOptions);
554550

555-
if (this.proxy != null)
556-
{
557-
capabilities.SetCapability(CapabilityType.Proxy, this.proxy);
558-
}
559-
560551
Dictionary<string, object> loggingPreferences = this.GenerateLoggingPreferencesDictionary();
561552
if (loggingPreferences != null)
562553
{

dotnet/src/webdriver/DriverOptions.cs

Lines changed: 260 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// <copyright file="DriverOptions.cs" company="WebDriver Committers">
1+
// <copyright file="DriverOptions.cs" company="WebDriver Committers">
22
// Licensed to the Software Freedom Conservancy (SFC) under one
33
// or more contributor license agreements. See the NOTICE file
44
// distributed with this work for additional information
@@ -16,17 +16,167 @@
1616
// limitations under the License.
1717
// </copyright>
1818

19+
using OpenQA.Selenium.Remote;
1920
using System;
2021
using System.Collections.Generic;
2122

2223
namespace OpenQA.Selenium
2324
{
25+
/// <summary>
26+
/// Specifies the behavior of handling unexpected alerts in the IE driver.
27+
/// </summary>
28+
public enum UnhandledPromptBehavior
29+
{
30+
/// <summary>
31+
/// Indicates the behavior is not set.
32+
/// </summary>
33+
Default,
34+
35+
/// <summary>
36+
/// Ignore unexpected alerts, such that the user must handle them.
37+
/// </summary>
38+
Ignore,
39+
40+
/// <summary>
41+
/// Accept unexpected alerts.
42+
/// </summary>
43+
Accept,
44+
45+
/// <summary>
46+
/// Dismiss unexpected alerts.
47+
/// </summary>
48+
Dismiss,
49+
50+
/// <summary>
51+
/// Accepts unexpected alerts and notifies the user that the alert has
52+
/// been accepted by throwing an <see cref="UnhandledAlertException"/>
53+
/// </summary>
54+
AcceptAndNotify,
55+
56+
/// <summary>
57+
/// Dismisses unexpected alerts and notifies the user that the alert has
58+
/// been dismissed by throwing an <see cref="UnhandledAlertException"/>
59+
/// </summary>
60+
DismissAndNotify
61+
}
62+
63+
/// <summary>
64+
/// Specifies the behavior of waiting for page loads in the driver.
65+
/// </summary>
66+
public enum PageLoadStrategy
67+
{
68+
/// <summary>
69+
/// Indicates the behavior is not set.
70+
/// </summary>
71+
Default,
72+
73+
/// <summary>
74+
/// Waits for pages to load and ready state to be 'complete'.
75+
/// </summary>
76+
Normal,
77+
78+
/// <summary>
79+
/// Waits for pages to load and for ready state to be 'interactive' or 'complete'.
80+
/// </summary>
81+
Eager,
82+
83+
/// <summary>
84+
/// Does not wait for pages to load, returning immediately.
85+
/// </summary>
86+
None
87+
}
88+
2489
/// <summary>
2590
/// Base class for managing options specific to a browser driver.
2691
/// </summary>
2792
public abstract class DriverOptions
2893
{
94+
private string browserName;
95+
private string browserVersion;
96+
private string platformName;
97+
private Proxy proxy;
98+
private bool? acceptInsecureCertificates;
99+
private UnhandledPromptBehavior unhandledPromptBehavior = UnhandledPromptBehavior.Default;
100+
private PageLoadStrategy pageLoadStrategy = PageLoadStrategy.Default;
101+
private Dictionary<string, object> additionalCapabilities = new Dictionary<string, object>();
29102
private Dictionary<string, LogLevel> loggingPreferences = new Dictionary<string, LogLevel>();
103+
private Dictionary<string, string> knownCapabilityNames = new Dictionary<string, string>();
104+
105+
protected DriverOptions()
106+
{
107+
this.AddKnownCapabilityName(CapabilityType.BrowserName, "BrowserName property");
108+
this.AddKnownCapabilityName(CapabilityType.BrowserVersion, "BrowserVersion property");
109+
this.AddKnownCapabilityName(CapabilityType.PlatformName, "PlatformName property");
110+
this.AddKnownCapabilityName(CapabilityType.Proxy, "Proxy property");
111+
this.AddKnownCapabilityName(CapabilityType.UnhandledPromptBehavior, "UnhandledPromptBehavior property");
112+
this.AddKnownCapabilityName(CapabilityType.PageLoadStrategy, "PageLoadStrategy property");
113+
}
114+
115+
/// <summary>
116+
/// Gets or sets the name of the browser.
117+
/// </summary>
118+
public string BrowserName
119+
{
120+
get { return this.browserName; }
121+
protected set { this.browserName = value; }
122+
}
123+
124+
/// <summary>
125+
/// Gets or sets the version of the browser.
126+
/// </summary>
127+
public string BrowserVersion
128+
{
129+
get { return this.browserVersion; }
130+
set { this.browserVersion = value; }
131+
}
132+
133+
/// <summary>
134+
/// Gets or sets the name of the platform on which the browser is running.
135+
/// </summary>
136+
public string PlatformName
137+
{
138+
get { return this.platformName; }
139+
set { this.platformName = value; }
140+
}
141+
142+
/// <summary>
143+
/// Gets or sets a value indicating whether the browser should accept self-signed
144+
/// SSL certificates.
145+
/// </summary>
146+
public bool? AcceptInsecureCertificates
147+
{
148+
get { return this.acceptInsecureCertificates; }
149+
set { this.acceptInsecureCertificates = value; }
150+
}
151+
152+
/// <summary>
153+
/// Gets or sets the value for describing how unexpected alerts are to be handled in the browser.
154+
/// Defaults to <see cref="UnhandledPromptBehavior.Default"/>.
155+
/// </summary>
156+
public UnhandledPromptBehavior UnhandledPromptBehavior
157+
{
158+
get { return this.unhandledPromptBehavior; }
159+
set { this.unhandledPromptBehavior = value; }
160+
}
161+
162+
/// <summary>
163+
/// Gets or sets the value for describing how the browser is to wait for pages to load in the browser.
164+
/// Defaults to <see cref="PageLoadStrategy.Default"/>.
165+
/// </summary>
166+
public PageLoadStrategy PageLoadStrategy
167+
{
168+
get { return this.pageLoadStrategy; }
169+
set { this.pageLoadStrategy = value; }
170+
}
171+
172+
/// <summary>
173+
/// Gets or sets the <see cref="Proxy"/> to be used with this browser.
174+
/// </summary>
175+
public Proxy Proxy
176+
{
177+
get { return this.proxy; }
178+
set { this.proxy = value; }
179+
}
30180

31181
/// <summary>
32182
/// Provides a means to add additional capabilities not yet added as type safe options
@@ -63,6 +213,32 @@ public void SetLoggingPreference(string logType, LogLevel logLevel)
63213
this.loggingPreferences[logType] = logLevel;
64214
}
65215

216+
/// <summary>
217+
/// Adds a known capability to the list of known capabilities and associates it
218+
/// with the type-safe property name of the options class to be used instead.
219+
/// </summary>
220+
/// <param name="capabilityName">The name of the capability.</param>
221+
/// <param name="typeSafeOptionName">The name of the option property or method to be used instead.</param>
222+
protected void AddKnownCapabilityName(string capabilityName, string typeSafeOptionName)
223+
{
224+
this.knownCapabilityNames[capabilityName] = typeSafeOptionName;
225+
}
226+
227+
protected bool IsKnownCapabilityName(string capabilityName)
228+
{
229+
return this.knownCapabilityNames.ContainsKey(capabilityName);
230+
}
231+
232+
protected string GetTypeSafeOptionName(string capabilityName)
233+
{
234+
if (this.IsKnownCapabilityName(capabilityName))
235+
{
236+
return string.Empty;
237+
}
238+
239+
return this.knownCapabilityNames[capabilityName];
240+
}
241+
66242
/// <summary>
67243
/// Generates the logging preferences dictionary for transmission as a desired capability.
68244
/// </summary>
@@ -82,5 +258,88 @@ protected Dictionary<string, object> GenerateLoggingPreferencesDictionary()
82258

83259
return loggingPreferenceCapability;
84260
}
261+
262+
protected DesiredCapabilities GenerateDesiredCapabilities(bool isSpecificationCompliant)
263+
{
264+
DesiredCapabilities capabilities = new DesiredCapabilities();
265+
ISpecificationCompliant specificationCompliantCapabilities = capabilities as ISpecificationCompliant;
266+
if (specificationCompliantCapabilities != null)
267+
{
268+
specificationCompliantCapabilities.IsSpecificationCompliant = isSpecificationCompliant;
269+
}
270+
271+
if (!string.IsNullOrEmpty(this.browserName))
272+
{
273+
capabilities.SetCapability(CapabilityType.BrowserName, this.browserName);
274+
}
275+
276+
if (!string.IsNullOrEmpty(this.browserVersion))
277+
{
278+
capabilities.SetCapability(CapabilityType.BrowserVersion, this.browserVersion);
279+
}
280+
281+
if (!string.IsNullOrEmpty(this.platformName))
282+
{
283+
capabilities.SetCapability(CapabilityType.PlatformName, this.platformName);
284+
}
285+
286+
if (this.acceptInsecureCertificates.HasValue)
287+
{
288+
capabilities.SetCapability(CapabilityType.AcceptInsecureCertificates, this.acceptInsecureCertificates);
289+
}
290+
291+
if (this.pageLoadStrategy != PageLoadStrategy.Default)
292+
{
293+
string pageLoadStrategySetting = "normal";
294+
switch (this.pageLoadStrategy)
295+
{
296+
case PageLoadStrategy.Eager:
297+
pageLoadStrategySetting = "eager";
298+
break;
299+
300+
case PageLoadStrategy.None:
301+
pageLoadStrategySetting = "none";
302+
break;
303+
}
304+
305+
capabilities.SetCapability(CapabilityType.PageLoadStrategy, pageLoadStrategySetting);
306+
}
307+
308+
if (this.UnhandledPromptBehavior != UnhandledPromptBehavior.Default)
309+
{
310+
string unhandledPropmtBehaviorSetting = "ignore";
311+
switch (this.UnhandledPromptBehavior)
312+
{
313+
case UnhandledPromptBehavior.Accept:
314+
unhandledPropmtBehaviorSetting = "accept";
315+
break;
316+
317+
case UnhandledPromptBehavior.Dismiss:
318+
unhandledPropmtBehaviorSetting = "dismiss";
319+
break;
320+
321+
case UnhandledPromptBehavior.AcceptAndNotify:
322+
unhandledPropmtBehaviorSetting = "accept and notify";
323+
break;
324+
325+
case UnhandledPromptBehavior.DismissAndNotify:
326+
unhandledPropmtBehaviorSetting = "dismiss and notify";
327+
break;
328+
}
329+
330+
capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, unhandledPropmtBehaviorSetting);
331+
}
332+
333+
if (this.Proxy != null)
334+
{
335+
Dictionary<string, object> proxyCapability = this.Proxy.ToCapability();
336+
if (proxyCapability != null)
337+
{
338+
capabilities.SetCapability(CapabilityType.Proxy, proxyCapability);
339+
}
340+
}
341+
342+
return capabilities;
343+
}
85344
}
86345
}

0 commit comments

Comments
 (0)