【问题标题】:selenium grid for python errorpython错误的硒网格
【发布时间】:2017-12-12 10:30:38
【问题描述】:

我在 ubuntu virtualbox 上为 python 3 运行 selenium 网格, 我设置了一个网格

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

一切似乎都很好,我上了终端

INFO - Selenium Grid 中心已启动并正在运行

我添加一个节点

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

一切似乎都很好,我上了终端

INFO - 节点已注册到集线器并可以使用

INFO - SessionCleaner 初始化为 insideBrowserTimeout 0 和 clientGoneTimeout 1800000,每 180000 轮询一次

如果我使用节点地址 http://10.0.2.15:5555/wd/hub 运行此代码 一切正常

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()

如果我使用网格地址http://10.0.2.15:4444/wd/hub 运行上面的代码,就像假设它必须那样,我总是会收到错误:

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)

我在 virtualbox 和 selenium python 上运行 ubuntu 的问题可能出在哪里

非常感谢

【问题讨论】:

  • 从给出的信息中唯一有意义的事情(尽管回溯通常会告诉你)是网格系统上的端口 4444 上已经运行了一些东西。你可以在命令中执行netstat -a行以查看该端口上是否正在运行任何东西。

标签: python-3.x selenium selenium-grid


【解决方案1】:

您实际上可能偶然发现了 Grid 端的一个错误(已经修复但等待发布)

当您的 python 客户端代码通过以下行实例化一个新的 Remote WebDriver 时

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)

这将被翻译成以下形式的 JSON 负载

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

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

在网格方面(Selenium Grid v.3.4.0),集线器尝试使用org.openqa.grid.web.servlet.handler.WebDriverRequest#extractDesiredCapability 中的以下逻辑将此 JSON 解析为所需的功能:

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);
    }
}

如您所见,此逻辑最终会为所需功能返回 NULL 值,因为:

  • 在 JSON 有效负载中,找到了元素 capabilities,但 在 JSON 子元素 capabilities 中,没有名为 desiredCapabilities 的子元素
  • 这会导致通过extractDesiredCapability() 返回一个NULL 映射并最终触发NullPointerException

我知道这已经作为this 提交的一部分在 Selenium Grid 代码库中得到修复,它在实例化 HashMap 之前添加了一个 Null Check 防护,this 提交确保 Grid 基本上检查是否:

  • JSON 有效负载有一个名为 capabilities 的键和
  • 在键 capabilities 中有一个名为 desiredCapabilities 的子键,然后它会尝试将功能提取为映射,如果不只是查找键 desiredCapabilities

另一方面,如果您将测试代码直接指向节点,它工作正常,因为当测试被路由到节点时,不涉及上述解析。

所以现在我建议您回滚到使用 Grid 的 Selenium 2.53.1 直到下一个版本(包含上述两个提交)发布。

希望对您有所帮助。

【讨论】:

  • 非常感谢您的回复,我为此发疯了
  • 除了降级还有其他解决方法吗?我不敢相信他们会像这样彻底打破网格......
  • 我终于在这篇文章中找到了一个解决方法:github.com/SeleniumHQ/selenium/issues/… 它似乎有效,但我还没有寻找任何副作用。
猜你喜欢
  • 1970-01-01
  • 2014-05-24
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多