Want to run your system tests headless? And why not both ways? Here’s how to extend Rails tasks to run your system tests with the driver of your choice.
Rails 6 came with system tests baked-in, and so if you generate a new Rails app today, you end up with the following setup code:
# test/application_system_test_case.rb
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
end
You’ll need some dependencies for this to work. If you don’t have them, add the following to your Gemfile
:
# Gemfile
...
group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem "capybara", ">= 3.26"
gem "selenium-webdriver", ">= 4.0.0"
gem "webdrivers"
end
A lot of people want to switch the default driver to something else, especially to the headless Chrome for faster tests.
It’s surprisingly easy. You only need to replace the driver’s name in using
parameter:
# test/application_system_test_case.rb
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :headless_chrome, screen_size: [1400, 1400]
end
But by doing this change, you lost the ability to watch your tests visually. So why not have both?
Let’s set the driver based on DRIVER
environment variable:
# test/application_system_test_case.rb
require "test_helper"
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
DRIVER = if ENV["DRIVER"]
ENV["DRIVER"].to_sym
else
:headless_chrome
end
driven_by :selenium, using: DRIVER, screen_size: [1400, 1400]
end
I kept headless Chrome as default as something you want to run in CI.
To run system tests with a different driver, we just set that variable on the command line:
$ DRIVER=chrome rails test:system
Pretty nice, yet we can do more. We can have a fancy new Rake task to do this job for us:
# lib/tasks/test.rake
namespace :test do
namespace :system do
task :with, [:driver] => :environment do |task, args|
ENV["DRIVER"] = args[:driver]
Rake::Task["test:system"].invoke
end
end
end
This task sets the ENV variable for us and then invokes the regular Rails’ test:system
task. Nothing less, nothing more.
By defining the driver
argument, we can now choose the driver nicely on the command line:
$ rails test:system:with[chrome]
$ rails test:system:with[firefox]
$ rails test:system:with[headless_chrome]
If, on the other hand, we want to define exact tasks for particular drivers, we can do this too:
# lib/tasks/test.rake
namespace :test do
namespace :system do
task :chrome => :environment do |task, args|
ENV["DRIVER"] = "chrome"
Rake::Task["test:system"].invoke
end
end
end
Then we can run the test:system:chrome
task for the headfull Chrome:
$ rails test:system:chrome
And that’s it! Develop with headless browsers and admire your work once in a while with a full experience!
Get Test Driving Rails while it's in prerelease.