Like the Selenium hub command-line options, there is also a -nodeConfig option to load a JSON configuration file with all the common WebDriver desired capabilities for the nodes.
Here is a sample Selenium node JSON configuration file:
// selenium_node.json
{
"capabilities":[
{
"browserName":"firefox",
"version":"56.0",
"platform":"LINUX",
"applicationName":"LINUX-FIREFOX",
"maxInstances":10,
"seleniumProtocol":"WebDriver",
"acceptSslCerts":true,
"javascriptEnabled":true,
"takesScreenshot":true
}
],
"_comment":"Configuration for Selenium Node Linux/Firefox",
"timeout":600,
"browserTimeout":300,
"cleanUpCycle":5000,
"proxy":"org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"maxSession":10,
"port":5555,
"hub":"http://127.0.0.1:4444",
"register":true,
"registerCycle":5000,
"nodeStatusCheckTimeout":5000,
"nodePolling":5000,
"unregisterIfStillDownAfter":60000,
"role":"node",
"downPollingLimit":2,
"debug":false
}
The JSON config files are the same for each node on the grid, with the exception of changing the browserName, version, platform, and applicationName. These must be set in the setDriver method as desired capabilities, and storing properties such as the version should go in the selenium.properties file.
When the RemoteWebDriver class is cast, it will look for a node wth the exact parameters passed into it. And, there are many additional capabilities for mobile device testing, and those should also be stored in the properties file and passed into the driver. This allows you to create different nodes on the grid with different browser or mobile device versions, platforms, and so on.
caps.setCapability("applicationName",
platform.toUpperCase()
+ "-"
+ browser.toUpperCase());
Here is another example where one node contains Chrome, Firefox, Safari, and Opera browser instances on a macOS platform (notice there is no driver for Safari, it's built into the browser):
// selenium_nodes.sh
java -jar /opt/selenium/selenium-server-standalone-3.x.x.jar
-Dwebdriver.chrome.driver=/opt/selenium/chromedriver
-Dwebdriver.gecko.driver=/opt/selenium/geckodriver
-Dwebdriver.opera.driver=/opt/selenium/operadriver
-role node
-nodeConfig /opt/selenium/selenium_nodes.json
And here is the selenium_nodes.json file structure:
// selenium_nodes.json
{
"capabilities":[
{
"browserName":"chrome",
"version":"62.0",
"platform":"MAC",
"applicationName":"MAC-CHROME",
"maxInstances":10,
"seleniumProtocol":"WebDriver",
"acceptSslCerts":true,
"javascriptEnabled":true,
"takesScreenshot":true
},
{
"browserName":"firefox",
"version":"56.0",
"platform":"MAC",
"applicationName":"MAC-FIREFOX",
"maxInstances":10,
"seleniumProtocol":"WebDriver",
"acceptSslCerts":true,
"javascriptEnabled":true,
"takesScreenshot":true
},
{
"browserName":"safari",
"version":"11.0",
"platform":"MAC",
"applicationName":"MAC-SAFARI",
"maxInstances":10,
"seleniumProtocol":"WebDriver",
"acceptSslCerts":true,
"javascriptEnabled":true,
"takesScreenshot":true
},
{
"browserName":"opera",
"version":"12.11",
"platform":"MAC",
"applicationName":"MAC-OPERA",
"maxInstances":10,
"seleniumProtocol":"WebDriver",
"acceptSslCerts":true,
"javascriptEnabled":true,
"takesScreenshot":true
}
],
"_comment":"Configuration for Selenium Nodes MAC/All",
"timeout":600,
"browserTimeout":300,
"cleanUpCycle":5000,
"proxy":"org.openqa.grid.selenium.proxy.DefaultRemoteProxy",
"maxSession":100,
"port":5555,
"hub":"http://127.0.0.1:4444",
"register":true,
"host":"myHubHost",
"registerCycle":5000,
"nodeStatusCheckTimeout":5000,
"nodePolling":5000,
"unregisterIfStillDownAfter":60000,
"role":"node",
"downPollingLimit":2,
"debug":false,
"servlets":[],
"withoutServlets":[],
"custom":{}
}