Selenium standalone-chrome with rspec in docker not working

  capybara, docker, rspec, selenium, webdriver

I want to use a standalone container for integration specs with RSpecs in my docker setup. This is my docker-compose.yml

# docker-compose.yml
x-ata-development: &ata-development
  volumes:
    - ./tmp/capybara/:/usr/src/app/tmp/capybara
    - ./:/usr/src/app:delegated
    - /usr/src/app/tmp
  build: .

version: "3.4"
services:
  ata:
    <<: *ata-development
    ports:
      - 3000:3000
      - 6006:6006
      - 9229:9229
    command: bash -c "bundle exec rails s -b 0.0.0.0"
    tty: true
    stdin_open: true
    depends_on:
      - chrome

  chrome:
    image: selenium/standalone-chrome
    ports:
      - 4444:4444
    networks:
      - app
    environment:
      - JAVA_OPTS=-Dwebdriver.chrome.whitelistedIps=

I’m executing the test from within a container like this:

❯ docker-compose exec ata bash
[email protected]:/usr/src/app# rspec  spec/my_spec.rb

Randomized with seed 30174

F

Failures:

  1) product with variants QuickEditButtons renders product quick edit buttons without JS errors
     Failure/Error: visit url

     Selenium::WebDriver::Error::UnknownError:
       unknown error: net::ERR_CONNECTION_REFUSED
         (Session info: headless chrome=88.0.4324.96)
     # #0 0x5558c713e199 <unknown>
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/response.rb:72:in `assert_ok'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/response.rb:34:in `initialize'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/common.rb:88:in `new'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/common.rb:88:in `create_response'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/default.rb:114:in `request'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/common.rb:64:in `call'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/bridge.rb:167:in `execute'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/w3c/bridge.rb:567:in `execute'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/w3c/bridge.rb:59:in `get'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/common/navigation.rb:32:in `to'
     # /usr/local/bundle/gems/capybara-3.35.3/lib/capybara/selenium/driver.rb:104:in `visit'
     # /usr/local/bundle/gems/capybara-3.35.3/lib/capybara/session.rb:278:in `visit'
     # /usr/local/bundle/gems/capybara-3.35.3/lib/capybara/dsl.rb:58:in `block (2 levels) in <module:DSL>'
     # ./spec/my_spec.rb:10:in `block (4 levels) in <top (required)>'

Finished in 8.47 seconds (files took 10.85 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/features/product_spec.rb:58 # product with variants QuickEditButtons renders product quick edit buttons without JS errors

Randomized with seed 30174
# my_spec.rb
it "visits a route" do
  visit "/my_route"
end
  1) visits a route
     Failure/Error: visit url

     Selenium::WebDriver::Error::UnknownError:
       unknown error: net::ERR_CONNECTION_REFUSED
         (Session info: headless chrome=88.0.4324.96)
     # #0 0x55a4b915e199 <unknown>
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/response.rb:72:in `assert_ok'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/response.rb:34:in `initialize'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/common.rb:88:in `new'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/common.rb:88:in `create_response'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/default.rb:114:in `request'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/http/common.rb:64:in `call'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/bridge.rb:167:in `execute'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/w3c/bridge.rb:567:in `execute'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/remote/w3c/bridge.rb:59:in `get'
     # /usr/local/bundle/gems/selenium-webdriver-3.142.7/lib/selenium/webdriver/common/navigation.rb:32:in `to'
     # /usr/local/bundle/gems/capybara-3.35.3/lib/capybara/selenium/driver.rb:104:in `visit'
     # /usr/local/bundle/gems/capybara-3.35.3/lib/capybara/session.rb:278:in `visit'
     # /usr/local/bundle/gems/capybara-3.35.3/lib/capybara/dsl.rb:58:in `block (2 levels) in <module:DSL>'

It says connection refused, but I see some log output for the chrome container when the test starts:

2021-02-04 16:37:18,645 INFO Included extra file "/etc/supervisor/conf.d/selenium.conf" during parsing
2021-02-04 16:37:18,649 INFO supervisord started with pid 8
2021-02-04 16:37:19,656 INFO spawned: 'xvfb' with pid 10
2021-02-04 16:37:19,660 INFO spawned: 'selenium-standalone' with pid 11
2021-02-04 16:37:20,663 INFO success: xvfb entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
2021-02-04 16:37:20,663 INFO success: selenium-standalone entered RUNNING state, process has stayed up for > than 0 seconds (startsecs)
16:37:21.699 INFO [GridLauncherV3.parse] - Selenium server version: 3.141.59, revision: e82be7d358
16:37:22.415 INFO [GridLauncherV3.lambda$buildLaunchers$3] - Launching a standalone Selenium Server on port 4444
2021-02-04 16:37:22.707:INFO::main: Logging initialized @2994ms to org.seleniumhq.jetty9.util.log.StdErrLog
16:37:23.934 INFO [WebDriverServlet.<init>] - Initialising WebDriverServlet
16:37:24.502 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 4444
16:39:57.721 INFO [ActiveSessionFactory.apply] - Capabilities are: {
  "browserName": "chrome",
  "cssSelectorsEnabled": true,
  "goog:chromeOptions": {
    "args": [
      "no-sandbox",
      "headless",
      "disable-gpu",
      "window-size=1400,12000",
      "whitelisted-ips",
      "host-resolver-rules=MAP * 127.0.0.1, EXCLUDE storage.googleapis.com"
    ]
  },
  "javascriptEnabled": true,
  "nativeEvents": false,
  "rotatable": false,
  "takesScreenshot": false,
  "version": ""
}
16:39:57.737 INFO [ActiveSessionFactory.lambda$apply$11] - Matched factory org.openqa.selenium.grid.session.remote.ServicedSession$Factory (provider: org.openqa.selenium.chrome.ChromeDriverService)
Starting ChromeDriver 88.0.4324.96 (68dba2d8a0b149a1d3afac56fa74648032bcf46b-refs/branch-heads/[email protected]{#1784}) on port 4469
All remote connections are allowed. Use an allowlist instead!
Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
ChromeDriver was started successfully.
16:39:59.557 INFO [ProtocolHandshake.createSession] - Detected dialect: W3C
16:39:59.636 INFO [RemoteSession$Factory.lambda$performHandshake$0] - Started new session c1965f0e410ae251a0ac4dc31322e170 (org.openqa.selenium.chrome.ChromeDriverService)
16:40:02.166 INFO [ActiveSessions$1.onStop] - Removing session c1965f0e410ae251a0ac4dc31322e170 (org.openqa.selenium.chrome.ChromeDriverService)

And this is my driver that I register:

Capybara.register_driver :chrome_headless do |app|
  args = %w[no-sandbox headless disable-gpu window-size=1400,12000]
  options = Selenium::WebDriver::Chrome::Options.new(args: args)

  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    options: options,
    url: "http://chrome:4444/wd/hub"
  )
end
Capybara.javascript_driver = :chrome_headless

I’m pretty much out of ideas, as I’ve been trying every tip I could find so far, but nothing worked.

Source: Docker Questions

LEAVE A COMMENT