Working with Rails 8 System Tests: Handling Mobile and Web Views
Edu Depetris
- Dec 06, 2024- Testing
- System Tests
- Mobile Testing
- Ruby On Rails
Working with Rails system tests (using Capybara under the hood), I bumped into an issue while writing tests for both mobile views and web.
My tests pass when I execute them individually or when I only run the mobile versions, but they started to fail (flaky 😞) when I run all the system tests together. In other words, when I run multiple screen sizes, they fail in a flaky manner.
My first approach was quite simple and I took it from the Rails testing guide The only change I made was the browser; I'm using
My tests pass when I execute them individually or when I only run the mobile versions, but they started to fail (flaky 😞) when I run all the system tests together. In other words, when I run multiple screen sizes, they fail in a flaky manner.
My first approach was quite simple and I took it from the Rails testing guide The only change I made was the browser; I'm using
headless_chrome
instead of chrome (as the Rails example)require "test_helper"
class MobileSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :headless_chrome, screen_size: [375, 667]
end
require "mobile_system_test_case"
class PostsTest < MobileSystemTestCase
test "visiting the index" do
visit posts_url
assert_selector "h1", text: "Posts"
end
end
After debugging a bit, I noticed that when a mobile test runs interchanged with web tests, the screen_size does not respect the specification
screen_size: [375, 667]
I decided to read more about this and dove into the Rails guide for ActionDispatch::SystemTestCase. Here, I found an interesting behavior for headless_chrome:
Let's read it together:
driven_by
has a required argument for the driver name. The keyword arguments are:using
for the browser and:screen_size
to change the size of the browser screen. These two options are not applicable for headless drivers and will be silently ignored if passed.
Headless browsers such as headless Chrome and headless Firefox are also supported. You can use these browsers by setting the:using
argument to:headless_chrome
or:headless_firefox
.
The documentation mentions headless drivers, and since I’m using a headless browser, I wasn’t aware of the difference between these. This motived me to search for another
solution to set the screen sizes.
Minitest provides two handy callbacks: setup (before every test) and teardown (after every test).
require "test_helper"
class MobileSystemTestCase < ActionDispatch::SystemTestCase
driven_by :selenium, using: :headless_chrome, screen_size: [375, 667]
setup do
# force the mobile window size before each test
current_window.resize_to(375, 667)
end
teardown do
# go back to the default window size to avoid side effects
current_window.resize_to(1400, 1400)
end
end
The idea is to set the mobile screen size before the test and return to the default size after the test to prevent side effects on other tests.
Results:
After a couple of run locally and on the CI it seems to work 🎉
Happy Coding.