【问题标题】:Accessing file downloads from containerized RSpec/Capybara and Selenium Chrome从容器化的 RSpec/Capybara 和 Selenium Chrome 访问文件下载
【发布时间】:2020-12-02 22:07:37
【问题描述】:

我想在 Docker 中运行 RSpec/Capybara 测试套件。此测试套件执行文件下载。

如果我使用 rspec 运行测试套件,我可以访问下载的文件。

如果我将 rspec 和 selenium chrome 作为容器运行,我无法弄清楚如何访问下载的文件。

.ruby 版本

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'

spec/spec_helper.rb

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

spec/test/demo_spec.rb

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

Dockerfile

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"]

docker-compose.yml

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

运行 rspec 时的输出

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)>'

【问题讨论】:

    标签: docker selenium-webdriver docker-compose capybara


    【解决方案1】:

    当您拥有 Chrome 下载文件时,它们将被下载到 Chrome 容器中,因此要从运行测试的容器中访问它们,您可能需要在两个容器之间创建一个共享卷并将其挂载为 Chrome 下载目录。

    【讨论】:

    • 我尝试将卷绑定到 /home/seluser/Downloads,但我无法看到我的下载内容出现在该文件夹中。
    • @terrywb 我不知道你的 chrome 配置中的下载目录是什么。下载文件后连接到正在运行的容器并检查它的保存位置
    • 很遗憾,docker exec -it chrome find / -name 'compose-1.27.0.zip' 没有找到任何文件。
    • @terrywb 然后听起来它实际上并没有下载文件——点击下载链接并休眠后截屏,这样你就可以看到页面认为它完成了什么。在为有效的运行注册驱动程序时,您是否将相同的选项传递给 Chrome?通常需要传递一些配置选项来将 Chrome 配置为不提示下载。
    • 感谢您的提示。修改传递给 Chrome 的首选项后,我能够看到下载的内容。
    【解决方案2】:

    以下修改解决了我的问题。

    spec/spec_helper.rb

    在 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
    
    

    spec/test/demo_spec.rb

    将目录更改为 /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
    
    

    docker-compose.yml

    在 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-19
      • 2023-03-13
      • 2015-06-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-15
      相关资源
      最近更新 更多