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
Related
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?
Hi all I am using TestNG framework for selenium webdriver scripts. I run them on Jenkins on two slaves one being windows the other being linux. I have close to 100 test cases and they take 2hrs 40 mins on each machine. I would want to speed up the execution time. will selenium grid be helpful in this case?
No. Selenium grid would not be the solution. Selenium grid can multiply the same action, not taking different actions in parallel.
You should look for the opportunities in test parallelization.
Selenium grid is designed to allow you to run test in parallel
The page says:
Selenium Grid allows us to run tests in parallel on multiple machines, and to manage different browser versions and browser configurations centrally (instead of in each individual test).
However it's not as easy as installing it and connecting up.
You'll need to ensure the rest of your framework and tests are capable of parallel execution. Most important part is to watch out for your test data e.g. if multiple tests rely on the same data source and they try and update it at the same time you'll get flaky results.
You're also capable of running tests in parallel on a local machine without selenium grid. If i were you i'd start with this first.
Typically most machines have the resources to run more than one browser - get it running locally before you go to far down the grid rabbit hole.
Here's a link for testng
Also worth a review is zalenium - a docker image that contains a grid + auto scaling nodes allowing easier browser control on a single machine.
Does anyone have a shell script or know of a way to ping a selenium hub to see if Nodes are available. Like a way to use wait-for or wait-for-it or another way to check the Selenium Hub for a node before triggering a test?
EDIT: A specific node with a browser version available. So for example if the hub has Chrome 64 attached and Chrome 63 is connecting I'm trying to ping the hub until the Chrome 63 node attaches to the hub and is available for use.
There is an endpoint in the Selenium Hub that can give you some of this info.
way to check the Selenium Hub for a node before triggering a test
Do a GET to http://your-hub-here:4444/grid/api/hub and you should see the free/total slotCounts (look at newSessionRequestCount to see queued tests). It doesn't have the granularity to show different browsers but you can get overview to determine if your grid is saturated.
Or if you are using Selenium Grid Extras there would probably be an API behind their webview, that you would call to get the number of available browsers.
Try this if you run docker on your local machine http://localhost:4444/wd/hub/status
Here is a general from http://{location}:4444/wd/hub/status
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.
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 ...