I am hoping someone can point out what I am doing wrong. I wanted to configure RSpec/Capybara to do my system tests such that the default behaviour would be to run headless, but if I set js:true
on the test, then it would run in standard browser mode so I could watch it, and work out why the test is failing.
I originally set javascript_driver
to :selenium_chrome
in my spec/rails_helper.rb
file and js:true
on the failing test. That did not make a browser window appear. I then tried setting default_driver
to :selenium_chrome
as well, but that too failed to generate any effect either.
For completeness sake, here is the full spec/rails_helper.rb
file:
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
# Require any support files.
Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
require 'rspec/rails'
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
# Add additional requires below this line. Rails is not loaded until this point!
require "capybara/rails"
require "capybara/rspec"
require 'action_view/helpers/number_helper'
require 'action_view/record_identifier'
# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
puts e.to_s.strip
exit 1
end
RSpec.configure do |config|
# Reset the database before each test
config.use_transactional_fixtures = true
# setup for factory bot
config.include FactoryBot::Syntax::Methods
config.before(:suite) do
Rails.application.load_seed
end
config.before(:each) do
FactoryBot.rewind_sequences
end
config.include Rails.application.routes.url_helpers
end
# Capybara configuration
# Capybara.register_driver :chrome do |app|
# options = Selenium::WebDriver::Chrome::Options.new
# options.add_argument('--start-maximized')
# Capybara::Selenium::Driver.new(app, browser: :chrome, options: options)
# end
Capybara.default_driver = :selenium_chrome
Capybara.javascript_driver = :selenium_chrome
My RSpec test file looks like this:
require 'rails_helper'
RSpec.describe "Clients", type: :system do
# other tests deleted not relevant to question.
describe "Payee Reference functionality" do
let!(:payee) { FactoryBot.create(:payee) }
it "hides payee reference field when self-paying is selected", js:true do
visit new_client_path
puts Capybara.default_driver # -> selenium_chrome
puts Capybara.javascript_driver # -> selenium_chrome
puts Capybara.current_driver # -> selenium_chrome_headless
# Check that the payee reference field is initially hidden
expect(page).to have_select('client_paid_by_id', selected: 'Self Paying')
expect(page).to have_css('div[data-payee-reference-target="referenceField", display:none]', visible: false)
end
end
end
So I would have expected current_driver to be selenium_chrome
. Interestingly, if I set current_driver
to :selenium_chrome
in the actual test before the visit command, it does use a standard browser. However, this feels like the wrong approach.
You can achieve this by removing
Capybara.default_driver = :selenium_chrome
Capybara.javascript_driver = :selenium_chrome
and add the following to your rails_helper.rb
config.before(:each, type: :system) do |example|
if example.metadata[:js]
driven_by :selenium_chrome
else
driven_by :selenium_chrome_headless
end
end
This will set the driver to :selenium_chrome if js true and :selenium_chrome_headless otherwise.