How to provide custom capabilities on the selenium server?
Asked Answered
O

2

0

I know that some selenium capabilities can be obtained with a method, one of them like this :

driver.getCapabilities().getBrowserName();

It returns the value of the browser name.

But if it refers to an available method, if I don't misunderstand it, this seems to be related to custom capabilities, like this I mean :

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

Returns: The value, or null if not set.

get capabilities

So, I've tried to make a simple code to get the value I mean.

    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();
    }

With json, server log say :

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

server log

But i get a null value.

How to the right setup ? How do you make our server provide the capabilities testName I mean? and can be obtained with driver.getCapabilities().getCapability("testName");

Current result Browser Name : chrome Test Name : null

Expected result Browser Name : chrome Test Name : Login

Thanks advance

Oriental answered 5/8, 2019 at 6:1 Comment(7)
w3.org/TR/webdriver1/#capabilities this may help understanding the capabilities . Remote end will not return values if its not supported.Overwrought
@RahulL yes correct, if i use .getCapability("browserName") platformName etc, it will return a value, but it still the default available in selenium. I've used a paid testing platform (platform based on selenium and appium) and for the purposes of the report name I can only setup by adding the dc.setCapability("testName"," Login ") method, and I can get the value of testName using the method .getCapability ("testName"), even I can also get the value of the report url using the .getCapability ("urlReport") method. So I assume that the name of the capability can be custom as needed.Oriental
But in the fact it's not simple as my imagineOriental
Sauce lab or Browser stack have their own implementations of remote servers. They don't use selenium remote server as it is . So there server recognize capabilities defined by them. Example github.com/aerokube/selenoid implemented in go languageOverwrought
So, you mean, the capabilities that I mean are made separate from the Selenium framework ?Oriental
Answer is Yes.As per W3C protocol -'Remote ends may also introduce extension capabilities that are extra capabilities used to provide configuration or fulfill other vendor-specific needs' Capability dc.setCapability("testName", "Login") It will be sent in Json but it will be ignored by remote server .When you request it back it will not send anything.Overwrought
Let us continue this discussion in chat.Oriental
W
1

You can extract the WebDriver Capabilities e.g. Browser Name, Browser Version, Platform Name, etc using either of the following solutions:

  • Using direct APIs:

    • Code Block:

      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());
      
    • Console Output:

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

    • Code Block:

      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"));
      
    • Console Output:

      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
      

You can find the list of the supported capabilities in the Capabilities section within the WebDriver W3C Recommendation

Whin answered 5/8, 2019 at 10:43 Comment(4)
Thanks. But browserName browserVersion platformName is default capability from selenium, i need custom string name to set capability and get value it.Oriental
@Frian Check out the answer update and let me know the status.Whin
i've updated my question with more explanation, maybe you have any idea.Oriental
@Frian testName is not a standard capability. You can't send it to RemoteWebDriver.Whin
V
1

It sounds like what you're looking for is how to add a custom capability to your Grid configuration. This is possible, but requires several steps.

First, you need to build a capability matcher. The matcher will be its own project, importing the Selenium-Server and Selenium-Java libraries as dependencies. You'll need a single class that extends org.openqa.grid.internal.utils.DefaultCapabilityMatcher, and overrides the matches() method with your own logic to determine whether or not a node possesses the desired capability. When complete, you'll build this project and generate a jar file.

Second, you'll need to attach your new matcher to your Grid Hub. I store my matcher jars in the same directory as my selenium-server-standalone jar, and I alter my normal launch command to accommodate the 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

In my hubConfig.json, I had to add two lines to the JSON to wire in the matcher:

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

Third, you'll need to configure your nodes to accept the new capability. If you're using JSON to also configure your nodes, it's just as simple as adding a new line for your capability:

"capabilityName": "foo"

That's pretty much it. It's also worth noting that DesiredCapabilities does have a capability called applicationName, which is left as a user-definable value. Depending on your specific use case, you might be able to leverage this capability in place of adding something new.

I found a sample repo on Github a while back when I was learning this process myself. It's a basic setup, but it illustrates the steps above pretty well. It should give you a great starting point for your own implementation.

Verso answered 9/8, 2019 at 14:30 Comment(14)
Let me check, i'll back to you.Oriental
sorry for late response, thank before for the suggest. I've complete the steps like your suggest, long enough in the first step :), but can you correct my job ? wrong or true with your review. Hub and node fine work, indicate by 10:29:44.122 INFO [SelfRegisteringRemote.registerToHub] - The node is registered to the hub and ready to use.Oriental
This is the value custom-capability.jar : public class CustomCapability extends DefaultCapabilityMatcher { private final String testName = "testName"; boolean allCapabilitiesAvailability = false;Oriental
@Override public boolean matches(Map<String, Object> nodeCapability, Map<String, Object> 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 && nodeOSAvailability); return allCapabilitiesAvailability; } } }Oriental
This is the value 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 }Oriental
So execute the hub with this command : java -cp custom-capability.jar:selenium-server-standalone-3.141.59.jar org.openqa.grid.selenium.GridLauncherV3 -role hub -hubConfig hubConfig.jsonOriental
This is the value nodeConfig.json : { "capabilities": [ { "browserName": "firefox", "maxInstances": 5, "seleniumProtocol": "WebDriver", "testName": "untitled" }, { "browserName": "chrome", "maxInstances": 5, "seleniumProtocol": "WebDriver", "testName": "untitled" } ], "proxy": "org.openqa.grid.selenium.proxy.DefaultRemoteProxy", "maxSession": 5, "port": 5555, "register": true, "registerCycle": 5000, "hub": "http://localhost:4444"Oriental
So execute the node with this command : java -Dwebdriver.chrome.driver=chromedriver -Dwebdriver.gecko.driver=geckodriver -cp custom-capability.jar:selenium-server-standalone-3.141.59.jar org.openqa.grid.selenium.GridLauncherV3 -role node -nodeConfig nodeConfig.jsonOriental
My question is, the test script code like this question i've tried set dc.setCapability("testName", "untitled"); it's fine work, but if i use this command : driver.getCapabilities().getCapability("testName") it's return null. Then i've tried set dc.setCapability("testName", "login");, it's getting error like this : org.openqa.selenium.WebDriverException: Error forwarding the new session cannot find : Capabilities {browserName: chrome, testName: login}Oriental
Did the results of your suggestion really produce this ? if not, then where is my mistake ? Because the point of my question is how testName can be made like a parameter, it can be filled with any string value, and I can get the testName value with this : driver.getCapabilities().getCapability("testName"), thanks and please help me again for review :)Oriental
Just at a quick glance, I think the launch command for your nodes might need to be changed. I'd start by dropping the -Dwebdriver args. There is also, apparently, a known issue right now with capability matchers, but workarounds exist. Please see this over at Github.Verso
I will visit the link and investigate, btw with the correct result, is I can change the value testName capability with any string like I mean ? example : dc.setCapability("testName", "login");Oriental
dc.setCapability() isn't meant to assign a new value. The Matcher and the JSON configuration define a set of capabilities held by the Node (such as which browser, which OS, etc). In the case of custom capabilities (such as your testName option), you'll assign a value to each node in the JSON configuration. Then, when configuring your DesiredCapabilities instance to be passed to your RemoteWebDriver, you're telling DC which capabilities to seek out when choosing a Node on which to run the test.Verso
By invoking setCapability(), you are telling DC which of the options to use that you've assigned to your various Nodes. In your example, dc.setCapability("testName", "login"), you're instructing DC to find a Node with the "login" value for the "testName" capability.Verso

© 2022 - 2024 — McMap. All rights reserved.