Skip to content

Commit

Permalink
Updating .NET Options classes to better support W3C Capabilities
Browse files Browse the repository at this point in the history
  • Loading branch information
jimevans committed Nov 2, 2017
1 parent 3440b61 commit 5c5ee6e
Show file tree
Hide file tree
Showing 9 changed files with 419 additions and 254 deletions.
59 changes: 25 additions & 34 deletions dotnet/src/webdriver/Chrome/ChromeOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ public class ChromeOptions : DriverOptions
/// </summary>
public static readonly string Capability = "goog:chromeOptions";

private const string BrowserNameValue = "chrome";

private const string ArgumentsChromeOption = "args";
private const string BinaryChromeOption = "binary";
private const string ExtensionsChromeOption = "extensions";
Expand Down Expand Up @@ -89,7 +91,24 @@ public class ChromeOptions : DriverOptions
private ChromeMobileEmulationDeviceSettings mobileEmulationDeviceSettings;
private ChromePerformanceLoggingPreferences perfLoggingPreferences;

private Proxy proxy;
public ChromeOptions() : base()
{
this.BrowserName = BrowserNameValue;
this.AddKnownCapabilityName(ChromeOptions.Capability, "current ChromeOptions class instance");
this.AddKnownCapabilityName(CapabilityType.LoggingPreferences, "SetLoggingPreference method");
this.AddKnownCapabilityName(ChromeOptions.ArgumentsChromeOption, "AddArguments method");
this.AddKnownCapabilityName(ChromeOptions.BinaryChromeOption, "BinaryLocation property");
this.AddKnownCapabilityName(ChromeOptions.ExtensionsChromeOption, "AddExtensions method");
this.AddKnownCapabilityName(ChromeOptions.LocalStateChromeOption, "AddLocalStatePreference method");
this.AddKnownCapabilityName(ChromeOptions.PreferencesChromeOption, "AddUserProfilePreference method");
this.AddKnownCapabilityName(ChromeOptions.DetachChromeOption, "LeaveBrowserRunning property");
this.AddKnownCapabilityName(ChromeOptions.DebuggerAddressChromeOption, "DebuggerAddress property");
this.AddKnownCapabilityName(ChromeOptions.ExcludeSwitchesChromeOption, "AddExcludedArgument property");
this.AddKnownCapabilityName(ChromeOptions.MinidumpPathChromeOption, "MinidumpPath property");
this.AddKnownCapabilityName(ChromeOptions.MobileEmulationChromeOption, "EnableMobileEmulation method");
this.AddKnownCapabilityName(ChromeOptions.PerformanceLoggingPreferencesChromeOption, "PerformanceLoggingPreferences property");
this.AddKnownCapabilityName(ChromeOptions.WindowTypesChromeOption, "AddWindowTypes method");
}

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

/// <summary>
/// Gets or sets the proxy to use with this instance of Chrome.
/// </summary>
public Proxy Proxy
{
get { return this.proxy; }
set { this.proxy = value; }
}

/// <summary>
/// Gets the list of arguments appended to the Chrome command line as a string array.
/// </summary>
Expand Down Expand Up @@ -503,24 +513,10 @@ public override void AddAdditionalCapability(string capabilityName, object capab
/// existing value with the new value in <paramref name="capabilityValue"/></remarks>
public void AddAdditionalCapability(string capabilityName, object capabilityValue, bool isGlobalCapability)
{
if (capabilityName == ChromeOptions.Capability ||
capabilityName == CapabilityType.Proxy ||
capabilityName == CapabilityType.LoggingPreferences ||
capabilityName == ChromeOptions.ArgumentsChromeOption ||
capabilityName == ChromeOptions.BinaryChromeOption ||
capabilityName == ChromeOptions.ExtensionsChromeOption ||
capabilityName == ChromeOptions.LocalStateChromeOption ||
capabilityName == ChromeOptions.PreferencesChromeOption ||
capabilityName == ChromeOptions.DetachChromeOption ||
capabilityName == ChromeOptions.DebuggerAddressChromeOption ||
capabilityName == ChromeOptions.ExtensionsChromeOption ||
capabilityName == ChromeOptions.ExcludeSwitchesChromeOption ||
capabilityName == ChromeOptions.MinidumpPathChromeOption ||
capabilityName == ChromeOptions.MobileEmulationChromeOption ||
capabilityName == ChromeOptions.PerformanceLoggingPreferencesChromeOption ||
capabilityName == ChromeOptions.WindowTypesChromeOption)
{
string message = string.Format(CultureInfo.InvariantCulture, "There is already an option for the {0} capability. Please use that instead.", capabilityName);
if (this.IsKnownCapabilityName(capabilityName))
{
string typeSafeOptionName = this.GetTypeSafeOptionName(capabilityName);
string message = string.Format(CultureInfo.InvariantCulture, "There is already an option for the {0} capability. Please use the {1} instead.", capabilityName, typeSafeOptionName);
throw new ArgumentException(message, "capabilityName");
}

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

DesiredCapabilities capabilities = new DesiredCapabilities("chrome", string.Empty, new Platform(PlatformType.Any), false);
DesiredCapabilities capabilities = this.GenerateDesiredCapabilities(false);
capabilities.SetCapability(ChromeOptions.Capability, chromeOptions);

if (this.proxy != null)
{
capabilities.SetCapability(CapabilityType.Proxy, this.proxy);
}

Dictionary<string, object> loggingPreferences = this.GenerateLoggingPreferencesDictionary();
if (loggingPreferences != null)
{
Expand Down
261 changes: 260 additions & 1 deletion dotnet/src/webdriver/DriverOptions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="DriverOptions.cs" company="WebDriver Committers">
// <copyright file="DriverOptions.cs" company="WebDriver Committers">
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
Expand All @@ -16,17 +16,167 @@
// limitations under the License.
// </copyright>

using OpenQA.Selenium.Remote;
using System;
using System.Collections.Generic;

namespace OpenQA.Selenium
{
/// <summary>
/// Specifies the behavior of handling unexpected alerts in the IE driver.
/// </summary>
public enum UnhandledPromptBehavior
{
/// <summary>
/// Indicates the behavior is not set.
/// </summary>
Default,

/// <summary>
/// Ignore unexpected alerts, such that the user must handle them.
/// </summary>
Ignore,

/// <summary>
/// Accept unexpected alerts.
/// </summary>
Accept,

/// <summary>
/// Dismiss unexpected alerts.
/// </summary>
Dismiss,

/// <summary>
/// Accepts unexpected alerts and notifies the user that the alert has
/// been accepted by throwing an <see cref="UnhandledAlertException"/>
/// </summary>
AcceptAndNotify,

/// <summary>
/// Dismisses unexpected alerts and notifies the user that the alert has
/// been dismissed by throwing an <see cref="UnhandledAlertException"/>
/// </summary>
DismissAndNotify
}

/// <summary>
/// Specifies the behavior of waiting for page loads in the driver.
/// </summary>
public enum PageLoadStrategy
{
/// <summary>
/// Indicates the behavior is not set.
/// </summary>
Default,

/// <summary>
/// Waits for pages to load and ready state to be 'complete'.
/// </summary>
Normal,

/// <summary>
/// Waits for pages to load and for ready state to be 'interactive' or 'complete'.
/// </summary>
Eager,

/// <summary>
/// Does not wait for pages to load, returning immediately.
/// </summary>
None
}

/// <summary>
/// Base class for managing options specific to a browser driver.
/// </summary>
public abstract class DriverOptions
{
private string browserName;
private string browserVersion;
private string platformName;
private Proxy proxy;
private bool? acceptInsecureCertificates;
private UnhandledPromptBehavior unhandledPromptBehavior = UnhandledPromptBehavior.Default;
private PageLoadStrategy pageLoadStrategy = PageLoadStrategy.Default;
private Dictionary<string, object> additionalCapabilities = new Dictionary<string, object>();
private Dictionary<string, LogLevel> loggingPreferences = new Dictionary<string, LogLevel>();
private Dictionary<string, string> knownCapabilityNames = new Dictionary<string, string>();

protected DriverOptions()
{
this.AddKnownCapabilityName(CapabilityType.BrowserName, "BrowserName property");
this.AddKnownCapabilityName(CapabilityType.BrowserVersion, "BrowserVersion property");
this.AddKnownCapabilityName(CapabilityType.PlatformName, "PlatformName property");
this.AddKnownCapabilityName(CapabilityType.Proxy, "Proxy property");
this.AddKnownCapabilityName(CapabilityType.UnhandledPromptBehavior, "UnhandledPromptBehavior property");
this.AddKnownCapabilityName(CapabilityType.PageLoadStrategy, "PageLoadStrategy property");
}

/// <summary>
/// Gets or sets the name of the browser.
/// </summary>
public string BrowserName
{
get { return this.browserName; }
protected set { this.browserName = value; }
}

/// <summary>
/// Gets or sets the version of the browser.
/// </summary>
public string BrowserVersion
{
get { return this.browserVersion; }
set { this.browserVersion = value; }
}

/// <summary>
/// Gets or sets the name of the platform on which the browser is running.
/// </summary>
public string PlatformName
{
get { return this.platformName; }
set { this.platformName = value; }
}

/// <summary>
/// Gets or sets a value indicating whether the browser should accept self-signed
/// SSL certificates.
/// </summary>
public bool? AcceptInsecureCertificates
{
get { return this.acceptInsecureCertificates; }
set { this.acceptInsecureCertificates = value; }
}

/// <summary>
/// Gets or sets the value for describing how unexpected alerts are to be handled in the browser.
/// Defaults to <see cref="UnhandledPromptBehavior.Default"/>.
/// </summary>
public UnhandledPromptBehavior UnhandledPromptBehavior
{
get { return this.unhandledPromptBehavior; }
set { this.unhandledPromptBehavior = value; }
}

/// <summary>
/// Gets or sets the value for describing how the browser is to wait for pages to load in the browser.
/// Defaults to <see cref="PageLoadStrategy.Default"/>.
/// </summary>
public PageLoadStrategy PageLoadStrategy
{
get { return this.pageLoadStrategy; }
set { this.pageLoadStrategy = value; }
}

/// <summary>
/// Gets or sets the <see cref="Proxy"/> to be used with this browser.
/// </summary>
public Proxy Proxy
{
get { return this.proxy; }
set { this.proxy = value; }
}

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

/// <summary>
/// Adds a known capability to the list of known capabilities and associates it
/// with the type-safe property name of the options class to be used instead.
/// </summary>
/// <param name="capabilityName">The name of the capability.</param>
/// <param name="typeSafeOptionName">The name of the option property or method to be used instead.</param>
protected void AddKnownCapabilityName(string capabilityName, string typeSafeOptionName)
{
this.knownCapabilityNames[capabilityName] = typeSafeOptionName;
}

protected bool IsKnownCapabilityName(string capabilityName)
{
return this.knownCapabilityNames.ContainsKey(capabilityName);
}

protected string GetTypeSafeOptionName(string capabilityName)
{
if (this.IsKnownCapabilityName(capabilityName))
{
return string.Empty;
}

return this.knownCapabilityNames[capabilityName];
}

/// <summary>
/// Generates the logging preferences dictionary for transmission as a desired capability.
/// </summary>
Expand All @@ -82,5 +258,88 @@ protected Dictionary<string, object> GenerateLoggingPreferencesDictionary()

return loggingPreferenceCapability;
}

protected DesiredCapabilities GenerateDesiredCapabilities(bool isSpecificationCompliant)
{
DesiredCapabilities capabilities = new DesiredCapabilities();
ISpecificationCompliant specificationCompliantCapabilities = capabilities as ISpecificationCompliant;
if (specificationCompliantCapabilities != null)
{
specificationCompliantCapabilities.IsSpecificationCompliant = isSpecificationCompliant;
}

if (!string.IsNullOrEmpty(this.browserName))
{
capabilities.SetCapability(CapabilityType.BrowserName, this.browserName);
}

if (!string.IsNullOrEmpty(this.browserVersion))
{
capabilities.SetCapability(CapabilityType.BrowserVersion, this.browserVersion);
}

if (!string.IsNullOrEmpty(this.platformName))
{
capabilities.SetCapability(CapabilityType.PlatformName, this.platformName);
}

if (this.acceptInsecureCertificates.HasValue)
{
capabilities.SetCapability(CapabilityType.AcceptInsecureCertificates, this.acceptInsecureCertificates);
}

if (this.pageLoadStrategy != PageLoadStrategy.Default)
{
string pageLoadStrategySetting = "normal";
switch (this.pageLoadStrategy)
{
case PageLoadStrategy.Eager:
pageLoadStrategySetting = "eager";
break;

case PageLoadStrategy.None:
pageLoadStrategySetting = "none";
break;
}

capabilities.SetCapability(CapabilityType.PageLoadStrategy, pageLoadStrategySetting);
}

if (this.UnhandledPromptBehavior != UnhandledPromptBehavior.Default)
{
string unhandledPropmtBehaviorSetting = "ignore";
switch (this.UnhandledPromptBehavior)
{
case UnhandledPromptBehavior.Accept:
unhandledPropmtBehaviorSetting = "accept";
break;

case UnhandledPromptBehavior.Dismiss:
unhandledPropmtBehaviorSetting = "dismiss";
break;

case UnhandledPromptBehavior.AcceptAndNotify:
unhandledPropmtBehaviorSetting = "accept and notify";
break;

case UnhandledPromptBehavior.DismissAndNotify:
unhandledPropmtBehaviorSetting = "dismiss and notify";
break;
}

capabilities.SetCapability(CapabilityType.UnhandledPromptBehavior, unhandledPropmtBehaviorSetting);
}

if (this.Proxy != null)
{
Dictionary<string, object> proxyCapability = this.Proxy.ToCapability();
if (proxyCapability != null)
{
capabilities.SetCapability(CapabilityType.Proxy, proxyCapability);
}
}

return capabilities;
}
}
}
Loading

0 comments on commit 5c5ee6e

Please sign in to comment.