I am attempting to write a Capybara test suite in Ruby (without Rails).
I would like to run the Ruby code in a Docker container.
FROM ruby:2.7
RUN gem install bundler
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install
COPY . .
CMD ["bundle", "exec", "rspec", "spec"]
My tests require a headless version of Chrome which is not available in the Ruby image. I have attempted to create a docker-compose file to include the Ruby code and a headless Chrome image.
version: '3.7'
networks:
mynet:
services:
admin:
container_name: mrt-integ-tests
image: cdluc3/mrt-integ-tests
build:
context: .
dockerfile: Dockerfile
volumes:
- type: bind
source: ./config/test_config.yml
target: /config/test_config.yml
stdin_open: true
tty: true
networks:
mynet:
depends_on:
- chrome
chrome:
container_name: chrome
image: selenium/standalone-chrome
ports:
- published: 4444
target: 4444
networks:
mynet:
This is how I am attempting to create my Capybara session:
Capybara.register_driver :selenium_chrome do |app|
args = ['--no-default-browser-check', '--start-maximized', '--headless', '--disable-dev-shm-usage']
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {"args" => args})
Capybara::Selenium::Driver.new(
app,
browser: :remote,
desired_capabilities: caps,
url: "http://chrome:4444/wd/hub"
)
end
@session = Capybara::Session.new(:selenium_chrome)
When I start my containers, I see the following error.
chrome | 05:39:44.350 INFO [GridLauncherV3.lambda$buildLaunchers$3] - Launching a standalone Selenium Server on port 4444
chrome | 2020-06-04 05:39:44.420:INFO::main: Logging initialized @766ms to org.seleniumhq.jetty9.util.log.StdErrLog
chrome | 05:39:44.920 INFO [WebDriverServlet.<init>] - Initialising WebDriverServlet
chrome | 05:39:45.141 INFO [SeleniumServer.boot] - Selenium Server is up and running on port 4444
chrome | 05:39:47.431 INFO [ActiveSessionFactory.apply] - Capabilities are: {
chrome | "browserName": "chrome",
chrome | "chromeOptions": {
chrome | "args": [
chrome | "--no-default-browser-check",
chrome | "--start-maximized",
chrome | "--headless",
chrome | "--disable-dev-shm-usage"
chrome | ]
chrome | },
chrome | "cssSelectorsEnabled": true,
chrome | "javascriptEnabled": true,
chrome | "nativeEvents": false,
chrome | "rotatable": false,
chrome | "takesScreenshot": false,
chrome | "version": ""
chrome | }
chrome | 05:39:47.435 INFO [ActiveSessionFactory.lambda$apply$11] - Matched factory org.openqa.selenium.grid.session.remote.ServicedSession$Factory (provider: org.openqa.selenium.chrome.ChromeDriverService)
chrome | Starting ChromeDriver 83.0.4103.39 (ccbf011cb2d2b19b506d844400483861342c20cd-refs/branch-heads/4103@{#416}) on port 13554
chrome | Only local connections are allowed.
chrome | Please see https://chromedriver.chromium.org/security-considerations for suggestions on keeping ChromeDriver safe.
chrome | ChromeDriver was started succ[e1s5s9f1u2l4l9y1.8
chrome | 7.473][SEVERE]: bind() failed: Cannot assign requested address (99)
chrome | 05:39:48.211 INFO [ProtocolHandshake.createSession] - Detected dialect: W3C
chrome | 05:39:48.247 INFO [RemoteSession$Factory.lambda$performHandshake$0] - Started new session 1ed95304843a1d5ab904708d998710a0 (org.openqa.selenium.chrome.ChromeDriverService)
What suggestions do you have to resolve this error?
To run this script
docker-compose build
docker-compose up -d chrome
docker-compose run --rm my-integ-tests
docker-compose down
version: '3.9'
services:
my-integ-tests:
container_name: my-integ-tests
image: test/my-integ-tests
build:
context: .
dockerfile: Dockerfile
environment:
CHROME_URL: http://chrome:4444/wd/hub
stdin_open: true
tty: true
depends_on:
- chrome
chrome:
container_name: chrome
image: selenium/standalone-chrome
environment:
JAVA_OPTS: -Dwebdriver.chrome.whitelistedIps= -Dwebdriver.chrome.allowedIps=
shm_size: '2gb'
#FROM ruby:2.7
FROM ruby:3
RUN apt-get update -y && \
apt-get -y upgrade && \
apt-get install -y libarchive-tools zip
RUN gem install bundler
COPY Gemfile Gemfile
RUN bundle install
COPY . .
CMD ["bundle", "exec", "rspec", "/spec/test"]
source "https://rubygems.org"
gem 'rspec'
gem 'capybara'
gem 'capybara-webmock'
gem 'colorize'
gem 'webdrivers'
#gem 'chromedriver-helper'
gem 'selenium-webdriver'
gem 'byebug'
gem 'nokogiri'
require 'colorize'
require 'capybara/dsl'
require 'capybara/rspec'
require 'nokogiri'
RSpec.configure do |config|
config.color = true
config.tty = true
config.formatter = :documentation
config.include Capybara::DSL
end
def create_web_session
Capybara.app_host = "https://www.google.com"
Capybara.run_server = false # don't start Rack
if ENV['CHROME_URL']
Capybara.register_driver :remote do |app|
Capybara::Selenium::Driver.new(app, browser: :remote, options: Selenium::WebDriver::Options.chrome, url: ENV['CHROME_URL'])
end
@session = Capybara::Session.new(:remote)
else
@session = Capybara::Session.new(:selenium_chrome)
end
end
def end_web_session(session)
session.reset!
session.driver.quit
end
require 'spec_helper.rb'
require 'webdrivers/chromedriver'
require 'cgi'
sleep 1
RSpec.describe 'simple tests', type: :feature do
before(:each) do
@session = create_web_session
end
after(:each) do
end_web_session(@session)
end
it 'Load home page' do
@session.visit '/'
end
end