Skip to content

Commit

Permalink
Add save_and_open_page helper to IntegrationTest
Browse files Browse the repository at this point in the history
`save_and_open_page` is a capybara helper that lets developers
inspect the status of the page at any given point in their
test. This is helpful when trying to keep a short feedback loop while
working on a test.

This change adds a similar helper with matching signature to
integration tests.
  • Loading branch information
JoeDupuis committed Mar 8, 2024
1 parent 83702d6 commit 610b286
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 0 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -196,3 +196,4 @@ gem "wdm", ">= 0.1.0", platforms: [:windows]
if RUBY_VERSION < "3.2"
gem "error_highlight", ">= 0.4.0", platforms: [:ruby]
end
gem "launchy"
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ GEM
kramdown-parser-gfm (1.1.0)
kramdown (~> 2.0)
language_server-protocol (3.17.0.3)
launchy (2.5.2)
addressable (~> 2.8)
libxml-ruby (5.0.0)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
Expand Down Expand Up @@ -613,6 +615,7 @@ DEPENDENCIES
jbuilder
jsbundling-rails
json (>= 2.0.0, != 2.7.0)
launchy
libxml-ruby
listen (~> 3.3)
mdl (!= 0.13.0)
Expand Down
6 changes: 6 additions & 0 deletions actionpack/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@

*DHH*

* Add `save_and_open_page` helper to IntegrationTest
`save_and_open_page` is a helpful helper to keep a short feedback loop when working on system tests.
A similar helper with matching signature has been added to integration tests.

*Joé Dupuis*

* Add `allow_browser` to set minimum browser versions for the application.

A browser that's blocked will by default be served the file in `public/426.html` with a HTTP status code of "426 Upgrade Required".
Expand Down
2 changes: 2 additions & 0 deletions actionpack/lib/action_dispatch/testing/integration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
require "active_support/test_case"

require "action_dispatch/testing/request_encoder"
require "action_dispatch/testing/test_helpers/page_dump_helper"

module ActionDispatch
module Integration # :nodoc:
Expand Down Expand Up @@ -651,6 +652,7 @@ module Behavior

include Integration::Runner
include ActionController::TemplateAssertions
include TestHelpers::PageDumpHelper

included do
include ActionDispatch::Routing::UrlFor
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

module ActionDispatch
module TestHelpers
module PageDumpHelper
class InvalidResponse < StandardError; end

# Saves the content of response body to a file and tries to open it in your browser.
# Launchy must be present in your Gemfile for the page to open automatically.
def save_and_open_page(path = html_dump_defaul_path)
save_page(path).tap { |s_path| open_file(s_path) }
end

private
def save_page(path = html_dump_defaul_path)
raise InvalidResponse.new("Response is a redirection!") if response.redirection?
path = Pathname.new(path)
path.dirname.mkpath
File.write(path, response.body)
path
end

def open_file(path)
require "launchy"
Launchy.open(path)
rescue LoadError
warn "File saved to #{path}.\nPlease install the launchy gem to open the file automatically."
end

def html_dump_defaul_path
Rails.root.join("tmp/html_dump", "#{method_name}_#{DateTime.current.to_i}.html").to_s
end
end
end
end
86 changes: 86 additions & 0 deletions actionpack/test/controller/integration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require "abstract_unit"
require "controller/fake_controllers"
require "rails/engine"
require "launchy"

class SessionTest < ActiveSupport::TestCase
StubApp = lambda { |env|
Expand Down Expand Up @@ -1307,3 +1308,88 @@ def test_fixture_file_upload
assert_equal "45142", @response.body
end
end

class PageDumpIntegrationTest < ActionDispatch::IntegrationTest
require "debug"
class FooController < ActionController::Base
def index
render plain: "Hello world"
end

def redirect
redirect_to action: :index
end
end

def with_root(&block)
Rails.stub(:root, Pathname.getwd.join("test"), &block)
end

def setup
with_root do
remove_dumps
end
end

def teardown
with_root do
remove_dumps
end
end

def self.routes
@routes ||= ActionDispatch::Routing::RouteSet.new
end

def self.call(env)
routes.call(env)
end

def app
self.class
end

def dump_path
Pathname.new(Dir["#{Rails.root}/tmp/html_dump/#{method_name}*"].sole)
end

def remove_dumps
Dir["#{Rails.root}/tmp/html_dump/#{method_name}*"].each(&File.method(:delete))
end

routes.draw do
get "/" => "page_dump_integration_test/foo#index"
get "/redirect" => "page_dump_integration_test/foo#redirect"
end

test "save_and_open_page saves a copy of the page and call to Launchy" do
launchy_called = false
get "/"
with_root do
Launchy.stub(:open, ->(path) { launchy_called = (path == dump_path) }) do
save_and_open_page
end
assert launchy_called
assert_equal File.read(dump_path), response.body
end
end

test "prints a warning to install launchy if it can't be loaded" do
get "/"
with_root do
Launchy.stub(:open, ->(path) { raise LoadError.new }) do
self.stub(:warn, ->(warning) { warning.include?("Please install the launchy gem to open the file automatically.") }) do
save_and_open_page
end
end
assert_equal File.read(dump_path), response.body
end
end

test "raises when called after a redirect" do
with_root do
get "/redirect"
assert_raise(InvalidResponse) { save_and_open_page }
end
end
end

0 comments on commit 610b286

Please sign in to comment.