我想在 Docker 中运行 RSpec/Capybara 测试套件。该测试套件执行文件下载。
如果我使用 rspec 运行测试套件,我就可以访问下载的文件。
如果我将 rspec 和 selenium chrome 作为容器运行,我无法弄清楚如何访问下载的文件。
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)>'
当您有 Chrome 下载文件时,它们将被下载到 Chrome 容器中,因此要从运行测试的容器访问它们,您可能需要在两个容器之间创建一个共享卷并将其挂载为 Chrome 下载目录。
以下修改解决了我的问题。
在 chromeOptions 中传递以下首选项
"prefs" => {
'download.default_directory' => '/tmp',
'download.directory_upgrade' => true,
'download.prompt_for_download' => false
}
这是完整的文件
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
将目录更改为 /tmp 并在 /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
在 rspec 和 chrome 容器之间将 /tmp 共享为 docker 卷
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