【问题标题】:How to provide custom capabilities on the selenium server?如何在 selenium 服务器上提供自定义功能?
【发布时间】:2019-12-12 15:25:20
【问题描述】:

我知道一些 selenium 功能可以通过一种方法获得,其中之一是这样的:

driver.getCapabilities().getBrowserName();

它返回浏览器名称的值。

但是如果它指的是一个可用的方法,如果我没有误解的话,这似乎与自定义能力有关,我的意思是这样的:

driver.getCapabilities().getCapability("something ?");

返回:值,如果未设置,则返回 null。

所以,我尝试编写一个简单的代码来获得我的意思。

    private RemoteWebDriver driver;
    private URL url;
    private DesiredCapabilities dc = new DesiredCapabilities();

    @Before
    public void setUp() throws MalformedURLException {
        url = new URL("http://localhost:4444/wd/hub");
        dc.setCapability(CapabilityType.BROWSER_NAME, BrowserType.CHROME);
        //this is custom capability i mean
        dc.setCapability("testName", "Login");
        driver = new RemoteWebDriver(url, dc);
    }
    
    @Test
    public void test() {
        some code.....
    }
    
    @After
    public void tearDown() {
        System.out.println("Browser Name : "+ driver.getCapabilities().getCapability("browserName"));
        System.out.println("Test Name : "+ driver.getCapabilities().getCapability("testName"));
        driver.quit();
    }

使用json,服务器日志说:

Capabilities are: {
  "browserName": "chrome",
  "testName": "Login"
}

但我得到一个null 值。

如何正确设置?您如何使我们的服务器提供testName 我的意思的功能?并且可以通过driver.getCapabilities().getCapability("testName");获得

当前结果 Browser Name : chrome Test Name : null

预期结果 Browser Name : chrome Test Name : Login

提前感谢

【问题讨论】:

  • w3.org/TR/webdriver1/#capabilities 这可能有助于理解功能。如果不支持,远程端将不会返回值。
  • @RahulL 是正确的,如果我使用 .getCapability("browserName") platformName 等,它将返回一个值,但它仍然是 selenium 中可用的默认值。我使用了付费测试平台(基于 selenium 和 appium 的平台),出于报告名称的目的,我只能通过添加 dc.setCapability("testName"," Login ") 方法来设置,我可以使用 @ 方法获取 testName 的值987654343@,即使我也可以使用.getCapability ("urlReport")方法获取报告url的值。所以我假设能力的名称可以根据需要自定义。
  • 但其实并不像我想象的那么简单
  • 酱实验室或浏览器堆栈有自己的远程服务器实现。他们不按原样使用 selenium 远程服务器。因此,服务器可以识别它们定义的功能。例子github.com/aerokube/selenoid用go语言实现
  • 答案是肯定的。根据 W3C 协议 - '远程端还可能引入扩展功能,这些扩展功能是用于提供配置或满足其他供应商特定需求的额外功能' Capability dc.setCapability("testName", "Login") 它将以 Json 形式发送,但会被远程服务器忽略。当您请求它返回时,它不会发送任何内容。

标签: java selenium remotewebdriver desiredcapabilities


【解决方案1】:

听起来您正在寻找的是如何将自定义功能添加到您的网格配置中。这是可能的,但需要几个步骤。

首先,您需要构建一个能力匹配器。匹配器将是它自己的项目,将 Selenium-Server 和 Selenium-Java 库作为依赖项导入。您将需要一个扩展org.openqa.grid.internal.utils.DefaultCapabilityMatcher 的类,并用您自己的逻辑覆盖matches() 方法以确定节点是否具有所需的功能。完成后,您将构建此项目并生成一个 jar 文件。

其次,您需要将新的匹配器附加到您的 Grid Hub。我将 matcher jar 存储在与 selenium-server-standalone jar 相同的目录中,并更改了正常的启动命令以适应 matcher。

java -cp <custom-matcher>-1.0.0.jar;selenium-server-standalone-3.141.59.jar org.openqa.grid.selenium.GridLauncher -role hub -hubConfig hubConfig.json

在我的hubConfig.json 中,我必须在 JSON 中添加两行以连接到匹配器中:

  "capabilityMatcher": "fully.qualified.path.to.Matcher",
  "throwOnCapabilityNotPresent": true,

第三,您需要配置节点以接受新功能。如果您还使用 JSON 来配置节点,那么只需为您的功能添加新行即可:

"capabilityName": "foo"

差不多就是这样。还值得注意的是,DesiredCapabilities 确实具有称为applicationName 的功能,它保留为用户可定义的值。根据您的特定用例,您也许可以利用此功能来代替添加新内容。

不久前,当我自己学习这个过程时,我在 Github 上找到了一个sample repo。这是一个基本设置,但它很好地说明了上述步骤。它应该为您自己的实施提供一个很好的起点。

【讨论】:

  • 让我检查一下,我会回复你的。
  • 抱歉回复晚了,谢谢之前的建议。我已经完成了你建议的步骤,第一步足够长:),但你能纠正我的工作吗?您的评论错误或真实。集线器和节点工作正常,由10:29:44.122 INFO [SelfRegisteringRemote.registerToHub] - The node is registered to the hub and ready to use指示。
  • 这是custom-capability.jar的值:public class CustomCapability extends DefaultCapabilityMatcher { private final String testName = "testName"; boolean allCapabilitiesAvailability = false;
  • @Override public boolean matches(Map&lt;String, Object&gt; nodeCapability, Map&lt;String, Object&gt; requestedCapability){ boolean defaultCapabilitiesAvailability = super.matches(nodeCapability, requestedCapability); if (! requestedCapability.containsKey(testName)){ return defaultCapabilitiesAvailability; }else { boolean nodeOSAvailability = nodeCapability.get(testName).equals(requestedCapability.get(testName)); allCapabilitiesAvailability = (defaultCapabilitiesAvailability &amp;&amp; nodeOSAvailability); return allCapabilitiesAvailability; } } }
  • 这是hubConfig.json 的值:{ "port": 4444, "newSessionWaitTimeout": -1, "servlets" : [], "withoutServlets": [], "custom": {}, "capabilityMatcher": "com.matcher.CustomCapability", "throwOnCapabilityNotPresent": true, "cleanUpCycle": 5000, "role": "hub", "debug": false, "browserTimeout": 0, "timeout": 1800 }
【解决方案2】:

您可以提取 WebDriver Capabilities 例如Browser Name、Browser Version、Platform Name 等使用以下任一解决方案:

  • 使用直接 API:

    • 代码块:

      System.out.println("Class Name is : "+((RemoteWebDriver) driver).getCapabilities().getClass().toString());
      System.out.println("Browser Name is : "+((RemoteWebDriver) driver).getCapabilities().getBrowserName().toLowerCase());
      System.out.println("Browser Version is : "+((RemoteWebDriver) driver).getCapabilities().getVersion().toString());
      System.out.println("Platform Name is : "+((RemoteWebDriver) driver).getCapabilities().getPlatform().toString());
      
    • 控制台输出:

      Class Name is : class org.openqa.selenium.MutableCapabilities
      Browser Name is : firefox
      Browser Version is : 67.0
      Platform Name is : WINDOWS
      
  • 使用getCapability():

    • 代码块:

      Capabilities cap = ((RemoteWebDriver) driver).getCapabilities();
      System.out.println("acceptInsecureCerts value is: "+cap.getCapability("acceptInsecureCerts"));
      System.out.println("Browser Name is : "+cap.getBrowserName());
      System.out.println("Browser version is : "+cap.getVersion());           
      System.out.println("Platform is : "+cap.getPlatform().toString());
      System.out.println("javascriptEnabled value is: "+cap.getCapability("javascriptEnabled"));
      System.out.println("moz:accessibilityChecks value is: "+cap.getCapability("moz:accessibilityChecks"));
      System.out.println("moz:buildID value is: "+cap.getCapability("moz:buildID"));
      System.out.println("geckodriverVersion value is: "+cap.getCapability("geckodriverVersion"));
      System.out.println("Headless Mozilla value is: "+((RemoteWebDriver) driver).getCapabilities().getCapability("moz:headless"));
      System.out.println("moz:headless value is: "+cap.getCapability("moz:headless"));
      System.out.println("Mozilla Profile value is : "+ ((RemoteWebDriver) driver).getCapabilities().getCapability("moz:profile"));
      System.out.println("moz:processID value is : "+cap.getCapability("moz:processID"));
      System.out.println("moz:profile value is : "+cap.getCapability("moz:profile"));
      System.out.println("moz:shutdownTimeout value is : "+cap.getCapability("moz:shutdownTimeout"));
      System.out.println("moz:useNonSpecCompliantPointerOrigin value is : "+cap.getCapability("moz:useNonSpecCompliantPointerOrigin"));
      System.out.println("moz:webdriverClick value is : "+cap.getCapability("moz:webdriverClick"));
      System.out.println("pageLoadStrategy value is : "+cap.getCapability("pageLoadStrategy"));
      System.out.println("Platform is : "+cap.getPlatform().toString());
      System.out.println("platformName value is : "+cap.getCapability("platformName"));
      System.out.println("platformVersion value is : "+cap.getCapability("platformVersion"));
      System.out.println("rotatable value is : "+cap.getCapability("rotatable"));
      System.out.println("setWindowRect value is : "+cap.getCapability("setWindowRect"));
      System.out.println("strictFileInteractability value is : "+cap.getCapability("strictFileInteractability"));
      System.out.println("timeouts values are : "+cap.getCapability("timeouts"));
      System.out.println("unhandledPromptBehavior value is : "+cap.getCapability("unhandledPromptBehavior"));
      
    • 控制台输出:

      acceptInsecureCerts value is: true
      Browser Name is : firefox
      Browser version is : 67.0
      Platform is : WINDOWS
      javascriptEnabled value is: true
      moz:accessibilityChecks value is: false
      moz:buildID value is: 20190516215225
      geckodriverVersion value is: null
      Headless Mozilla value is: false
      moz:headless value is: false
      Mozilla Profile value is : C:\Users\Debanjan.B\AppData\Local\Temp\rust_mozprofile.7HI7QUtzF1YP
      moz:processID value is : 7308
      moz:profile value is : C:\Users\Debanjan.B\AppData\Local\Temp\rust_mozprofile.7HI7QUtzF1YP
      moz:shutdownTimeout value is : 60000
      moz:useNonSpecCompliantPointerOrigin value is : false
      moz:webdriverClick value is : true
      pageLoadStrategy value is : normal
      Platform is : WINDOWS
      platformName value is : WINDOWS
      platformVersion value is : 6.2
      rotatable value is : false
      setWindowRect value is : true
      strictFileInteractability value is : false
      timeouts values are : {implicit=0, pageLoad=300000, script=30000}
      unhandledPromptBehavior value is : dismiss and notify
      

您可以在WebDriver 的Capabilities 部分找到支持的功能列表 W3C 推荐

【讨论】:

  • 谢谢。但是 browserName browserVersion platformName 是 selenium 的默认功能,我需要自定义 string name 来设置功能并获得价值。
  • @Frian 查看答案更新,让我知道状态。
  • 我已经用更多解释更新了我的问题,也许你有任何想法。
  • @Frian testName 不是标准功能。您无法将其发送到 RemoteWebDriver。
猜你喜欢
  • 2019-02-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-05
相关资源
最近更新 更多