Headless Gem causes Errno::ECONNREFUSED

Have you ever gotten this error while trying to run simultaneous headless Firefox instances of WebDriver?

Errno::ECONNREFUSED: Connection refused - connect(2)
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:762:in `initialize'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:762:in `open'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:762:in `block in connect'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/timeout.rb:54:in `timeout'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/timeout.rb:99:in `timeout'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:762:in `connect'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:755:in `do_start'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:744:in `start'
/home/site/.rvm/rubies/ruby-1.9.3-p385/lib/ruby/1.9.1/net/http.rb:1284:in `request'

This one was plaguing me for a while. I could not understand why Firefox could not run separate instances of itself, when the SWD documentation indicated that each run used an entirely separate temporary Firefox profile, and so the instances would not conflict with each other.

But sure enough, if I started another job while one was already running, I would get the above error on the first job, while the second job hijacked the connection.

After really delving into the issue, I finally realized that the issue was not the Firefox profiles conflicting. Instead, the issues came from my usage of the headless gem to run the jobs headlessly using Xvfb. I was not defining a specific display to use when my scripts ran, and so the headless gem would default to using the :99 display. This was all fine and good when running the scripts individually. But if you run multiple scripts that try to use the same display, the first script gets disconnected from the headless session and the second script takes over.

The solution to this problem is to explicitly define a display number to use for each script that runs. This works especially well if you are running your scripts in a CI environment like Jenkins, where each build is given its own number that you can easily access as an environmental variable such as “BUILD_NUMBER”. Other ideas are to generate a random display number on the fly, or use another means to generate any integer number.

display = ENV['BUILD_NUMBER'] || "99"
@headless = Headless.new(:display => display)

This will generate a headless session on the display number that is defined by the BUILD_NUMBER environmental variable, and as long as the build numbers are completely different from each other, you will be good.