1

I can't seem to get Selenium Grid2 to abide by the maxSession parameter, no matter whether I set it as a command line option or in a JSON config, whether I set it on the hub or node or both. Grid ignores it completely. Before I open a bug ticket for it, I want to make sure I'm doing this right.

This is a node.js application utilizing the selenium-server-standalone-jar and selenium-webdriver NPM modules, both up to date. The process breaks down roughly as follows:

1) Start a selenium grid hub running locally:

var jar = require("selenium-server-standalone-jar"),
    hub = require("selenium-webdriver/remote").SeleniumServer(jar.path, {
        loopback: true,
        port:     4444,
        args:     [ "-role hub", "-hubConfig " + config_path ]
    });

That hub config file looks like this:

{
    "host": null,
    "port": 4444,
    "newSessionWaitTimeout": -1,
    "throwOnCapabilityNotPresent": true,
    "nodePolling": 5000,
    "cleanUpCycle": 5000,
    "timeout": 300000,
    "browserTimeout": 0,
    "maxSession": 1
}

2) Start a selenium grid node running locally:

var hub = require("selenium-webdriver/remote").SeleniumServer(jar.path, {
        loopback: true,
        port:     5555,
        args:     [ "-role node", "-nodeConfig " + config_path ]
    });

The node config looks like this:

{
    "capabilities": [
        {
            "browserName": "firefox",
            "maxInstances": 1,
            "seleniumProtocol": "WebDriver"
        }
    ],
    "configuration": {
        "maxSession": 1,
        "port": 5555,
        "host": "127.0.0.1",
        "register": true,
        "registerCycle": 5000,
        "hubPort": 4444,
        "hubHost": "127.0.0.1"
    }
}

So at this point I have a hub running with maxSession=1 and a node running with maxSession=1 and maxInstances=1 (for Firefox). This isn't how the application will function long term, I'm just trying to get Selenium Grid to demonstrate that it CAN limit sessions.

3) Start 5 child processes, each with its own webdriver using the hub server

Each proceeds to run through its browser actions and then closes the webdriver before terminating.

What I would expect to see: the grid should limit the number of browsers that those child processes can open. Whether that should result in the child processes queuing up for their turn.

What I actually see: A succession of firefox windows open (I've let it climb to ~30 before killing it) and start running through their steps in parallel, totally ignoring the maxSession and maxInstance configuration.

UPDATE 2016-04-14

I have isolated this problem in the SeleniumServer class. It appears that the "args" option I supply to its constructor is being ignored. This explains my inability to reach localhost:4444/grid/console while tests are running; the standalone server jar isn't running with a "hub" role.

I have verified that if I use child_process.exec to run the jar directly (with its role and JSON config) that everything starts working more or less correctly, but there's a problem with this approach in that a race condition exists between hub readiness and cucumber tests' attempts to connect a webdriver to it. Ideally, I'd like to use SeleniumServer like I planned. Any advice on what I might be doing wrong with it, or how I can make it behave, would be greatly appreciated.

Sophist
  • 33
  • 6
  • Try putting the maxSession value, the number 1, in quotes? If it still doesn't work, I would try 'maxSessions' , with an 's' on the end. The problem is probably something minor. Don't forget to login to the grid hub admin to check the settings after you start the grid. – djangofan Feb 16 '16 at 18:39
  • I'm basing my JSON configs on these ([hub](https://github.com/SeleniumHQ/selenium/blob/master/java/server/src/org/openqa/grid/common/defaults/DefaultHub.json) and [node](https://github.com/SeleniumHQ/selenium/blob/master/java/server/src/org/openqa/grid/common/defaults/DefaultNode.json)). Plural "maxSessions" and quoting the number didn't help. I had forgotten about the existence of the console though. When I try to reach it at http://localhost:4444/grid/console, I get a 403 error... – Sophist Feb 16 '16 at 19:53
  • One small update. I wrote some test scripts to vastly simplify the process by which I launch grid hub and node. My thinking was, start from scratch and streamline to see if the simplest possible version would work, then build back up from there. While this simpler version of the process solved the 403 I was getting from the hub admin console, it still ignores the maxSessions config. – Sophist Feb 24 '16 at 22:43
  • Good work. I don't know what else to suggest. Maybe use the SeleniumGridHub docker image: https://github.com/SeleniumHQ/docker-selenium/tree/master/Hub . Just install Docker Toolbox: https://www.docker.com/products/docker-toolbox and then launch Kitematic to get the GridHub image. – djangofan Feb 25 '16 at 00:51
  • I have new information on this bug. It seems to reside in the SeleniumServer construction; specifically, the "args" option array does not seem to be having any effect. Some of the above behavior turned out to be the cause of a bug of mine in attempting to determine if a grid hub was active and using it if so; the 5 cucumber processes proceeded in parallel because they were found no active hub. The symptom that revealed the root problem turned out to be that I couldn't reach http://localhost:4444/grid/console while running by tests because the selenium servers were created without role args. – Sophist Apr 14 '16 at 18:46
  • (continued) When I refactored my application to start the java processes using child_process.exec, everything seems to work more or less. Still, this approach has problems because it creates a race condition between the grid startup and my cucumber processes; there is no readiness waiting as I would get from chaining off of the start() promise. Is there any reason anyone can find in steps 1 and 2 above that my "args" list might not be working? I'd really rather not resort to child_process as a final solution. – Sophist Apr 14 '16 at 18:46

3 Answers3

1

It turns out it was just a problem with the way I was forming the args array. It expects param names and values to be separate items, so [ "-role hub", "-hubConfig " + config_path ] doesn't work, but [ "-role", "hub", "-hubConfig", config_path ] probably does.

I say probably because now I have a new problem where the hub start() times out after 30 seconds, but at least I can load up grid/console during those 30 seconds and see that the configuration is correct. Thanks @djangofan and @nash for your help.

Sophist
  • 33
  • 6
0

Update your testNG.xml file with thread-count="10" (or how many ever instance you want to run Ex: 2, 3, 4 etc)

I use testNG to run my tests in parallel. @Factory and @DataProvider generate my tests programatically. I was running into the same problem. After trying various workarounds I updated my testng.xml file with thread-count="10" and it worked.

I still wasn't able to get it to sync with .JSON file settings used as the hub config, but it did help me achieve what I was trying to. Here's my complete testNG.xml file (I do parallel="methods" as that's how @Factory works)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="SuiteMain" parallel="methods" thread-count="10">
    <test name="maintest">
        <classes>
            <class name="test.java.MainDriverScript"></class>
        </classes>
    </test>
</suite>
Nash N
  • 342
  • 2
  • 17
  • I don't use testNG, and don't relish adding another middle man into my application just to get this Selenium feature to work. If I'm understanding what you're saying though, it doesn't actually use Selenium Grid's config parameters to control the process, but rather sets up some external job queuing/threading system. (It's also a Java framework, whereas my application is Node.js). – Sophist Mar 23 '16 at 20:36
  • (continued from last) If I just wanted to process 10 jobs at a time -- and this is a compromise solution I'm considering now -- then it wouldn't be too hard to set that up using child processes and so forth; there's probably already an NPM module for it in fact. But that sacrifices the advertised Selenium capability of being able to set session and instance count on a browser-by-browser and node-by-node basis. It's much less configurable and much less scalable than the built in Selenium Grid feature theoretically would be. So I'm still hoping to be able to use that. – Sophist Mar 23 '16 at 20:40
  • See my other answer. PS: I was very inactive recently. Apologies for late reply – Nash N Dec 14 '17 at 18:38
0

What you are missing here is, Se Grid does not have the capability to initiate test scripts in parallel. If you're framework (I did it using TestNG) is capable of generating multi threads, then Se Grid will happily consume it and run them for you.

Se Grid is just an executor, it just consumes what you feed into it. You need to create and feed multiple parallel tests to it via your framework.

Nash N
  • 342
  • 2
  • 17