Add save_and_open_page helper to IntegrationTest

`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.
This commit is contained in:
Joé Dupuis 2023-09-13 12:21:19 -07:00 committed by Rafael Mendonça França
parent fd3a7a2dd2
commit 7f9ce6f62b
No known key found for this signature in database
GPG Key ID: FC23B6D0F1EEE948
6 changed files with 132 additions and 0 deletions

@ -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"

@ -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.3)
listen (3.8.0)
rb-fsevent (~> 0.10, >= 0.10.3)
@ -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)

@ -1,3 +1,9 @@
* 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*
* Fix a regression in 7.1.3 passing a `to:` option without a controller when the controller is already defined by a scope.
```ruby

@ -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:
@ -651,6 +652,7 @@ module Behavior
include Integration::Runner
include ActionController::TemplateAssertions
include TestHelpers::PageDumpHelper
included do
include ActionDispatch::Routing::UrlFor

@ -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

@ -3,6 +3,7 @@
require "abstract_unit"
require "controller/fake_controllers"
require "rails/engine"
require "launchy"
class SessionTest < ActiveSupport::TestCase
StubApp = lambda { |env|
@ -1307,3 +1308,87 @@ def test_fixture_file_upload
assert_equal "45142", @response.body
end
end
class PageDumpIntegrationTest < ActionDispatch::IntegrationTest
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