I would like to run an RSpec/Capybara test suite in Docker. This test suite performs a file download.
If I run the test suite with rspec, I am able to access the downloaded file.
If I run both rspec and selenium chrome as containers, I cannot figure out how to access the downloaded file.
2.7.0
source "https://rubygems.org"
gem 'rspec'
gem 'capybara'
gem 'capybara-webmock'
gem 'colorize'
gem 'webdrivers'
#gem 'chromedriver-helper'
gem 'selenium-webdriver'
gem 'byebug'
require 'colorize'
require 'capybara/dsl'
require 'capybara/rspec'
require 'byebug'
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://github.com'
Capybara.run_server = false # don't start Rack
if ENV['CHROME_URL']
Capybara.register_driver :selenium_chrome_headless do |app|
args = [
'--no-default-browser-check',
'--start-maximized',
'--headless',
'--disable-dev-shm-usage',
'--whitelisted-ips'
]
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
end
@session = Capybara::Session.new(:selenium_chrome_headless)
#@session = Capybara::Session.new(:selenium_chrome)
end
require 'spec_helper.rb'
require 'webdrivers/chromedriver'
sleep 1
RSpec.describe 'basic_tests', type: :feature do
before(:each) do
@session = create_web_session
end
it 'Load page' do
@session.visit '/docker/compose/releases/tag/1.27.0'
@session.find_link('Source code (zip)')
@session.click_link('Source code (zip)')
sleep 3
f = File.join('compose-1.27.0.zip')
expect(File.exists?(f)).to be true
File.delete(f)
end
end
FROM ruby:2.7
RUN gem install bundler
COPY Gemfile Gemfile
COPY Gemfile.lock Gemfile.lock
RUN bundle install
COPY . .
RUN chmod 777 .
CMD ["bundle", "exec", "rspec", "spec"]
version: '3.7'
networks:
mynet:
services:
rspec-chrome:
container_name: rspec-chrome
image: rspec-chrome
build:
context: .
dockerfile: Dockerfile
environment:
CHROME_URL: http://chrome:4444/wd/hub
stdin_open: true
tty: true
networks:
mynet:
depends_on:
- chrome
chrome:
container_name: chrome
image: selenium/standalone-chrome
networks:
mynet:
volumes:
- /dev/shm:/dev/shm
basic_tests
Load page
Finished in 8.45 seconds (files took 6.79 seconds to load)
1 example, 0 failures
docker-compose up -d --build
docker logs -f rspec-chrome
basic_tests
Load page (FAILED - 1)
Failures:
1) basic_tests Load page
Failure/Error: expect(File.exists?(f)).to be true
expected true
got false
# /spec/test/demo_spec.rb:17:in `block (2 levels) in <top (required)>'
The following modifications resolved my issue.
Pass the following prefs in chromeOptions
"prefs" => {
'download.default_directory' => '/tmp',
'download.directory_upgrade' => true,
'download.prompt_for_download' => false
}
Here is the complete file
require 'colorize'
require 'capybara/dsl'
require 'capybara/rspec'
require 'byebug'
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://github.com'
Capybara.run_server = false # don't start Rack
if ENV['CHROME_URL']
Capybara.register_driver :selenium_chrome_headless do |app|
args = [
'--no-default-browser-check',
'--start-maximized',
'--headless',
'--disable-dev-shm-usage',
'--whitelisted-ips'
]
caps = Selenium::WebDriver::Remote::Capabilities.chrome("chromeOptions" => {
"args" => args,
"prefs" => {
'download.default_directory' => '/tmp',
'download.directory_upgrade' => true,
'download.prompt_for_download' => false
}
})
Capybara::Selenium::Driver.new(
app,
browser: :remote,
desired_capabilities: caps,
url: ENV['CHROME_URL']
)
end
end
@session = Capybara::Session.new(:selenium_chrome_headless)
#@session = Capybara::Session.new(:selenium_chrome)
end
Change directory to /tmp and look for the download in /tmp
require 'spec_helper.rb'
require 'webdrivers/chromedriver'
sleep 1
RSpec.describe 'basic_tests', type: :feature do
before(:each) do
@session = create_web_session
Dir.chdir "/tmp"
end
it 'Load page' do
@session.visit '/docker/compose/releases/tag/1.27.0'
@session.find_link('Source code (zip)')
@session.click_link('Source code (zip)')
sleep 3
f = File.join('/tmp','compose-1.27.0.zip')
expect(File.exists?(f)).to be true
File.delete(f)
end
end
Share /tmp as a docker volume between the rspec and chrome containers
version: '3.7'
networks:
mynet:
volumes:
downloads:
services:
rspec-chrome:
container_name: rspec-chrome
image: rspec-chrome
build:
context: .
dockerfile: Dockerfile
environment:
CHROME_URL: http://chrome:4444/wd/hub
stdin_open: true
tty: true
networks:
mynet:
depends_on:
- chrome
volumes:
- downloads:/tmp
chrome:
container_name: chrome
image: selenium/standalone-chrome
networks:
mynet:
volumes:
- /dev/shm:/dev/shm
- downloads:/tmp