Andrea Garcia
Andrea Garcia

Reputation: 31

selenium grid for python error

i run selenium grid for python 3 on ubuntu virtualbox, i setup a grid

java -jar selenium-server-standalone-3.4.0.jar -port 4444 -role hub

everything seems ok i get on terminal

INFO - Selenium Grid hub is up and running

i add a node

java -jar selenium-server-standalone-3.4.0.jar -role webdriver -browser "browserName=firefox,version=54,maxinstance=2,platform=LINUX" -hub http://localhost:4444/grid/register -port 5555

everything seems ok i get on terminal

INFO - The node is registered to the hub and ready to use

INFO - SessionCleaner initialized with insideBrowserTimeout 0 and clientGoneTimeout 1800000 polling every 180000

if i run this code with node address http://10.0.2.15:5555/wd/hub everything works

PLATFORM = 'LINUX' 
BROWSER = 'firefox'

     def setUp(self):
         desired_caps = {}
         desired_caps['platform'] = self.PLATFORM
        desired_caps['browserName'] = self.BROWSER
         self.driver = \
             webdriver.Remote('http://10.0.2.15:5555/wd/hub', desired_caps)
         self.driver.get("https://www.facebook.com/login/")
         self.driver.implicitly_wait(30)    self.driver.maximize_window()

if i run the code above with the grid address http://10.0.2.15:4444/wd/hub like it's supposed it has to be i always get an error:

Error
Traceback (most recent call last):
  File "/home/thorbuntu/PycharmProjects/seletests/grid_test.py", line 21, in setUp
    webdriver.Remote('http://10.0.2.15:4444/wd/hub', desired_caps)
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webdriver.py", line 98, in __init__
    self.start_session(desired_capabilities, browser_profile)
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webdriver.py", line 188, in start_session
    response = self.execute(Command.NEW_SESSION, parameters)
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/webdriver.py", line 256, in execute
    self.error_handler.check_response(response)
  File "/usr/local/lib/python3.5/dist-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: None
Stacktrace:
    at java.util.HashMap.putMapEntries (HashMap.java:500)
    at java.util.HashMap.putAll (HashMap.java:784)
    at org.openqa.selenium.remote.DesiredCapabilities.<init> (DesiredCapabilities.java:55)
    at org.openqa.grid.web.servlet.handler.RequestHandler.process (RequestHandler.java:104)
    at org.openqa.grid.web.servlet.DriverServlet.process (DriverServlet.java:83)
    at org.openqa.grid.web.servlet.DriverServlet.doPost (DriverServlet.java:67)
    at javax.servlet.http.HttpServlet.service (HttpServlet.java:707)
    at javax.servlet.http.HttpServlet.service (HttpServlet.java:790)
    at org.seleniumhq.jetty9.servlet.ServletHolder.handle (ServletHolder.java:841)
    at org.seleniumhq.jetty9.servlet.ServletHandler.doHandle (ServletHandler.java:543)
    at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextHandle (ScopedHandler.java:188)
    at org.seleniumhq.jetty9.server.session.SessionHandler.doHandle (SessionHandler.java:1584)
    at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextHandle (ScopedHandler.java:188)
    at org.seleniumhq.jetty9.server.handler.ContextHandler.doHandle (ContextHandler.java:1228)
    at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextScope (ScopedHandler.java:168)
    at org.seleniumhq.jetty9.servlet.ServletHandler.doScope (ServletHandler.java:481)
    at org.seleniumhq.jetty9.server.session.SessionHandler.doScope (SessionHandler.java:1553)
    at org.seleniumhq.jetty9.server.handler.ScopedHandler.nextScope (ScopedHandler.java:166)
    at org.seleniumhq.jetty9.server.handler.ContextHandler.doScope (ContextHandler.java:1130)
    at org.seleniumhq.jetty9.server.handler.ScopedHandler.handle (ScopedHandler.java:141)
    at org.seleniumhq.jetty9.server.handler.HandlerWrapper.handle (HandlerWrapper.java:132)
    at org.seleniumhq.jetty9.server.Server.handle (Server.java:564)
    at org.seleniumhq.jetty9.server.HttpChannel.handle (HttpChannel.java:320)
    at org.seleniumhq.jetty9.server.HttpConnection.onFillable (HttpConnection.java:251)
    at org.seleniumhq.jetty9.io.AbstractConnection$ReadCallback.succeeded (AbstractConnection.java:279)
    at org.seleniumhq.jetty9.io.FillInterest.fillable (FillInterest.java:112)
    at org.seleniumhq.jetty9.io.ChannelEndPoint$2.run (ChannelEndPoint.java:124)
    at org.seleniumhq.jetty9.util.thread.QueuedThreadPool.runJob (QueuedThreadPool.java:672)
    at org.seleniumhq.jetty9.util.thread.QueuedThreadPool$2.run (QueuedThreadPool.java:590)
    at java.lang.Thread.run (Thread.java:748)

where can be the problem i'm rinning ubuntu on virtualbox and selenium python

thanks a lot

Upvotes: 1

Views: 1685

Answers (1)

Krishnan Mahadevan
Krishnan Mahadevan

Reputation: 14746

You may have actually stumbled into a bug in the Grid side (which has been fixed already but pending a release)

When your python client code instantiates a new Remote WebDriver via the below lines

desired_caps = {}
desired_caps['platform'] = self.PLATFORM
desired_caps['browserName'] = self.BROWSER

self.driver = webdriver.Remote('http://10.0.2.15:4444/wd/hub', desired_caps)

This gets translated into a JSON payload of the below form

{
    "capabilities": {
        "alwaysMatch": {
            "browserName": "chrome"
        },
        "firstMatch": [

        ]
    },
    "desiredCapabilities": {
        "browserName": "chrome"
    }
}

On the grid side (Selenium Grid v.3.4.0), the hub attempts at parsing this JSON into a desired capability using the below logic in org.openqa.grid.web.servlet.handler.WebDriverRequest#extractDesiredCapability:

public Map<String, Object> extractDesiredCapability() {
    String json = getBody();
    try {
      JsonObject map = new JsonParser().parse(json).getAsJsonObject();
      // Current W3C has required / desired capabilities wrapped in a 'capabilites' object.
      // This will need to be updated if/when https://github.com/w3c/webdriver/pull/327 gets merged
      if (map.has("capabilities")) {
        return new JsonToBeanConverter().convert(Map.class, map.getAsJsonObject("capabilities").getAsJsonObject("desiredCapabilities"));
      }
      JsonObject dc = map.get("desiredCapabilities").getAsJsonObject();
      return new JsonToBeanConverter().convert(Map.class, dc);

    } catch (Exception e) {
      throw new GridException("Cannot extract a capabilities from the request: " + json, e);
    }
}

As you can see, this logic ends up returning a NULL value for the desired capabilities because :

  • In the JSON Payload, the element capabilities was found but Within the JSON sub element capabilities, there was no sub element called desiredCapabilities
  • This causes a NULL map to be returned via extractDesiredCapability() and eventually triggers a NullPointerException.

I know that this has now been fixed in the Selenium Grid codebase as part of this commit which adds a Null Check guard before instantiating a HashMap and this commit ensures that the Grid basically checks if :

  • The JSON payload has a key called capabilities and
  • Within the key capabilities there's a subkey called desiredCapabilities before it attempts at extracting the capabilities as a map and if not just look for the key desiredCapabilities.

If on the other hand you point your test code directly to the node, it works fine, because none of this above mentioned parsing is involved when a test is routed to the node.

So for now I would suggest that you please roll back to using Selenium 2.53.1 of Grid till the next version (which contains both the above cited commits) is released.

Hope that helps.

Upvotes: 1

Related Questions