From 1a0ca84a064b07ecab798793a3d7ebe89bb6367c Mon Sep 17 00:00:00 2001 From: eileencodes Date: Sun, 19 Feb 2017 11:50:42 -0500 Subject: Move and rename system tests * Move system tests back into Action Pack * Rename `ActionSystemTest` to `ActionDispatch::SystemTestCase` * Remove private base module and only make file for public `SystemTestCase` class, name private module `SystemTesting` * Rename `ActionSystemTestCase` to `ApplicationSystemTestCase` * Update corresponding documentation and guides * Delete old `ActionSystemTest` files --- actionpack/lib/action_dispatch.rb | 2 + actionpack/lib/action_dispatch/system_test_case.rb | 129 +++++++++++++++++++++ .../lib/action_dispatch/system_testing/browser.rb | 28 +++++ .../lib/action_dispatch/system_testing/driver.rb | 18 +++ .../lib/action_dispatch/system_testing/server.rb | 23 ++++ .../test_helpers/screenshot_helper.rb | 53 +++++++++ .../test/dispatch/system_testing/browser_test.rb | 10 ++ .../test/dispatch/system_testing/driver_test.rb | 9 ++ .../system_testing/screenshot_helper_test.rb | 10 ++ .../test/dispatch/system_testing/server_test.rb | 10 ++ .../system_testing/system_test_case_test.rb | 21 ++++ 11 files changed, 313 insertions(+) create mode 100644 actionpack/lib/action_dispatch/system_test_case.rb create mode 100644 actionpack/lib/action_dispatch/system_testing/browser.rb create mode 100644 actionpack/lib/action_dispatch/system_testing/driver.rb create mode 100644 actionpack/lib/action_dispatch/system_testing/server.rb create mode 100644 actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb create mode 100644 actionpack/test/dispatch/system_testing/browser_test.rb create mode 100644 actionpack/test/dispatch/system_testing/driver_test.rb create mode 100644 actionpack/test/dispatch/system_testing/screenshot_helper_test.rb create mode 100644 actionpack/test/dispatch/system_testing/server_test.rb create mode 100644 actionpack/test/dispatch/system_testing/system_test_case_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 028177ace2..303790e96d 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -97,6 +97,8 @@ module ActionDispatch autoload :TestResponse autoload :AssertionResponse end + + autoload :SystemTestCase, "action_dispatch/system_test_case" end autoload :Mime, "action_dispatch/http/mime_type" diff --git a/actionpack/lib/action_dispatch/system_test_case.rb b/actionpack/lib/action_dispatch/system_test_case.rb new file mode 100644 index 0000000000..850f101ca8 --- /dev/null +++ b/actionpack/lib/action_dispatch/system_test_case.rb @@ -0,0 +1,129 @@ +require "capybara/dsl" +require "action_controller" +require "action_dispatch/system_testing/driver" +require "action_dispatch/system_testing/server" +require "action_dispatch/system_testing/browser" +require "action_dispatch/system_testing/test_helpers/screenshot_helper" + +module ActionDispatch + class SystemTestCase < IntegrationTest + # = System Testing + # + # System tests let you test real application in the browser. Because system + # tests use a real browser experience you can test all of your JavaScript + # easily from your test suite. + # + # To create a system test in your application, extend your test class + # from ApplicationSystemTestCase. System tests use Capybara as a + # base and allow you to configure the settings through your + # system_test_helper.rb file that is generated with a new + # application or scaffold. + # + # Here is an example system test: + # + # require 'system_test_helper' + # + # class Users::CreateTest < ApplicationSystemTestCase + # test "adding a new user" do + # visit users_path + # click_on 'New User' + # + # fill_in 'Name', with: 'Arya' + # click_on 'Create User' + # + # assert_text 'Arya' + # end + # end + # + # When generating an application or scaffold a +system_test_helper.rb+ will also + # be generated containing the base class for system testing. This is where you + # can change the driver, add Capybara settings, and other configuration for + # your system tests. + # + # require "test_helper" + # + # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + # teardown do + # take_failed_screenshot + # Capybara.reset_sessions! + # end + # end + # + # By default, ActionDispatch::SystemTestCase is driven by the + # Selenium driver, with the Chrome browser, and a browser size of 1400x1400. + # + # Changing the driver configuration options are easy. Let's say you want to use + # and the Firefox browser instead. In your +system_test_helper.rb+ + # file add the following: + # + # require "test_helper" + # + # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + # driven_by :selenium, using: :firefox + # + # teardown do + # take_failed_screenshot + # Capybara.reset_sessions! + # end + # end + # + # +driven_by+ has a required argument for the driver name. The keyword + # arguments are +:using+ for the browser (not applicable for headless drivers), + # and +:screen_size+ to change the size of the screen taking screenshots. + # + # To use a headless driver, like Poltergeist, update your Gemfile to use + # Poltergeist instead of Selenium and then declare the driver name in the + # +system_test_helper.rb+ file. In this case you would leave out the +:using+ + # option because the driver is headless. + # + # require "test_helper" + # require "capybara/poltergeist" + # + # class ApplicationSystemTestCase < ActionDispatch::SystemTestCase + # driven_by :poltergeist + # + # teardown do + # take_failed_screenshot + # Capybara.reset_sessions! + # end + # end + # + # Because ActionDispatch::SystemTestCase is a shim between Capybara + # and Rails, any driver that is supported by Capybara is supported by system + # tests as long as you include the required gems and files. + include Capybara::DSL + include SystemTesting::TestHelpers::ScreenshotHelper + + def self.start_application # :nodoc: + Capybara.app = Rack::Builder.new do + map "/" do + run Rails.application + end + end + end + + # System Test configuration options + # + # The defaults settings are Selenium, using Chrome, with a screen size + # of 1400x1400. + # + # Examples: + # + # driven_by :poltergeist + # + # driven_by :selenium, using: :firefox + # + # driven_by :selenium, screen_size: [800, 800] + def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400]) + SystemTesting::Driver.new(driver).run + SystemTesting::Server.new.run + SystemTesting::Browser.new(using, screen_size).run if selenium?(driver) + end + + def self.selenium?(driver) # :nodoc: + driver == :selenium + end + end + + SystemTestCase.start_application +end diff --git a/actionpack/lib/action_dispatch/system_testing/browser.rb b/actionpack/lib/action_dispatch/system_testing/browser.rb new file mode 100644 index 0000000000..c9a6628516 --- /dev/null +++ b/actionpack/lib/action_dispatch/system_testing/browser.rb @@ -0,0 +1,28 @@ +module ActionDispatch + module SystemTesting + class Browser # :nodoc: + def initialize(name, screen_size) + @name = name + @screen_size = screen_size + end + + def run + register + setup + end + + private + def register + Capybara.register_driver @name do |app| + Capybara::Selenium::Driver.new(app, browser: @name).tap do |driver| + driver.browser.manage.window.size = Selenium::WebDriver::Dimension.new(*@screen_size) + end + end + end + + def setup + Capybara.default_driver = @name.to_sym + end + end + end +end diff --git a/actionpack/lib/action_dispatch/system_testing/driver.rb b/actionpack/lib/action_dispatch/system_testing/driver.rb new file mode 100644 index 0000000000..7c2ad84e19 --- /dev/null +++ b/actionpack/lib/action_dispatch/system_testing/driver.rb @@ -0,0 +1,18 @@ +module ActionDispatch + module SystemTesting + class Driver # :nodoc: + def initialize(name) + @name = name + end + + def run + register + end + + private + def register + Capybara.default_driver = @name + end + end + end +end diff --git a/actionpack/lib/action_dispatch/system_testing/server.rb b/actionpack/lib/action_dispatch/system_testing/server.rb new file mode 100644 index 0000000000..62ba07736b --- /dev/null +++ b/actionpack/lib/action_dispatch/system_testing/server.rb @@ -0,0 +1,23 @@ +require "rack/handler/puma" + +module ActionDispatch + module SystemTesting + class Server # :nodoc: + def run + register + setup + end + + private + def register + Capybara.register_server :rails_puma do |app, port, host| + Rack::Handler::Puma.run(app, Port: port, Threads: "0:1") + end + end + + def setup + Capybara.server = :rails_puma + end + end + end +end diff --git a/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb b/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb new file mode 100644 index 0000000000..1ad64b7f78 --- /dev/null +++ b/actionpack/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb @@ -0,0 +1,53 @@ +module ActionDispatch + module SystemTesting + module TestHelpers + # Screenshot helper for system testing + module ScreenshotHelper + # Takes a screenshot of the current page in the browser. + # + # +take_screenshot+ can be used at any point in your system tests to take + # a screenshot of the current state. This can be useful for debugging or + # automating visual testing. + def take_screenshot + save_image + puts "[Screenshot]: #{image_path}" + puts display_image + end + + # Takes a screenshot of the current page in the browser if the test + # failed. + # + # +take_screenshot+ is included in system_test_helper.rb that is + # generated with the application. To take screenshots when a test fails + # add +take_failed_screenshot+ to the teardown block before clearing + # sessions. + def take_failed_screenshot + take_screenshot unless passed? + end + + private + def image_path + "tmp/screenshots/failures_#{method_name}.png" + end + + def save_image + page.save_screenshot(Rails.root.join(image_path)) + end + + def display_image + if ENV["CAPYBARA_INLINE_SCREENSHOT"] == "artifact" + "\e]1338;url=artifact://#{image_path}\a" + else + name = inline_base64(File.basename(image_path)) + image = inline_base64(File.read(image_path)) + "\e]1337;File=name=#{name};height=400px;inline=1:#{image}\a" + end + end + + def inline_base64(path) + Base64.encode64(path).gsub("\n", "") + end + end + end + end +end diff --git a/actionpack/test/dispatch/system_testing/browser_test.rb b/actionpack/test/dispatch/system_testing/browser_test.rb new file mode 100644 index 0000000000..b0ad309492 --- /dev/null +++ b/actionpack/test/dispatch/system_testing/browser_test.rb @@ -0,0 +1,10 @@ +require "abstract_unit" +require "action_dispatch/system_testing/browser" + +class BrowserTest < ActiveSupport::TestCase + test "initializing the browser" do + browser = ActionDispatch::SystemTesting::Browser.new(:chrome, [ 1400, 1400 ]) + assert_equal :chrome, browser.instance_variable_get(:@name) + assert_equal [ 1400, 1400 ], browser.instance_variable_get(:@screen_size) + end +end diff --git a/actionpack/test/dispatch/system_testing/driver_test.rb b/actionpack/test/dispatch/system_testing/driver_test.rb new file mode 100644 index 0000000000..f0ebdb38db --- /dev/null +++ b/actionpack/test/dispatch/system_testing/driver_test.rb @@ -0,0 +1,9 @@ +require "abstract_unit" +require "action_dispatch/system_testing/driver" + +class DriverTest < ActiveSupport::TestCase + test "initializing the driver" do + driver = ActionDispatch::SystemTesting::Driver.new(:selenium) + assert_equal :selenium, driver.instance_variable_get(:@name) + end +end diff --git a/actionpack/test/dispatch/system_testing/screenshot_helper_test.rb b/actionpack/test/dispatch/system_testing/screenshot_helper_test.rb new file mode 100644 index 0000000000..3da89f4a10 --- /dev/null +++ b/actionpack/test/dispatch/system_testing/screenshot_helper_test.rb @@ -0,0 +1,10 @@ +require "abstract_unit" +require "action_dispatch/system_testing/test_helpers/screenshot_helper" + +class ScreenshotHelperTest < ActiveSupport::TestCase + test "image path is saved in tmp directory" do + new_test = ActionDispatch::SystemTestCase.new("x") + + assert_equal "tmp/screenshots/failures_x.png", new_test.send(:image_path) + end +end diff --git a/actionpack/test/dispatch/system_testing/server_test.rb b/actionpack/test/dispatch/system_testing/server_test.rb new file mode 100644 index 0000000000..66842f4ea9 --- /dev/null +++ b/actionpack/test/dispatch/system_testing/server_test.rb @@ -0,0 +1,10 @@ +require "abstract_unit" +require "capybara/dsl" +require "action_dispatch/system_testing/server" + +class ServerTest < ActiveSupport::TestCase + test "initializing the server port" do + server = ActionDispatch::SystemTesting::Server.new.run + assert_includes Capybara.servers, :rails_puma + end +end diff --git a/actionpack/test/dispatch/system_testing/system_test_case_test.rb b/actionpack/test/dispatch/system_testing/system_test_case_test.rb new file mode 100644 index 0000000000..a384902a14 --- /dev/null +++ b/actionpack/test/dispatch/system_testing/system_test_case_test.rb @@ -0,0 +1,21 @@ +require "abstract_unit" + +class SystemTestCaseTest < ActiveSupport::TestCase + test "driven_by sets Capybara's default driver to poltergeist" do + ActionDispatch::SystemTestCase.driven_by :poltergeist + + assert_equal :poltergeist, Capybara.default_driver + end + + test "driven_by sets Capybara's drivers respectively" do + ActionDispatch::SystemTestCase.driven_by :selenium, using: :chrome + + assert_includes Capybara.drivers, :selenium + assert_includes Capybara.drivers, :chrome + assert_equal :chrome, Capybara.default_driver + end + + test "selenium? returns false if driver is poltergeist" do + assert_not ActionDispatch::SystemTestCase.selenium?(:poltergeist) + end +end -- cgit v1.2.3