Rails 7 now accepts "html" and "screenshot" kwargs for system test screenshot helper


Rails offers a robust testing environment making it extremely easy to test all aspects of an application. With system test cases, one can test workflows by simulating user interactions.

Here’s a simple example,

class RocketsTest < ApplicationSystemTestCase
  include Devise::Test::IntegrationHelpers

  setup do
    @user = create(:user)
    @rocket = create(:rocket, user_id: @user.id)

    sign_in @user
  end

  test "should create rocket" do
    visit rockets_url
    click_on "New rocket"

    fill_in "Name", with: @rocket.name
    fill_in "Description", with: @rocket.description
    click_on "Create Rocket"

    assert_text "Rocket was successfully created"
    click_on "Back"
  end
end

This example simulates a user, creates a new rocket and then navigates back to the rockets index page. Now in case a test fails, it’s useful to have a screenshot or HTML dump of the page. This fastens the process of debugging.

Before

Rails provides options to take screenshots of the page at any point during the test. Simply call the take_screenshot method multiple times. In order to also include HTML dumps, use the RAILS_SYSTEM_TESTING_SCREENSHOT_HTML environment variable.

Here’s an example. First let’s add a take_screenshot method to the test.

class RocketsTest < ApplicationSystemTestCase
  include Devise::Test::IntegrationHelpers

  setup do
    @user = create(:user)
    @rocket = create(:rocket, user_id: @user.id)

    sign_in @user
  end

  test "should create rocket" do
    visit rockets_url
    click_on "New rocket"

    take_screenshot
    fill_in "Name", with: @rocket.name
    fill_in "Description", with: @rocket.description
    take_screenshot

    click_on "Create Rocket"

    assert_text "Rocket was successfully created"
    click_on "Back"
  end
end

Now we will get debug data before and after updating the form. Let’s run the test.

  RAILS_SYSTEM_TESTING_SCREENSHOT_HTML=1 rails test test/system/rockets_test.rb  

The screenshots and HTML dumps are stored in the tmp/screenshots directory.

After

However Rails will always take both images and HTML dumps every time the environment variable is used. This quickly becomes a problem when debugging to find HTML only issues.

To mitigate this, Rails now allows the html parameter in the take_screenshot method.

class RocketsTest < ApplicationSystemTestCase
  include Devise::Test::IntegrationHelpers

  setup do
    @user = create(:user)
    @rocket = create(:rocket, user_id: @user.id)

    sign_in @user
  end

  test "should create rocket" do
    visit rockets_url
    click_on "New rocket"

    take_screenshot
    fill_in "Name", with: @rocket.name
    fill_in "Description", with: @rocket.description
    take_screenshot(html: true)

    click_on "Create Rocket"

    assert_text "Rocket was successfully created"
    click_on "Back"
  end
end

We can now run the test without the environment variable. This time only two files will be created, instead of four. One image and one HTML file.

  rails test test/system/rockets_test.rb  

This PR introduces four variations of the take_screenshot method.

  take_screenshot(html: true, screenshot: "inline") # takes a screenshot, shows it in iTerm, and dumps the HTML to a file, and prints paths for both
  take_screenshot(html: true) # dumps the HTML to a file and prints its path
  take_screenshot(screenshot: "artifact") # takes a screenshot, shows it in the terminal 
  and prints its path
  take_screenshot # takes a screenshot, prints its path

Join Our Newsletter