Sometimes your Rails apps just need to execute JavaScript in a real browser. But you also want to run tests on CI, which typically doesn't have a UI. So you need to configure Google Chrome to run headless, i.e. without popping up a browser window (but still exercising your app as if it were).
Urgh.
Having just worked through this now, here's what worked for us.
Prerequisites
Install chromedriver.
Configure test environment
In your app.json
, add the chromedriver
and google-chrome
buildpacks, as well as the usual ruby
one. Our app.json
ended up looking like this:
{
"environments": {
"test": {
"buildpacks": [
{ "url": "https://github.com/heroku/heroku-buildpack-ruby" },
{ "url": "https://github.com/heroku/heroku-buildpack-chromedriver" },
{ "url": "https://github.com/heroku/heroku-buildpack-google-chrome" }
],
"addons": [
"heroku-postgresql"
],
"scripts": {
"test-setup": "bin/rails assets:precompile",
"test": "bin/rspec"
}
}
}
}
Also, set any environment variables you might need in your test env via the Heroku UI. You can set non-sensitive stuff in app.json if you want, though.
Configure Capybara with a headless driver
# spec/rails_helper.rb
chrome_bin = ENV.fetch('GOOGLE_CHROME_SHIM', nil)
chrome_opts = chrome_bin ? { "chromeOptions" => { "binary" => chrome_bin } } : {}
opts = Selenium::WebDriver::Chrome::Options.new
chrome_args = %w[--headless --no-sandbox --disable-gpu]
chrome_args.each { |arg| opts.add_argument(arg) }
Capybara.register_driver :headless do |app|
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
options: opts,
desired_capabilities: Selenium::WebDriver::Remote::Capabilities.chrome(chrome_opts)
)
end
Capybara.javascript_driver = :headless
...and that's about it.
The bit that we found we had to do that was different from other posts of this nature we found was setting Selenium::WebDriver::Chrome::Options.new
. Without this, everything we tried to tell Chrome to be headless was ignored.
If you're reading this, I hope it helps!
Top comments (0)