mirror of https://github.com/rails/rails
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:
parent
fd3a7a2dd2
commit
7f9ce6f62b
1
Gemfile
1
Gemfile
|
@ -196,3 +196,4 @@ gem "wdm", ">= 0.1.0", platforms: [:windows]
|
||||||
if RUBY_VERSION < "3.2"
|
if RUBY_VERSION < "3.2"
|
||||||
gem "error_highlight", ">= 0.4.0", platforms: [:ruby]
|
gem "error_highlight", ">= 0.4.0", platforms: [:ruby]
|
||||||
end
|
end
|
||||||
|
gem "launchy"
|
||||||
|
|
|
@ -305,6 +305,8 @@ GEM
|
||||||
kramdown-parser-gfm (1.1.0)
|
kramdown-parser-gfm (1.1.0)
|
||||||
kramdown (~> 2.0)
|
kramdown (~> 2.0)
|
||||||
language_server-protocol (3.17.0.3)
|
language_server-protocol (3.17.0.3)
|
||||||
|
launchy (2.5.2)
|
||||||
|
addressable (~> 2.8)
|
||||||
libxml-ruby (5.0.3)
|
libxml-ruby (5.0.3)
|
||||||
listen (3.8.0)
|
listen (3.8.0)
|
||||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
|
@ -613,6 +615,7 @@ DEPENDENCIES
|
||||||
jbuilder
|
jbuilder
|
||||||
jsbundling-rails
|
jsbundling-rails
|
||||||
json (>= 2.0.0, != 2.7.0)
|
json (>= 2.0.0, != 2.7.0)
|
||||||
|
launchy
|
||||||
libxml-ruby
|
libxml-ruby
|
||||||
listen (~> 3.3)
|
listen (~> 3.3)
|
||||||
mdl (!= 0.13.0)
|
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.
|
* Fix a regression in 7.1.3 passing a `to:` option without a controller when the controller is already defined by a scope.
|
||||||
|
|
||||||
```ruby
|
```ruby
|
||||||
|
|
|
@ -8,6 +8,7 @@ require "rack/test"
|
||||||
require "active_support/test_case"
|
require "active_support/test_case"
|
||||||
|
|
||||||
require "action_dispatch/testing/request_encoder"
|
require "action_dispatch/testing/request_encoder"
|
||||||
|
require "action_dispatch/testing/test_helpers/page_dump_helper"
|
||||||
|
|
||||||
module ActionDispatch
|
module ActionDispatch
|
||||||
module Integration # :nodoc:
|
module Integration # :nodoc:
|
||||||
|
@ -651,6 +652,7 @@ module ActionDispatch
|
||||||
|
|
||||||
include Integration::Runner
|
include Integration::Runner
|
||||||
include ActionController::TemplateAssertions
|
include ActionController::TemplateAssertions
|
||||||
|
include TestHelpers::PageDumpHelper
|
||||||
|
|
||||||
included do
|
included do
|
||||||
include ActionDispatch::Routing::UrlFor
|
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 "abstract_unit"
|
||||||
require "controller/fake_controllers"
|
require "controller/fake_controllers"
|
||||||
require "rails/engine"
|
require "rails/engine"
|
||||||
|
require "launchy"
|
||||||
|
|
||||||
class SessionTest < ActiveSupport::TestCase
|
class SessionTest < ActiveSupport::TestCase
|
||||||
StubApp = lambda { |env|
|
StubApp = lambda { |env|
|
||||||
|
@ -1307,3 +1308,87 @@ class IntegrationFileUploadTest < ActionDispatch::IntegrationTest
|
||||||
assert_equal "45142", @response.body
|
assert_equal "45142", @response.body
|
||||||
end
|
end
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue