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

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 ...

Related

Selenium Java custom browser timeout

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?

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

Windows Authentication using Selenium Grid and Webdriver

I was asked a question :
Assume I have 4 machines and I need to execute a script in all the machines across all the browsers. How will I achieve that.
I told him the concept of Selenium Grid, where in we could set up a machine which acts like a hub, configure 3 more machines which would act like a node.
Using Desired Capabilities among others we could choose a browser type and version type in that and write a script.
But he asked me two things :
IN all the node machines how do you configure the Windows username and Password if the machine is locked. Can you write windows Authentication in the script.
Can I achieve testing different browser versions of same browser type in a single node?
Can I pass as a the browser type and browser version as a parameter
from hub to the node?
Can someone throw some light on these as I was unable to answer. Thanks.
Question 1: Is it really necessary for the machine to be unlocked for the test to start? The selenium node is a background process that listens for commands, and executes them on the browser, so I do not think this is necessary. If it is necessary due to your specific windows settings however, then no, you cannot do this from the selenium script obviously.
Question 2: Yes, you can test different browser versions of the same type on the same node. You can pass the browser name and version to the node. However, keep in mind that the node cannot know the location of the different browser versions, so you will also have to supply the path to the browser executable for your requested version

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.

Can we set the selection of browser default ?

i am running my suite using selenium grid on different ports parallely. i am passing the port and browser to the defaultselenium method statically. Things are running good but i want to run my tests on different instances of grid on different browser.That is not happening with this setup though it is picking port independently that is good but it runs only on single type of browser that is specified in selenium method.Is there any way that my tests picks the browser value as specified on grid instance. Or any way with which we can set default browser value in selenium method ?
The grid simply makes the browsers available and gives you a single point to connect to (the hub) from your client. It is up to you to make your code request the browser you want and run your tests in parallel.