Ruby - 无法在45秒内绑定到锁定端口7054 (Selenium::WebDriver::Error::WebDriverError)

11

最近我在运行任何Cucumber测试时都会看到这个错误消息。我进行了一些研究,并找到了一些类似的错误实例,但大多数都是与浏览器相关的问题。在此输出中,我没有看到任何特定于浏览器的错误消息:

unable to bind to locking port 7054 within 45 seconds (Selenium::WebDriver::Error::WebDriverError)

我在这里看到了另一个问题的答案(A selenium webdriver exception),但那个解决方案对我没有用。运行"lsof -i TCP:7054"没有产生任何输出。

以防万一有人建议这样做,我已经多次重新启动了我的机器,并擦除了我的gemset并重新运行了"bundle"。

以下是我正在使用的相关gems:

capybara (0.4.1.2)
cucumber (0.10.7)   
cucumber-rails (0.4.1)
fuubar-cucumber (0.0.9)
selenium-webdriver (0.2.0)

为了确保,我也尝试使用Firefox 3.6、4.0和5.0运行这些测试。每次都出现相同的消息。

不是要成为阴谋论者,但在手动退出我的测试套件并对Cucumber启动的所有活动Firefox进程运行pkill之前,一切都正常工作。在测试套件期间,我大约有9个Firefox实例同时运行。我不确定这是否会导致某些问题发生,从而产生我现在运行Cucumber测试时看到的结果。

是否有人有任何修复此问题的建议?


你尝试在等待连接的45秒窗口期内运行lsof命令了吗?使用$DEBUG = true(或将-d传递给ruby)运行将提供更多的调试输出。 - jarib
我在第一次测试期间运行了lsof,在45秒的时间窗口内。我仍然没有得到任何输出。以调试模式运行会为我提供每个宝石的此错误:“Exception NoMethodError' at rvm/gems/ruby-1.9.2-p136/gems/bundler-1.0.15/lib/bundler/lazy_specification.rb:66 - undefined method to_ary' for json_pure (1.5.1):Bundler::LazySpecification”。 - Joel Andritsch
$DEBUG = true 将打印所有被拯救的异常,因此预计会有大量输出。看到这些输出将有助于我们诊断您的问题。 - jarib
抱歉,在你的 Ruby 代码中,$DEBUG 需要被设置为全局变量,而不是环境变量。同样的效果可以通过在命令行中传递 -d 给 ruby 来实现。 - jarib
4个回答

18

更新:问题已解决

将$DEBUG设置为true并重新运行测试后,这个错误变得更加有趣:

<Selenium::WebDriver::Firefox::SocketLock:0x00000102f9c010>: getaddrinfo: nodename nor servname provided, or not known
Exception `SocketError' at /Users/bobrossasaurus/.rvm/gems/ruby-1.9.2-p136/gems/selenium-webdriver-0.2.0/lib/selenium/webdriver/common/platform.rb:131 - getaddrinfo: nodename nor servname provided, or not known

在查看platform.rb:131时,我注意到它试图连接到端口80上的"localhost",但连接失败了。这引起了我的警觉,因为最近我通过浏览器访问"localhost"时遇到了问题,必须使用127.0.0.1:3000来查看我的rails项目。

解决方案:

/etc/hosts文件中缺少了localhost主机条目:

127.0.0.1 localhost

虽然这是一个令人尴尬的问题,但这正是答案。


+1:我把我的Windows主机文件复制到了OS X上。Windows不需要localhost条目(它由DNS处理),但是OS X需要。如果我没有找到你的答案,我可能不会知道如何解决这个问题,所以谢谢。 - rsenna

0

我能够在初始化器中少做一些工作来重置这个常量。我需要将它设置得更短,这样我的脚本就可以创建另一个浏览器了。

# config/initializers/selenium.rb

module Selenium module WebDriver module Firefox class Launcher Selenium::WebDriver::Firefox::Launcher::SOCKET_LOCK_TIMEOUT = 10 end end end end


0
我在使用Chrome时遇到了同样的问题,并在我的application_system_test_case.rb中使用了以下内容:
class Selenium::WebDriver::Service
  remove_const(:SOCKET_LOCK_TIMEOUT)
  SOCKET_LOCK_TIMEOUT = 120
end

0

由于这是谷歌和DuckDuckGo上此问题的最高得分条目,我将在此记录我的解决方法。据我所知,问题在于selenium使用端口7054作为互斥锁*来解决firefox启动时分叉真实的firefox并退出启动脚本的问题。因此,真正的fox的PID只能从selenium中猜测,并且同时启动多个firefox副本会导致不断的竞争条件。因此,锁定端口,如果需要同时启动许多firefox,则可能成为问题。

我们的解决方法是增加此超时时间。

# Starting many firefoxen in parallel can easily take more than 45 (default) seconds
module Selenium
  module WebDriver
    module Firefox
      class Launcher
        remove_const(:SOCKET_LOCK_TIMEOUT)
      end
    end
  end
end
Selenium::WebDriver::Firefox::Launcher::SOCKET_LOCK_TIMEOUT = 90

在Selenium的启动代码中。

修复建议参考此提示:http://www.assertselenium.com/selenium-tips-tricks/

* 互斥锁是一种程序对象,允许多个程序线程共享同一资源(如文件访问),但不能同时进行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接