Selenium Java custom browser timeout - selenium

In our organization we are automating UI test cases in Selenium Java with Selenium Grid over several browsers (Chrome, Firefox, IE/Edge).
Our Selenium Grid has a timeout configuration to close the browser instance if no command is send in 30 seconds. This is very useful in the case of some unexpected problems appear during the execution.
In few special test cases we need to increase this value to 15 min due to the specification of the test case. However, if no command is send to the browser, it is closed in 30 seconds.
As we saw, the timeout value is set on the configuration of the node of the Selenium Grid. Before trying another workarounds, Is there a way to set a specific timeout value through capabilities/arguments when opening the web driver in Selenium Java? We want to maintain the 30 seconds timeout in general but apply a custom timeout in some special cases.
We already try with implicitlyWait, pageLoadTimeout and scriptTimeout, but nothing changes.

The grid 2 official documentation says that node is released for other tests, if no interactions are detected in set timeout:
-timeout 30 (300 is default) The timeout in seconds before the hub automatically releases a node that hasn’t received any requests for
more than the specified number of seconds. After this time, the node
will be released for another test in the queue. This helps to clear
client crashes without manual intervention. To remove the timeout
completely, specify -timeout 0 and the hub will never release the
node.
Since you mention that this is a special case for only some of your tests and 'interaction' with browser can be done with polling I suggest you try a FluentWait. An example in Java, would look like this:
FluentWait<WebDriver> wait = new FluentWait(driver)
.pollingEvery(Duration.ofSeconds(15))
.withTimeout(Duration.ofMinutes(15))
.ignoring(NoSuchElementException.class);
wait.until(driver -> driver.findElement(locator));
This would wait 15 minutes for some element to be 'found' ignoring NoSuchElementExceptions. Of course you can wait for some other condition, i.e. using the built in ExpectedConditions class. With polling set to something smaller then node -timeout the browser would not be killed.

When using Selenium Grid to set a specific timeout value you can configure the following parameter:
-timeout, -sessionTimeout
<Integer> in seconds : Specifies the timeout before the server
automatically kills a session that hasn't had any activity in the last X
seconds. The test slot will then be released for another test to use.
This is typically used to take care of client crashes. For grid hub/node
roles, cleanUpCycle must also be set. If a node does not specify it, the
hub value will be used.
An example:
At NODE level:
java -jar -Dwebdriver.chrome.driver=chromedriver selenium-server-standalone-3.141.59.jar -role node -hub http://127.0.0.1:4444/grid/register -browser browserName=chrome,maxInstances=2 -timeout 5
At HUB level:
java -jar selenium-server-standalone-3.141.59.jar -role hub -port 4444 -timeout 5
You can find a relevant detailed discussions in Is there a way too prevent selenium automatically terminating idle sessions?

Related

How to check if a remote Selenium Grid hub is executing tests?

We are currently building a web interface for our manual QA team to be able to run Selenium tests, which are executed on remote machines via Selenium Grid.
I am looking for some way to remotely check if the Selenium Grid is currently executing any tests so I can then queue any additional runs sent to the Grid from the web interface until the previous test execution completes. This will ensure we avoid overloading the grid with too many simultaneous test runs.
I have searched through StackOverflow and read through the Selenium documentation to see if there were any commands that can be used to check for this, but came up empty.
You can see this details in grid console. For example if you are running the hub in local machine then the console URL is http://localhost:4444/grid/console. If you are running the grid hub on another machine then replace the local host with IP or hostname of the grid hub machine in the console URL.
There are many ways to know it.
If any of the node is occupied by test execution then the browser icon will be greyed out.(some times, you have to refresh the page to get status).
Otherwise if you mouse over on any browser icon in the console it will show the session ID if it is executing any test.
In selenium hub command line window logs. It will list out available nodes in a frequent interval.
You dont need to manage tests queue by yourself. Selenium grid and nodes have it in place. So for reducing overload on each nodes there are some configurations available. We have maxSession and maxInstance parameters.
maxSession - the maximum number of browsers that can run in parallel on the node
maxInstance - the maximum number of same browser instances that can run in parallel on the node.
F.e. maxSession = 3, maxInstance = 2. You can have 2 firefox + 1 chrome
You didnt mention what is your selenium driver version. so lets say its the newest 3.x.x. You can create node-config.json file and store there this parameters.
{
"capabilities": [
{
"browserName": "chrome",
"maxInstances": "2",#settings per browser
}
],
"maxSession": "3", #settings per node
}
To start the node:
java -jar /path_to_driver/serve.jar -role node -hub HUB_ADDRESS -nodeConfig /path_to_node_config/node-config.json
So when you want to run new test - grid will register it and will wait for a free node. So it can keep a stack for you
Also you can use bash command parallel and create an array of your tests and then run it in a parallel way. Lets say 5 jobs in parallel.
parallel --jobs 5 -k --gnu ::: "${arrayToRun[#]}"
More about Selenium configuration
More about run tests in parallel

How to kill/unregister/remove a Selenium node from a Grid

I manage a Selenium Grid. And I want to remove or unregister a node from Grid with a command line or something like that because I don't have access to the PC registered as a selenium Node, but I can see its IP from the Grid.
This is the script to register that node:
java -jar selenium-server-standalone-2.48.2.jar -role node -hub http://10.0.50.34:4444/grid/register/
I can't find anyway to stop this script. I tried to shutdown the Hub and restarted it, but this node was registered again, because the script was still running and waiting for the hub.
You can unregister a node with an http command:
http://node_ip_address:port/selenium-server/driver/?cmd=shutDownSeleniumServer
EDIT: since Selenium 3 you must load this servlet (org.openqa.grid.web.servlet.LifecycleServlet) at startup and, depending if you created a hub or a node, use this calls for shutdown:
Hub
http://host:port/grid/admin/LifecycleServlet?action=shutdown
Node
http://host:port/extra/LifecycleServlet?action=shutdown
Hope this helps
Try blocking the IP, if it is blocked it wont receive anything from the node machine and it wont be displayed.

Selenium via a grid setup takes much longer than running the webdriver locally

Running with local webdriver my test suite completes in 2.7hrs, Running a remote webdriver with hub/node setup the tests take 21.4hrs.
I'm looking for ways to pin point what is actually the cause of this significant overhead.
Notes so far
The build machine and all the hub and node machines are all VMs with the exact same specifications.
The Node and Hub hangs (40-50s which is fortunately less than the 60s timeout) on a very small number of find element calls.
Idle is not because my C# not calling the webdriver. It is waiting on the hub's response and the node does log that INFO - Executing: [find element: By.selector:..., the selector is a CSS selector.
Behaviour is the same for the IE driver.
For most of the FindElement calls I can replace them with a ExecuteScript call and use jQuery instead. In these cases I no longer hang/idle for 40-50s. Yet I can't replace all calls this way.
The issue was due to implicit waits being set, in the remote web driver initialisation (by another developer). Remove it and the behaviour returns to what I was wanting.

How to get the number of idle browsers for a node in selenium grid2

My current setup is 5 nodes with 10 Firefox browsers each, all connected to a hub.
I am running into a problem where I am exhausting the 10 firefox browsers for each node. So any new selenium runs are getting queued up at the Hub and running when any FF browser for a node becomes available.
What I want to do is somehow query the selenium grid2 hub to get the number of free/idle/available browsers before actually running my tests on that particular grid setup. Based on my result I would redirect the tests to another grid setup (on another machine) or may be not even run the tests.
Of course I can add more nodes or even increase the number of browsers that can be handled by each node. But I am looking for an answer which will help me query the Grid and then allow me to decide on what action I can take rather than muscling my way by brute force (bigger server to handle more browser sessions).
I also sense that this may be a feature not implemented by Selenium Grid 2, so was wondering how others have got around this problem.
It provides sessions information from each selenium node in a selenium grid. You can get the session information of each node like this (assume your selenium node listens to port 5555):
$ curl http://<selenium-node>:5555/wd/hub/sessions
You will get a JSON object response like this:
{"value":[],"sessionId":null,"status":0,"hCode":1542413295,"class":"org.openqa.selenium.remote.Response"}
Then you can calculate how many active sessions from the "value" array value on each selenium node when it hits those nodes. Then you know how many left.

Is there a way to make Selenium Grid 2 DesiredCapabilities browser-agnostic?

I'm wondering if there's a (preferably built-in) way for Selenium hubs to ask for nodes that have any browser available. Basically, I want my hub to specify something like "BrowserName = 'any'", match on a node that is running less instances than its maxInstances, then let the node decide which browser to run on.
The motivation behind this is that I want to maximize the number of tests running in parallel on any given node without having multiple instances of any one browser. I don't care which browser is running for any given test.
As a reference, I'm currently using selenium server 2.17.
Ack, this is annoying.
I'm fairly sure there's a command line parameter that let's you override the specified browserName, but now I can't find it.
If my memory is not way off, the parameter let you do more or less what you are asking for - regardless of what browsers the node says it has, and regardless of what the hub asks for, one particular browser is always started.
Note to self: start a proper list of all command line options for selenium, and possibly submit it to the team for inclusion in the wiki.
One way to achieve this in any case would be to write a your own "CapabilityMatcher" class - but that may not be an option unless you want to create a custom JAR, and you want teh hub to do the change of browser, rather than the individual nodes.
Here you go:
java -jar selenium-server-standalone-2.14.0.jar -role node -hub http://localhost:4444/grid/register -maxSession 3 -browser browserName=firefox,maxInstances=1 -browser browserName=chrome,maxInstances=1 ...