12

我有两个使用RemoteWebDriverwithChromeOptions和的简单测试EdgeOptions。这两个测试都使用通用代码来设置功能,包括browserstack.userbrowserstack.key功能。

因为我使用的是DriverOptions(而不是DesiredCapabilities),所以我习惯AddAdditionalCapability(...)将这些功能添加到驱动程序中。

Edge 测试正常,但 Chrome 测试在测试开始之前就失败了;

OpenQA.Selenium.WebDriverException:意外错误。需要授权

DesiredCapabalities在我将 Selenium 驱动程序升级到 v3.14(DesiredCapabalities已弃用)之前,这些测试以前可以使用。


更新

我已降级到 Selenium.WebDriver v3.4。

通过 (EdgeOptions) 和失败 (使用 ChromeOptions) 的代码示例:

[TestClass]
public class Simple_GridTest_Chrome
{
    private static IWebDriver driver;

    private string _bsUsername = "<username>";
    private string _bsAccessKey = "<myaccesskey>";

    private string _bsProjectName = "TestProject";
    private string _bsBuildName = "Build-0.0.1";

    private void SetOptions(bool useEdge = false)
    {
        DriverOptions options;

        if (useEdge)
        {
            options = new EdgeOptions(); // this works OK
        } else
        {
            options = new ChromeOptions(); // this fails with OpenQA.Selenium.WebDriverException: Unexpected error. Authorization required
        }

        // the account that is running the test
        options.AddAdditionalCapability("browserstack.user", _bsUsername);
        options.AddAdditionalCapability("browserstack.key", _bsAccessKey);

        options.AddAdditionalCapability("project", _bsProjectName);
        options.AddAdditionalCapability("build", _bsBuildName);

        // gather additional data during the test run (screen shots etc)
        options.AddAdditionalCapability("browserstack.debug", "true");

        driver = new RemoteWebDriver(
          new Uri("https://hub-cloud.browserstack.com/wd/hub/"), options
        );

        //driver = new RemoteWebDriver(
        //  new Uri($"https://{_bsUsername}:{_bsAccessKey}@hub-cloud.browserstack.com/wd/hub/"), options
        //);
    }

    [ClassInitialize()]
    public static void MyClassInitialise(TestContext context)
    {
    }

    [TestMethod]
    [TestCategory("grid.BrowserStack.Google")]
    public void NavigateToGoogle_Windows7_Chrome()
    {
        SetOptions(false); // use Chrome
        GoogleTest(driver);
    }

    [TestMethod]
    [TestCategory("grid.BrowserStack.Google")]
    public void NavigateToGoogle_Windows10_Edge()
    {
        SetOptions(true); // use Edge
        GoogleTest(driver);
    }

    private void GoogleTest(IWebDriver driver)
    {
        driver.Navigate().GoToUrl("https://www.google.com/?q=test");
        Console.WriteLine(driver.Title);

        driver.WaitForWebElement(By.XPath("//*[@name=\"btnK\"]")).Click();
        Console.WriteLine(driver.Title);
    }
}

我安装了以下软件包:

<packages>
  <package id="Selenium.Firefox.WebDriver" version="0.21.0" targetFramework="net45" />
  <package id="Selenium.Support" version="3.4.0" targetFramework="net45" />
  <package id="Selenium.WebDriver" version="3.4.0" targetFramework="net45" />
  <package id="Selenium.WebDriver.ChromeDriver" version="2.41.0" targetFramework="net45" />
  <package id="Selenium.WebDriver.IEDriver" version="3.14.0" targetFramework="net45" />
</packages>
4

6 回答 6

5

这似乎是一个特定于 selenium 语言绑定如何生成有效负载以及 browserstack 如何在其末尾解析它的问题。

根据您分享的错误消息,很有可能在解析请求负载时,browserstack 无法找到您的用户名和访问密钥

您可以按照下面提到的步骤进行调试:

  • 将行更改driver = new RemoteWebDriver(new Uri("https://hub-cloud.browserstack.com/wd/hub/"), options);driver = new RemoteWebDriver( new Uri("http://localhost:4444/wd/hub/"), options );。您不需要在本地启动 selenium-standalone jar。

  • 启动一个代理,读取 localhost:4444 上的流量。(如果需要,您可以使用基于节点的实现。这是一个这样的实现:https ://gist.github.com/hanikhan/f817bd64b063129cb78dc7ed0b66fdb7 )

  • 观察您正在使用的 selenium 客户端绑定生成的请求有效负载(您提到的 v3.14)。例如,当仅通过浏览器时,我的基于 java 的 selenium 客户端会生成此功能。{"desiredCapabilities":{"browserName":"Chrome"},"capabilities":{"firstMatch":[{"browserName":"Chrome"}]}}

  • 现在降级你的 selenium 绑定(到它工作的版本)并观察它生成的有效负载。

检查客户端绑定是否使用严格检查,因为某些必需的功能最终会被丢弃。

如果这是真的,那么您将需要执行以下操作之一:

  • 提出 selenium C# 绑定问题以删除对您的案例的严格检查
  • 联系 Browserstack 并要求他们提供通过严格检查的能力
于 2018-09-11T15:22:07.790 回答
4

我遇到了同样的问题,并通过在 ChromeOptions 的每个“AddAdditionalCapability”方法(使用 Selenium 3.14)上将“isGlobalCapability”设置为 true 来解决它。如果其中只有一个没有设置,则测试失败。

chromeOptions.AddAdditionalCapability("browserstack.user", <user>, true);
chromeOptions.AddAdditionalCapability("browserstack.key", <key>, true);
chromeOptions.AddAdditionalCapability("browser", "chrome", true);
chromeOptions.AddAdditionalCapability("os", "Windows", true);
chromeOptions.AddAdditionalCapability("os_version", "10", true);
_Driver = new RemoteWebDriver(new Uri("http://hub-cloud.browserstack.com/wd/hub/"), chromeOptions);
于 2018-10-16T20:31:02.613 回答
4

您可以使用 EdgeOptions 和 ChromeOptions 为 Edge 和 Chrome 传递如下功能,以在 BrowserStack 上启动会话。这是在 Java 中。相应地将您的测试移植到其他语言。

对于边缘

EdgeOptions options = new EdgeOptions();

 options.setCapability("browserstack.user","<userName>");
 options.setCapability("browserstack.key","<accessKey>");
 options.setCapability("os_version", "10"); //desired os_version
 options.setCapability("browser", "chrome"); //desired browser

 driver = new RemoteWebDriver(new URL("https://hub-cloud.browserstack.com/wd/hub"), options);

对于铬

 ChromeOptions options = new ChromeOptions();

    options.setCapability("browserstack.user","<userName>");
    options.setCapability("browserstack.key","<accessKey>");
    options.setCapability("os_version", "10");
    options.setCapability("browser", "chrome");

    driver = new RemoteWebDriver(new URL("https://hub-cloud.browserstack.com/wd/hub"), options);
于 2018-09-06T17:25:49.980 回答
3

问题是在、和AddAdditionalCapability(string capabilityName, object capabilityValue)上调用时不会全局设置功能。相反,它将它们放在 JSON 中的特定浏览器选项中。有关更多信息,请参阅https://github.com/SeleniumHQ/selenium/issues/6563ChromeOptionsFirefoxOptionsInternetExplorerOptions

正如您所注意到的,EdgeOption确实将它们设置为全局,这就是为什么这对您有用(SafariOptions顺便说一句,它们的工作方式相同)。

现在,您看不到AddAdditionalCapability(string capabilityName, object capabilityValue, bool isGlobalCapability)重载的原因是您的options变量是 type DriverOptions,它不包含此重载。作为一种解决方法,您可以执行以下操作:

static void AddGlobalCapability(this DriverOptions options, string name, object value)
{
    switch (options)
    {
        case ChromeOptions chromeOptions:
            chromeOptions.AddAdditionalCapability(name, value, true);
            break;
        case FirefoxOptions firefoxOptions:
            firefoxOptions.AddAdditionalCapability(name, value, true);
            break;
        case InternetExplorerOptions internetExplorerOptions:
            internetExplorerOptions.AddAdditionalCapability(name, value, true);
            break;
        default:
            options.AddAdditionalCapability(name, value);
            break;
    }
}
于 2018-10-21T23:00:03.887 回答
3

您是否尝试将选项添加为options.ToCapabilities()

driver = new RemoteWebDriver(
    new Uri("https://hub-cloud.browserstack.com/wd/hub/"), options.ToCapabilities()
);

也尝试设置为全局能力:

options.AddAdditionalCapability("browserstack.user", _bsUsername, true);
于 2018-09-10T10:39:20.273 回答
-1

我们有同样的问题。我们试图在我们的 URL 中使用凭据,就像我们在 Java 项目中所做的那样。

var browserstackUrl = string.Format(
    "https://{0}:{1}@hub-cloud.browserstack.com/wd/hub", 
    browserstackUsername, 
    browserstackAccessKey
);
var webdriver = new RemoteWebDriver(new Uri(BrowserStackUrl), options);

通过将它们转移到功能上,我们能够解决这个问题:

capabilities.SetCapability("browserstack.user", browserstackUsername);
capabilities.SetCapability("browserstack.key", browserstackAccessKey);
var browserstackUrl = "https://hub-cloud.browserstack.com/wd/hub";
var webdriver = new RemoteWebDriver(new Uri(BrowserStackUrl), options);
于 2018-10-17T19:52:45.930 回答