capybara css design labs rails ruby

Capybara’s save_page with CSS

At Pivotal, we often use Capybara to write a suite of integration tests that navigate a browser through any scenario that can emerge in the application. We use these tests to guard against regressions and to drive out the design of the application in a red-green cycle throughout the day.

When it comes to styling the HTML/CSS/JS of the application, it’s common to switch to development mode and manually simulate a scenario so the page of interest can be refreshed in a tight cycle to observe the changes. This can be a rather manual process if the page is only served in response to a complex user flow or an exception case.

If you use capybara and run save_page, it will save a copy of the page it’s currently on and return the file path of the page. If you open that file, however, stylesheets are unavailable because it’s a save file and asset links are relative.
menu

The workaround

Create a controller along the lines of `FilePreviewsController` and use Mac’s open command to save and open the page.

#app/controllers/file_previews_controller.rb
class FilePreviewsController < ApplicationController
  def show
    render text: IO.read(params[:file])
  end
end

#spec/spec_helper.rb or spec/support/feature_helpers.rb
def save_and_open_preview
  `open #{file_preview_url(host: 'localhost:3000', file: save_page)}`
end

#config/routes.rb
if Rails.env.test? || Rails.env.development?
  resource :file_preview, only: [:show]
end

That’s it! You can now create complex flows in your feature specs, add save_and_open_preview, and use the browser to iterate on page’s look and feel.

with-css

 

Here are my top 3 use-cases for using capybara to style your page.

  • Getting to rare pages or particular datasets. This includes error pages, email-triggered flows like password-reset, or pages guarded by complex permissions.
  • Simulating large amount of content: wonder how to style a gallery with 20 items without manually creating all the items or running a one-off command.
  • Outputting views of the application for conversation with PM or designers. Just sprinkle as many of the above helper calls through a user flow and you have a deck to demonstrate a working feature.