Search code examples
c#seleniumproxysaucelabsremotewebdriver

Saucelabs Selenium not using proxy details for RemoteWebDriver (C#)


I'm using the Saucelabs Selenium implementation to automate my testing across multiple devices and platforms.

Using the demo code from SauceLabs (below) doesn't work behind a proxy.

I've tried adding the proxy details to the DesiredCapibilities but this doesn't seem to do anything

[TestMethod]
public void TestSauceLabs()
{
    DesiredCapabilities caps = new DesiredCapabilities();
    caps.SetCapability("browserName", "Safari");
    caps.SetCapability("platform", "macOS 10.13");
    caps.SetCapability("version", "11.1");
    caps.SetCapability("username", _sauceUserName);
    caps.SetCapability("accessKey", _sauceAccessKey);
    caps.SetCapability("name", _name);

    var tags = new List<string> {"demoTest", "sauceDemo"};
    caps.SetCapability("tags", tags);
    caps.SetCapability("maxDuration", 3600);
    caps.SetCapability("commandTimeout", 600);
    caps.SetCapability("idleTimeout", 1000);
    caps.SetCapability("build", "SauceDemo");

    /****************************************
     * Edited demo code here
     * Added proxy config to DesiredCapabilities **
     */
    var proxy = new Proxy
    {
        IsAutoDetect = false,
        HttpProxy = $"{_proxyScheme}://{_proxyHost}:{_proxyPort}",
        SslProxy = $"{_proxyScheme}://{_proxyHost}:{_proxyPort}",
        FtpProxy = $"{_proxyScheme}://{_proxyHost}:{_proxyPort}"
    };
    caps.SetCapability(CapabilityType.Proxy, proxy);
    /*
     *****************************************/

    var uri = new Uri("https://ondemand.eu-central-1.saucelabs.com/wd/hub");
    _driver = new RemoteWebDriver(uri,
        caps, TimeSpan.FromSeconds(600));

    _javascriptExecutor = ((IJavaScriptExecutor) _driver);

    _javascriptExecutor.ExecuteScript("sauce:context=Open SauceDemo.com");
    _driver.Navigate().GoToUrl(_url);

    _javascriptExecutor.ExecuteScript("sauce:context=Sleep for 10000ms");
    Thread.Sleep(10000);
    Assert.IsTrue(true);

    var passed = true;
    _javascriptExecutor.ExecuteScript("sauce:job-result=" + (passed ? "passed" : "failed"));
    _driver?.Quit();
}


Solution

  • Found the solution was to use the HttpCommandExecutor when using the RemoteWebDriver behind a proxy.

    Here is my example code:

    
    [TestMethod]
    public void TestSauceLabs_Chrome()
    {
        var remoteOptions = new Dictionary<string, object>
        {
            { "username", _sauceUserName },
            { "accessKey", _sauceAccessKey },
            { "name", _name },
            { "maxDuration", 3600 },
            { "commandTimeout", 600 },
            { "idleTimeout", 1000 }
        };
    
        var options = new ChromeOptions()
        {
            PlatformName = "Windows 10",
            BrowserVersion = "latest"
        };
    
        //Remote options need to be global
        options.AddAdditionalCapability("sauce:options", remoteOptions, true);
    
        var caps = options.ToCapabilities();
    
        /*
         Using the HttpCommandExecutor persists the proxy details 
         and allows you to pass in credentials if required
         */
        var executor = new HttpCommandExecutor(
            new Uri("https://ondemand.eu-central-1.saucelabs.com/wd/hub"), 
            TimeSpan.FromSeconds(600))
        {
            Proxy = GenerateProxy()
        };
    
        _driver = new RemoteWebDriver(executor, caps);
    
        _javascriptExecutor = ((IJavaScriptExecutor)_driver);
    
        _javascriptExecutor.ExecuteScript($"sauce:context=Open {_url}");
        _driver.Navigate().GoToUrl(_url);
    
        _javascriptExecutor.ExecuteScript("sauce:context=Sleep for 10000ms");
        Thread.Sleep(10000);
        Assert.IsTrue(true);
    
        var passed = true;
        _javascriptExecutor.ExecuteScript("sauce:job-result=" + (passed ? "passed" : "failed"));
        _driver?.Quit();
    }
    
    
    public WebProxy GenerateProxy()
    {
        var proxy = new WebProxy
        {
            Address = new Uri($"{_proxyScheme}://{_proxyHost}:{_proxyPort}"),
            BypassProxyOnLocal = false,
            UseDefaultCredentials = _networkCredential != null,
            Credentials = _networkCredential
        };
    
        return proxy;
    }