Skip to content

Instantly share code, notes, and snippets.

@bbonamin
Last active March 19, 2024 14:54
Show Gist options
  • Star 60 You must be signed in to star a gist
  • Fork 8 You must be signed in to fork a gist
  • Save bbonamin/4b01be9ed5dd1bdaf909462ff4fdca95 to your computer and use it in GitHub Desktop.
Save bbonamin/4b01be9ed5dd1bdaf909462ff4fdca95 to your computer and use it in GitHub Desktop.
Capybara Selenium Webdriver: Headless Chrome (with file downloads!) & Headless Firefox
tap "caskroom/cask"
cask "google-chrome"
cask "firefox"
brew "chromedriver"
brew "geckodriver"
require 'capybara/rspec'
require 'selenium/webdriver'
options = Selenium::WebDriver::Chrome::Options.new
options.add_preference(:download, prompt_for_download: false,
default_directory: '/tmp/downloads')
options.add_preference(:browser, set_download_behavior: { behavior: 'allow' })
Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
end
Capybara.register_driver :headless_chrome do |app|
options.add_argument('--headless')
options.add_argument('--disable-gpu')
options.add_argument('--window-size=1280,800')
driver = Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
### Allow file downloads in Google Chrome when headless!!!
### https://bugs.chromium.org/p/chromium/issues/detail?id=696481#c89
bridge = driver.browser.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: '/tmp/downloads'
})
###
driver
end
Capybara.javascript_driver = ENV['GUI'] ? :chrome : :headless_chrome
require 'capybara/rspec'
require 'selenium/webdriver'
Capybara.register_driver :firefox do |app|
Capybara::Selenium::Driver.new(app, browser: :firefox)
end
Capybara.register_driver :headless_firefox do |app|
options = Selenium::WebDriver::Firefox::Options.new
options.headless! # added on https://github.com/SeleniumHQ/selenium/pull/4762
Capybara::Selenium::Driver.new app,
browser: :firefox,
options: options
end
Capybara.javascript_driver = ENV['GUI'] ? :firefox : :headless_firefox
source 'https://rubygems.org'
gem 'selenium-webdriver'
gem 'capybara'
gem 'rspec'
@vizcay
Copy link

vizcay commented Jan 18, 2021

The section on how to download attachments from chromedriver headless in ruby was very useful. Thanks 👏

@galliani
Copy link

thank you for this gist, very useful to me across multiple projects!

@beerdy
Copy link

beerdy commented Oct 30, 2022

BIG BIG THANK YOU!!!!!

@ozzyaaron
Copy link

Was anybody able to get this to work for multiple tests/scenarios?

In my case I had to run the code that sets Page.setDownloadBehavior before every test that needed to do a headless download. It would download to the path specified on the first test but then on subsequent tests the download worked but instead was downloaded to the project root folder rather than the directory in downloadPath.

In a Before(@javascript) I just run the code that makes the http call to bridge and now it works for every test.

I did check that the session_id was the same between test runs but it seems that thedownloadPath setting is lost somewhere.

Also I'm not sure if it is a newer way but I used

driver.browser.execute_cdp("Browser.setDownloadBehavior", { behavior: "allow", downloadPath: download_path }) instead.

It uses execute_cdp_cmd and also I thought that Browser.setDownloadBehavior might be more appropriate than Page.

That being said whether I used the exact code above or my changes the downloadPath setting was lost after the first test.

@dancristianb
Copy link

Was anybody able to get this to work for multiple tests/scenarios?

@ozzyaaron we've hit the same issues here, the downloadPath seems to be lost between tests.
Clearly not ideal but we've worked around the issue by having the session destroyed and rebuilt for each example in the suite.

  after do
    Capybara.current_session.quit
  end

@vivipoit
Copy link

Thank you bbonamin and dancristianb for saving me tons of time as I update an old Rails app's webdrivers gem from 4.2.0 - with the tap syntax - to 5.3.1 - with this one! 🥳👏👏👏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment