Dynamically setting default_url_options
in Capybara
If you’re developing a full-stack Rails app with a link-based hypermedia API then you may find incorrect URLs breaking your system/feature Capybara specs. What’s going on?
When running your tests Capybara lazily boots the Rails app on a random port and, because this host/port are unknown to Rails, links generated in serializers (and emails) will point to the wrong URL — and following them within your test app and Capybara will fail. Just like dynamically setting Rails default_url_options
in Heroku review apps you must tell Rails the host/port on which to build these URLs.
To do this with RSpec you can use RSpec.shared_context
to update default_url_options
before the example runs and reset it after. Add a support file in spec/support/default_url_options.rb
with the following:
original_host = Rails.application.routes.default_url_options[:host]
original_port = Rails.application.routes.default_url_options[:port]
RSpec.shared_context 'default_url_options' do
before do
Rails.application.routes.default_url_options[:host] = Capybara.current_session.server.host
Rails.application.routes.default_url_options[:port] = Capybara.current_session.server.port
end
after do
Rails.application.routes.default_url_options[:host] = original_host
Rails.application.routes.default_url_options[:port] = original_port
end
end
(For a reason unknown to me I had to use separate before
/after
blocks instead of an around
block.)
Include it in your browser specs in spec/rails_helper.rb
:
RSpec.configure do |config|
# Traditional feature specs.
config.include_context 'default_url_options', js: true, type: :feature
# New fangled system tests.
config.include_context 'default_url_options', type: :system
end
Now all your _link
s will point to the correct host/port and you can get on with consuming them in your hypermedia link-driven single page app Rails monolith.
Also on medium.com.