5
votes

I'm using chrome headless with Selenium (3.14.0) and Capybara (3.8.0) in my Ruby on Rails (5.2.1) project and I have a test which works in Non-headless chrome but not in headless chrome. I'm using the '--headless' flag on google chrome stable version 69.

I've setup my headless chrome with the following and this works for all tests which don't download files.

download_path="#{Rails.root}/tmp/downloads"

Capybara.register_driver(:headless_chrome) do |app|
  caps = Selenium::WebDriver::Remote::Capabilities.chrome(
    chromeOptions: {
      prefs: {
        'download.default_directory' => download_path,
        "download.extensions_to_open" => "applications/pdf",
        'download.directory_upgrade' => true,
        'download.prompt_for_download' => false,
        'plugins.plugins_disabled' => ["Chrome PDF Viewer"]
      },
      binary: "/opt/google/chrome/google-chrome",
      args: %w[headless disable-gpu window-size=1920,1080]
    }
  )
  Capybara::Selenium::Driver.new(
    app,
    browser: :chrome,
    desired_capabilities: caps
  )
end

I've read that I should be sending a command to selenium chrome driver to allow downloads but I cannot figure out how to do that with my setup. Here is what I'm trying to get working, but with my setup; (not from my code base);

@driver = Selenium::WebDriver.for :chrome, options: options

bridge = @driver.send(:bridge)
path = '/session/:session_id/chromium/send_command'
path[':session_id'] = bridge.session_id
bridge.http.call(:post, path, cmd: 'Page.setDownloadBehavior',
                 params: {
                   behavior: 'allow',
                   downloadPath: download_path
                 })

How do I access the selenium bridge in my setup so that I can send this http call?

1

1 Answers

10
votes

You don't need to send that manually anymore it was added to selenium as Selenium::WebDriver::Chrome::Server#download_path=. You can set it in your driver registration via the Capybara::Selenium::Driver instance

...
Capybara::Selenium::Driver.new(
  app,
  browser: :chrome,
  desired_capabilities: caps
).tap { |d| d.browser.download_path = <your download path> }