Created
September 9, 2019 17:34
-
-
Save jimevans/9a23c1bcfd516f776c80b91564010d15 to your computer and use it in GitHub Desktop.
SauceLabs type-safe options creator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| SauceLabsSessionOptions sauceOptions = new SauceLabsSessionOptions(); | |
| sauceOptions.UserName = "username"; | |
| sauceOptions.AccessKey = "accessKey"; | |
| ChromeOptions options = new ChromeOptions(); | |
| options.AddAdditionalOption(SauceLabsSessionOptions.SauceOptionsOptionName, sauceOptions.ToDictionary()); | |
| IWebDriver driver = new RemoteWebDriver(new Uri("https://ondemand.saucelabs.com/wd/hub"), options); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| namespace SauceLabs | |
| { | |
| /// <summary> | |
| /// Represents the visibility levels of SauceLabs jobs. | |
| /// </summary> | |
| public enum SauceLabsJobVisibility | |
| { | |
| /// <summary> | |
| /// Job visibility is unspecified. | |
| /// </summary> | |
| Default, | |
| /// <summary> | |
| /// Job is accessible to everyone, and may be listed on public web pages and indexed by search engines. | |
| /// </summary> | |
| Public, | |
| /// <summary> | |
| /// Job video and result page are accessible to everyone, but logs are kept private. | |
| /// </summary> | |
| PublicRestricted, | |
| /// <summary> | |
| /// Job is only accessible to people having valid link and it is not listed on publicly available pages | |
| /// or indexed by search engines. | |
| /// </summary> | |
| Share, | |
| /// <summary> | |
| /// Job is only accessible to people under the same root account as the job . | |
| /// </summary> | |
| Team, | |
| /// <summary> | |
| /// Job is only accessible to the job owner. | |
| /// </summary> | |
| Private, | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| namespace SauceLabs | |
| { | |
| /// <summary> | |
| /// This class defines the options that can be set for an executable to be run | |
| /// before a test starts in a SauceLabs session. | |
| /// </summary> | |
| public class SauceLabsPreRunExecutableOptions | |
| { | |
| private List<object> arguments = new List<object>(); | |
| /// <summary> | |
| /// Initializes a new instance of the <see cref="SauceLabsPreRunExecutableOptions"/> class. | |
| /// </summary> | |
| /// <param name="urlToExecutable">The URL to an executable file to be downloaded and executed before the test starts.</param> | |
| public SauceLabsPreRunExecutableOptions(string urlToExecutable) | |
| { | |
| if (string.IsNullOrEmpty(urlToExecutable)) | |
| { | |
| throw new ArgumentNullException("urlToExecutable", "Executable path must not be null or the empty string"); | |
| } | |
| this.Executable = urlToExecutable; | |
| } | |
| /// <summary> | |
| /// Gets the URL of the executable to be downloaded and executed before the test starts. | |
| /// </summary> | |
| public string Executable { get; } | |
| /// <summary> | |
| /// Gets or sets a value indicating whether SauceLabs should wait for this executable | |
| /// to finish before the browser session starts. | |
| /// </summary> | |
| public bool RunInBackground { get; set; } | |
| /// <summary> | |
| /// Gets or sets the number of seconds SauceLabs will wait for the executable | |
| /// to finish before the browser session starts. | |
| /// </summary> | |
| public int Timeout { get; set; } | |
| /// <summary> | |
| /// Adds an argument to the command line of the executable. | |
| /// </summary> | |
| /// <param name="arg">The argument to add to the command line.</param> | |
| public void AddArgument(string arg) | |
| { | |
| if (string.IsNullOrEmpty(arg)) | |
| { | |
| throw new ArgumentNullException("arg", "Argument cannot be null or the empty string"); | |
| } | |
| this.AddArguments(arg); | |
| } | |
| /// <summary> | |
| /// Adds a set of arguments to the command line of the executable. | |
| /// </summary> | |
| /// <param name="args">The arguments to add to the command line.</param> | |
| public void AddArguments(params string[] args) | |
| { | |
| this.AddArguments(args); | |
| } | |
| /// <summary> | |
| /// Adds a set of arguments to the command line of the executable. | |
| /// </summary> | |
| /// <param name="args">The arguments to add to the command line.</param> | |
| public void AddArguments(IEnumerable<string> args) | |
| { | |
| foreach (string arg in args) | |
| { | |
| if (string.IsNullOrEmpty(arg)) | |
| { | |
| throw new ArgumentNullException("Argument to be added cannot be null or the empty string"); | |
| } | |
| this.arguments.Add(arg); | |
| } | |
| } | |
| /// <summary> | |
| /// Converts this <see cref="SauceLabsPreRunExecutableOptions"/> instance to a dictionary to be added | |
| /// to a set of options for creating a session on SauceLabs. | |
| /// </summary> | |
| /// <returns> | |
| /// A <see cref="Dictionary{String, Object}"/> containing the settings for the executable | |
| ///to be downloaded and run before a test starts. | |
| /// </returns> | |
| public Dictionary<string, object> ToDictionary() | |
| { | |
| Dictionary<string, object> toReturn = new Dictionary<string, object>(); | |
| toReturn["executable"] = this.Executable; | |
| if (this.arguments.Count > 0) | |
| { | |
| toReturn["args"] = this.arguments.ToArray(); | |
| } | |
| if (this.RunInBackground) | |
| { | |
| toReturn["background"] = true; | |
| } | |
| if (this.Timeout > 0) | |
| { | |
| toReturn["timeout"] = this.Timeout; | |
| } | |
| return toReturn; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| namespace SauceLabs | |
| { | |
| /// <summary> | |
| /// This class defines the options that can be set for a SauceLabs session. | |
| /// </summary> | |
| public class SauceLabsSessionOptions | |
| { | |
| /// <summary> | |
| /// The option name to be used in setting the SauceLabs options when creating a new session. | |
| /// </summary> | |
| public static readonly string SauceOptionsOptionName = "sauce:options"; | |
| private static readonly string UserNameOptionName = "username"; | |
| private static readonly string AccessKeyOptionName = "accessKey"; | |
| private static readonly string AppiumVersionOptionName = "appiumVersion"; | |
| private static readonly string SeleniumVersionOptionName = "seleniumVersion"; | |
| private static readonly string ChromeDriverVersionOptionName = "chromedriverVersion"; | |
| private static readonly string IEDriverVersionOptionName = "iedriverVersion"; | |
| private static readonly string ScreenResolutionOptionName = "screenResolution"; | |
| private static readonly string RecordVideoOptionName = "recordVideo"; | |
| private static readonly string RecordScreenshotsOptionName = "recordScrenshots"; | |
| private static readonly string RecordLogsOptionName = "recordLogs"; | |
| private static readonly string VideoUploadOnPassOptionName = "videoUploadOnPass"; | |
| private static readonly string TestNameOptionName = "name"; | |
| private static readonly string BuildOptionName = "build"; | |
| private static readonly string TagsOptionName = "tags"; | |
| private static readonly string PassedOptionName = "passed"; | |
| private static readonly string MaximumTestDurationOptionName = "maxDuration"; | |
| private static readonly string CommandTimeoutOptionName = "commandTimeout"; | |
| private static readonly string IdleTestTimeoutOptionName = "idleTimeout"; | |
| private static readonly string TunnelIdentifierOptionName = "tunnelIdentifier"; | |
| private static readonly string ParentTunnelOptionName = "parentTunnel"; | |
| private static readonly string TimeZoneOptionName = "timeZone"; | |
| private static readonly string AvoidProxyOptionName = "avoidProxy"; | |
| private static readonly string JobVisibilityOptionName = "public"; | |
| private static readonly string PriorityOptionName = "priority"; | |
| private static readonly string ExtendedDebuggingOptionName = "extendedDebugging"; | |
| private static readonly string CustomDataOptionName = "custom-data"; | |
| private static readonly string PrerunOptionName = "prerun"; | |
| private SauceLabsJobVisibility jobVisibility = SauceLabsJobVisibility.Default; | |
| private bool enableVideoRecording = true; | |
| private bool enableScreenshots = true; | |
| private bool enableVideoUploadOnPass = true; | |
| private bool enableLogs = true; | |
| private int priority = -1; | |
| private List<object> tags = new List<object>(); | |
| private Dictionary<string, object> customData; | |
| /// <summary> | |
| /// Gets or sets the SauceLabs user name used to create the session. | |
| /// </summary> | |
| public string UserName { get; set; } | |
| /// <summary> | |
| /// Gets or sets the SauceLabs access key used to create the session. | |
| /// </summary> | |
| public string AccessKey { get; set; } | |
| /// <summary> | |
| /// Gets or sets the version of Appium to be used during the session. | |
| /// </summary> | |
| public string AppiumVersion { get; set; } | |
| /// <summary> | |
| /// Gets or sets the version of Selenium to be used during the session. | |
| /// </summary> | |
| public string SeleniumVersion { get; set; } | |
| /// <summary> | |
| /// Gets or sets the version of chromedriver.exe to be used during the session. | |
| /// </summary> | |
| public string ChromeDriverVersion { get; set; } | |
| /// <summary> | |
| /// Gets or sets the version of IEDriverServer.exe to be used during the session. | |
| /// </summary> | |
| public string IEDriverVersion { get; set; } | |
| /// <summary> | |
| /// Gets or sets the screen resolution to be used during the session. | |
| /// </summary> | |
| public string ScreenResolution { get; set; } | |
| /// <summary> | |
| /// Gets or sets a value indicating whether to record video during the session. | |
| /// </summary> | |
| public bool RecordVideo | |
| { | |
| get { return this.enableVideoRecording; } | |
| set { this.enableVideoRecording = value; } | |
| } | |
| /// <summary> | |
| /// Gets or sets a value indicating whether to record screenshots during the session. | |
| /// </summary> | |
| public bool RecordScreenshots | |
| { | |
| get { return this.enableScreenshots; } | |
| set { this.enableScreenshots = value; } | |
| } | |
| /// <summary> | |
| /// Gets or sets a value indicating whether to record logs during the session. | |
| /// </summary> | |
| public bool RecordLogs | |
| { | |
| get { return this.enableLogs; } | |
| set { this.enableLogs = value; } | |
| } | |
| /// <summary> | |
| /// Gets or sets a value indicating whether to upload a video of the session if the test passes. | |
| /// </summary> | |
| public bool VideoUploadOnPass | |
| { | |
| get { return this.enableVideoUploadOnPass; } | |
| set { this.enableVideoUploadOnPass = value; } | |
| } | |
| /// <summary> | |
| /// Gets or sets a value indicating whether to record HAR files for some | |
| /// browsers as well as console.json logs during the session. | |
| /// </summary> | |
| public bool ExtendedDebugging { get; set; } | |
| /// <summary> | |
| /// Gets or sets a user-defined name for tests. | |
| /// </summary> | |
| public string TestName { get; set; } | |
| /// <summary> | |
| /// Gets or sets a user-defined identifier for the build against which the session is executed. | |
| /// </summary> | |
| public string Build { get; set; } | |
| /// <summary> | |
| /// Gets or sets a value indicating whether to record the pass/fail status of the test on SauceLabs. | |
| /// </summary> | |
| public bool? IsPassed { get; set; } | |
| /// <summary> | |
| /// Gets or sets the maximum test duration, in seconds. | |
| /// </summary> | |
| public int MaximumTestDuration { get; set; } | |
| /// <summary> | |
| /// Gets or sets the command timeout, in seconds. | |
| /// </summary> | |
| public int CommandTimeout { get; set; } | |
| /// <summary> | |
| /// Gets or sets the amount of time, in seconds, between commands that indicate an idle session | |
| /// that should be terminated. | |
| /// </summary> | |
| public int IdleTestTimeout { get; set; } | |
| /// <summary> | |
| /// Gets or sets the identifier for the SauceConnect tunnel to use during the session. | |
| /// </summary> | |
| public string TunnelIdentifier { get; set; } | |
| /// <summary> | |
| /// Gets or sets the identifier of a user name for a shared SauceConnect tunnel to use during the session. | |
| /// </summary> | |
| public string ParentTunnel { get; set; } | |
| /// <summary> | |
| /// Gets or sets the time zone to set in the SauceLabs virtual machine during the session. | |
| /// </summary> | |
| public string TimeZone { get; set; } | |
| /// <summary> | |
| /// Gets or sets a value indicating whether to avoid routing traffic through the Selenium HTTP proxy. | |
| /// </summary> | |
| public bool? AvoidProxy { get; set; } | |
| /// <summary> | |
| /// Gets or sets the priority of the session. | |
| /// </summary> | |
| public int Priority | |
| { | |
| get { return this.priority; } | |
| set | |
| { | |
| if (value < 0) | |
| { | |
| throw new ArgumentException("Priority must be greater than or equal to zero"); | |
| } | |
| this.priority = value; | |
| } | |
| } | |
| /// <summary> | |
| /// Gets or sets the visibility of the results of the session. | |
| /// </summary> | |
| public SauceLabsJobVisibility JobVisibility | |
| { | |
| get { return this.jobVisibility; } | |
| set { this.jobVisibility = value; } | |
| } | |
| /// <summary> | |
| /// Gets or sets the information about the executable to run before the test starts on SauceLabs. | |
| /// </summary> | |
| public SauceLabsPreRunExecutableOptions PreRunExecutable { get; set; } | |
| /// <summary> | |
| /// Adds a tag to the SauceLabs job. | |
| /// </summary> | |
| /// <param name="tagToAdd">The tag to add to the job.</param> | |
| public void AddTag(string tagToAdd) | |
| { | |
| if (string.IsNullOrEmpty(tagToAdd)) | |
| { | |
| throw new ArgumentNullException("tagToAdd", "tagToAdd cannot be null or the empty string"); | |
| } | |
| this.AddTags(tagToAdd); | |
| } | |
| /// <summary> | |
| /// Adds a set of tags to the SauceLabs job. | |
| /// </summary> | |
| /// <param name="tagsToAdd">The tags to add to the job.</param> | |
| public void AddTags(params string[] tagsToAdd) | |
| { | |
| this.AddTags(tagsToAdd); | |
| } | |
| /// <summary> | |
| /// Adds a set of tags to the SauceLabs job. | |
| /// </summary> | |
| /// <param name="tagsToAdd">The tags to add to the job.</param> | |
| public void AddTags(IEnumerable<string> tagsToAdd) | |
| { | |
| foreach(string tag in tagsToAdd) | |
| { | |
| if (string.IsNullOrEmpty(tag)) | |
| { | |
| throw new ArgumentNullException("Tag to be added cannot be null or the empty string"); | |
| } | |
| this.tags.Add(tag); | |
| } | |
| } | |
| /// <summary> | |
| /// Sets user-defined custom data to be used in the session. | |
| /// </summary> | |
| /// <param name="customData"></param> | |
| public void SetCustomData(Dictionary<string, object> customData) | |
| { | |
| if (customData == null) | |
| { | |
| throw new ArgumentNullException("customData", "Custom data cannot be null"); | |
| } | |
| this.customData = customData; | |
| } | |
| /// <summary> | |
| /// Converts this <see cref="SauceLabsSessionOptions"/> instance to a dictionary to be added | |
| /// to a set of options for creating a session on SauceLabs. | |
| /// </summary> | |
| /// <returns> | |
| /// A <see cref="Dictionary{String, Object}"/> containing the SauceLabs-specific | |
| /// settings for a session. | |
| /// </returns> | |
| public virtual Dictionary<string, object> ToDictionary() | |
| { | |
| Dictionary<string, object> options = new Dictionary<string, object>(); | |
| if (!string.IsNullOrEmpty(this.UserName)) | |
| { | |
| options[UserNameOptionName] = this.UserName; | |
| } | |
| if (!string.IsNullOrEmpty(this.AccessKey)) | |
| { | |
| options[AccessKeyOptionName] = this.AccessKey; | |
| } | |
| if (!string.IsNullOrEmpty(this.AppiumVersion)) | |
| { | |
| options[AppiumVersionOptionName] = this.AppiumVersion; | |
| } | |
| if (!string.IsNullOrEmpty(this.SeleniumVersion)) | |
| { | |
| options[SeleniumVersionOptionName] = this.SeleniumVersion; | |
| } | |
| if (!string.IsNullOrEmpty(this.ChromeDriverVersion)) | |
| { | |
| options[ChromeDriverVersionOptionName] = this.ChromeDriverVersion; | |
| } | |
| if (!string.IsNullOrEmpty(this.IEDriverVersion)) | |
| { | |
| options[IEDriverVersionOptionName] = this.IEDriverVersion; | |
| } | |
| if (!string.IsNullOrEmpty(this.ScreenResolution)) | |
| { | |
| options[ScreenResolutionOptionName] = this.ScreenResolution; | |
| } | |
| if (!this.enableVideoRecording) | |
| { | |
| options[RecordVideoOptionName] = false; | |
| } | |
| if (!this.enableScreenshots) | |
| { | |
| options[RecordScreenshotsOptionName] = false; | |
| } | |
| if (!this.enableVideoUploadOnPass) | |
| { | |
| options[VideoUploadOnPassOptionName] = false; | |
| } | |
| if (!this.enableLogs) | |
| { | |
| options[RecordLogsOptionName] = false; | |
| } | |
| if (!string.IsNullOrEmpty(this.TestName)) | |
| { | |
| options[TestNameOptionName] = this.TestName; | |
| } | |
| if (!string.IsNullOrEmpty(this.Build)) | |
| { | |
| options[BuildOptionName] = this.Build; | |
| } | |
| if (this.tags.Count > 0) | |
| { | |
| options[TagsOptionName] = this.tags.ToArray(); | |
| } | |
| if (this.IsPassed.HasValue) | |
| { | |
| options[PassedOptionName] = this.IsPassed.Value; | |
| } | |
| if (this.MaximumTestDuration > 0) | |
| { | |
| options[MaximumTestDurationOptionName] = this.MaximumTestDuration; | |
| } | |
| if (this.CommandTimeout > 0) | |
| { | |
| options[CommandTimeoutOptionName] = this.CommandTimeout; | |
| } | |
| if (this.IdleTestTimeout > 0) | |
| { | |
| options[IdleTestTimeoutOptionName] = this.IdleTestTimeout; | |
| } | |
| if (!string.IsNullOrEmpty(this.TunnelIdentifier)) | |
| { | |
| options[TunnelIdentifierOptionName] = this.TunnelIdentifier; | |
| } | |
| if (!string.IsNullOrEmpty(this.ParentTunnel)) | |
| { | |
| if (string.IsNullOrEmpty(this.TunnelIdentifier)) | |
| { | |
| throw new InvalidOperationException("When specifying a parent tunnel, a tunnel identifier must also be specified."); | |
| } | |
| options[ParentTunnelOptionName] = this.ParentTunnel; | |
| } | |
| if (!string.IsNullOrEmpty(this.TimeZone)) | |
| { | |
| options[TimeZoneOptionName] = this.TimeZone; | |
| } | |
| if (this.AvoidProxy.HasValue) | |
| { | |
| options[AvoidProxyOptionName] = this.AvoidProxy.Value; | |
| } | |
| if (this.jobVisibility != SauceLabsJobVisibility.Default) | |
| { | |
| if (this.jobVisibility == SauceLabsJobVisibility.PublicRestricted) | |
| { | |
| options[JobVisibilityOptionName] = "public restricted"; | |
| } | |
| else | |
| { | |
| options[JobVisibilityOptionName] = this.jobVisibility.ToString().ToLowerInvariant(); | |
| } | |
| } | |
| if (this.priority >= 0) | |
| { | |
| options[PriorityOptionName] = this.priority; | |
| } | |
| if (this.ExtendedDebugging) | |
| { | |
| options[ExtendedDebuggingOptionName] = this.ExtendedDebugging; | |
| } | |
| if (this.customData != null) | |
| { | |
| options[CustomDataOptionName] = this.customData; | |
| } | |
| if (this.PreRunExecutable != null) | |
| { | |
| options[PrerunOptionName] = this.PreRunExecutable.ToDictionary(); | |
| } | |
| return options; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment