Page tree
Skip to end of metadata
Go to start of metadata

Last updated: Jul 12, 2017 18:39

Use of the Selenium getCapabilities() method and how it differs from device info

By Brian Clark

When using RemoteWebDriver and trying perform conditional steps based on context (like os, os version, model, etc) it may be necessary to query the cloud for the current context of a test instance. The use of the getCapabilities() and getCapability() methods might be employed to achieve this end, but understand that not all device properties can be accessed from these methods.

The getCapabilities() and getCapability() methods can only provide information regarding the current instance as determined when the instance was created. This includes those specified by the test class as well as those added from the server side when the instance is created. For example for a basic test class you might set the capabilities like this:

String browserName = "mobileOS";DesiredCapabilities capabilities = new DesiredCapabilities(browserName, "", Platform.ANY);String 
host = args[0];
capabilities.setCapability("user", args[1]);
capabilities.setCapability("password", args[2]);
capabilities.setCapability("deviceName", "30E9D3E3");
RemoteWebDriver driver = new RemoteWebDriver(new URL("https://" + host + "/nexperience/perfectomobile/wd/hub"), capabilities);

In this case, the subsequent use of driver.getCapabilities().toString(), would generate the following:

GetCapabilities() typical response

The highlighted values were what we provided at runtime when creating the driver, everything else is added added by the server when the driver object is created as either session specific or default values. If additional DesiredCapabilities were used when creating the driver, they would also be available here. To get just a single value, you can employ the getCapability() method after getting the Capabilities object:

String cap = driver.getCapabilities().getCapability("deviceName").toString();
System.out.println("Current Device: " + cap);

This would produce the output: Current Device: 30E9D3E3

Additional information about the device can be collected using the executeScript() method with the mobile:handset:info command and setting the property parameter to "All":

Map params = new HashMap<>();         
params.put("property", "All");        
String properties = (String) driver.executeScript("mobile:handset:info", params);

This would produce a comma separated list of property/value pairs as seen below:

o get a single property, simple specify the desired property:

Map params = new HashMap<>();         
params.put("property", "model");        
String properties = (String) driver.executeScript("mobile:handset:info", params);


In this case: properties = "Galaxy S5".

This function provides all of the device specific information that we might use to make any decision, and it might be a good idea to create a method that populates a hash map with all of the device info in one call, so it is available throughout the test case without the need to make additional calls to the server. Below is a snippet that does just this:

public static HashMap getDevicePropertiesList(RemoteWebDriver driver { //hashmap to contain all device properties HashMap<String, String> deviceProperties = new HashMap();
    deviceProperties = new HashMap();        
    Map<String, Object> params = new HashMap<>();        
    params.put("property", "ALL");        
    String properties = (String) driver.executeScript("mobile:handset:info", params);        
    List<String> items = Arrays.asList(properties.split(","));        
    String key,value;
    //build hashmap for all device properties: 
    for (int i = 0; i < items.size(); i=i+2) {         
      key=items.get(i);         
        if (key.startsWith("[")||key.startsWith(" ")){    
          key=key.substring(1);         
        }         
        value=items.get(i+1);         
        if(value.startsWith(" ")){          
            value=value.substring(1);         
        }         
        if (value.startsWith("[")){          
          for (int j = i+2; j < items.size(); j++) {
            value=value+","+items.get(j);                 
            if (value.endsWith("]")){
                value=value.substring(1,value.length()-1); 
                i=j-1;                     
                break;                 
            }                         
          }         
        }         
        if (value.endsWith("]")){ 
            value=value.substring(0,value.length()-1); 
        } 
        deviceProperties.put(key, value);                
    } 
    return deviceProperties;  
}



Now if this method is called as some point after the driver is created at the beginning of the test, any property can be retrieved throughout the test case without the need to make additional server calls:

HashMap<String,String> deviceProperties = getDevicePropertiesList(driver);
String deviceModel = deviceProperties.get("model")