Yes, you can add more than one custom capability. These additional capabilities are stored in the Selenium hub server as a map of Strings to Strings. However, in order for the Selenium hub to make use of your custom capabilities, you have to provide your own matcher that makes use of those additional capabilities.
My hub config file looks something like this:
{
"capabilityMatcher": "com.example.GroupCapabilityMatcher",
"newSessionWaitTimeout": 300000,
"timeout": 1200000,
"browserTimeout": 600000
}
If all you want to do is provide your own custom implementation of a capability matcher, you really only need to have the "capabilityMatcher" line in there. The other options are just additional options I use for tweaking my setup.
A quick example of my GroupCapabilityMatcher class looks like this:
package com.example;
import org.openqa.grid.internal.utils.DefaultCapabilityMatcher;
public class GroupCapabilityMatcher extends DefaultCapabilityMatcher {
@Override
public boolean matches(Map<String, Object> nodeCapabilities, Map<String, Object> requestedCapabilities) {
boolean matches = super.matches(nodeCapability requestedCapability)
&& nodeCapabilities.get("groups").equals(requestedCapability.get("groups"));
return matches
}
}
I can add this class to the classpath when I launch the Selenium hub server, or I can package it with other supporting classes into a Jar, and then add the Jar to the classpath. In either case, I have to change my Selenium hub server launch command to look a bit something like the following:
java -cp selenium-server-standalone-2.53.0.jar:my-custom-capabilities.jar \
org.openqa.grid.selenium.GridLauncher -role hub \
-hubConfig my-hub-config.json
By the way, if you really want to know what sorts of features Selenium provides you, I recommend cloning the Selenium source code and taking a look around (and of course, reading the docs). This is where I found out how to customize the capability matchers.