Question
Does headless Chrome work with self-signed certificates via the Selenium Webdriver on macOS?
Info
I am attempting to get Rails system tests driven by headless Chrome over SSL.
I have a locally self-signed certificate that I pass the the ruby Puma application server to terminate SSL requests. In order to allow drivers to ignore SSL warnings on the locally signed certificate, I am using the acceptInsecureCerts
flag to configure the driver capabilities.
I'm led to believe by this ticket in Chromium that this flag should be recognized as of Chrome 64+.
I can get tests to succeed with Chrome, Firefox, and headless Firefox. Tests do not pass under headless Chrome. I am using (at the time of this writing) what I believe to be the latest versions of Chrome and its variants.
Though folks in the Chromium ticket appear to be successfully running headless Chrome over locally-signed SSL with the Selenium webdriver, I have not found this to work with the setup described here. If my configuration is correct, then I am unsure if there is a limitation in headless Chrome on macOS, in Selenium webdriver ruby gem, or something else I haven't considered. If anyone has something similar working with Rails on macOS, I'd be interested to learn about your setup.
Source
Here is some code to show how I am configuring and running my RSpec/Capybara tests.
Test setup
# rails_helper.rb
# ... standard rspec rails helper setup omitted ...
Capybara.register_driver(:headless_chrome) do |app|
options = Selenium::WebDriver::Chrome::Options.new(
args: %w[--headless --disable-gpu --no-sandbox --disable-web-security]
)
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
acceptInsecureCerts: true,
)
Capybara::Selenium::Driver.new(
app,
browser: :chrome,
options: options,
desired_capabilities: capabilities
)
end
RSpec.configure do |config|
config.before(:each, type: :system) do
driven_by :headless_firefox
end
end
module SystemTestHelpers
def key_file_path
Rails.root.join("config", "ssl", "ssl-lvh.me.key")
end
def cert_file_path
Rails.root.join("config", "ssl", "ssl-lvh.me.crt")
end
def using_app_host(host)
original_host = Capybara.app_host
Capybara.app_host = host
Capybara.server = :puma, {
Host: "ssl://#{Capybara.server_host}?key=#{key_file_path}&cert=#{cert_file_path}"
}
yield
ensure
Capybara.app_host = original_host
end
end
RSpec.configure do |config|
config.include SystemTestHelpers, type: :system
end
Sample test
# spec/system/welcome_spec.rb
require 'rails_helper'
RSpec.feature "Welcome", :js, type: :system do
scenario "Visit homepage" do
using_app_host('https://subdomain.lvh.me') do
visit "/"
expect(page).to have_content('Welcome')
expect(page).to have_content('Your domain: subdomain.lvh.me')
expect(page).to have_content('Your protocol: https://')
end
end
end
Page content:
<div>
<h2>Welcome!</h2>
<p>Your protocol: <%= request.protocol %></p>
<p>Your domain: <%= request.host %></p>
</div>
If I swap out the driver for headless Firefox, configured as below, the tests will pass.
Capybara.register_driver(:headless_firefox) do |app|
options = Selenium::WebDriver::Firefox::Options.new(args: %w[--headless])
capabilities = Selenium::WebDriver::Remote::Capabilities.firefox(
acceptInsecureCerts: true,
)
Capybara::Selenium::Driver.new(
app,
browser: :firefox,
options: options,
desired_capabilities: capabilities
)
end
The complete source code for an app that reproduces the issue, and includes the code above is located here: https://bitbucket.org/rossta/system-test-demo.
Debug output
Here's a link to some debug output from running the test in either headless Chrome or headless Firefox: https://gist.github.com/rossta/b160204baa87a520e7888c19c8b1ed98.
Note in the output that the session response does not include the 'acceptInsecureCerts' capability for Chrome (test-headless-chrome.log, line 15) while in Firefox we do see the session include the flag (test-headless-firefox.log, line 22).
System
- MacOS 10.13.6
- Rails 5.2.1
- Ruby 2.4.1
capybara
(gem) 3.5.1selenium-webdriver
(gem) 3.14.0chromdriver-helper
(gem) 2.34- Chrome 68.0.3440.106. Have also tried
- Google Chrome 70.0.3524.0 canary
- Chromium 70.0.3525.0
using_app_host
method appears to be incorrect since it resets toserver_host
rather thanapp_host
– Thomas Walpoleusing_app_host
2) Thanks, updated the permissions. 3) Also, thanks for all your hard work on Capybara! – rossta