From 5bf0aa6745db27c45c0778f9f6e9046f9ee9fb94 Mon Sep 17 00:00:00 2001 From: eileencodes Date: Sun, 6 Nov 2016 18:55:15 -0500 Subject: Turn system testing into it's own gem and rename Renames `Rails::SystemTestCase` to `ActionSystemTest` and moves it to a gem under the Rails name. We need to name the class `ActionSystemTestCase` because the gem expects a module but tests themselves expect a class. Adds MIT-LICENSE, CHANGELOG, and README for the future. --- .travis.yml | 2 +- Gemfile.lock | 8 +- actionpack/actionpack.gemspec | 1 - actionpack/lib/system_test_case.rb | 57 ----------- actionpack/lib/system_testing/driver_adapter.rb | 31 ------ actionpack/lib/system_testing/driver_adapters.rb | 46 --------- .../driver_adapters/capybara_driver.rb | 83 ---------------- .../driver_adapters/rails_selenium_driver.rb | 98 ------------------- .../system_testing/driver_adapters/web_server.rb | 45 --------- actionpack/lib/system_testing/railtie.rb | 17 ---- actionpack/lib/system_testing/test_helper.rb | 23 ----- actionpack/lib/system_testing/test_helpers.rb | 9 -- .../lib/system_testing/test_helpers/assertions.rb | 40 -------- .../lib/system_testing/test_helpers/form_helper.rb | 58 ----------- .../test_helpers/screenshot_helper.rb | 47 --------- actionpack/test/abstract_unit.rb | 1 - .../test/system_testing/capybara_driver_test.rb | 39 -------- .../test/system_testing/driver_adapter_test.rb | 13 --- .../system_testing/rails_selenium_driver_test.rb | 58 ----------- .../test/system_testing/screenshot_helper_test.rb | 20 ---- actionsystemtest/CHANGELOG.md | 3 + actionsystemtest/MIT-LICENSE | 20 ++++ actionsystemtest/README.md | 108 +++++++++++++++++++++ actionsystemtest/Rakefile | 32 ++++++ actionsystemtest/actionsystemtest.gemspec | 24 +++++ actionsystemtest/lib/action_system_test.rb | 59 +++++++++++ .../lib/action_system_test/driver_adapter.rb | 31 ++++++ .../lib/action_system_test/driver_adapters.rb | 46 +++++++++ .../driver_adapters/capybara_driver.rb | 83 ++++++++++++++++ .../driver_adapters/rails_selenium_driver.rb | 98 +++++++++++++++++++ .../driver_adapters/web_server.rb | 45 +++++++++ .../lib/action_system_test/gem_version.rb | 15 +++ actionsystemtest/lib/action_system_test/railtie.rb | 17 ++++ .../lib/action_system_test/test_helper.rb | 23 +++++ .../lib/action_system_test/test_helpers.rb | 9 ++ .../action_system_test/test_helpers/assertions.rb | 40 ++++++++ .../action_system_test/test_helpers/form_helper.rb | 58 +++++++++++ .../test_helpers/screenshot_helper.rb | 47 +++++++++ actionsystemtest/lib/action_system_test/version.rb | 8 ++ actionsystemtest/test/abstract_unit.rb | 13 +++ .../test/cases/capybara_driver_test.rb | 39 ++++++++ actionsystemtest/test/cases/driver_adapter_test.rb | 13 +++ .../test/cases/rails_selenium_driver_test.rb | 11 +++ .../test/cases/screenshot_helper_test.rb | 20 ++++ ci/travis.rb | 2 +- railties/lib/rails/all.rb | 2 +- .../rails/app/templates/config/application.rb | 1 - .../rails/plugin/templates/rails/application.rb | 1 - .../test_unit/system/templates/system_test.rb | 2 +- railties/lib/rails/test_help.rb | 4 +- railties/railties.gemspec | 1 + .../test/generators/scaffold_generator_test.rb | 2 +- .../test/generators/system_test_generator_test.rb | 2 +- 53 files changed, 877 insertions(+), 698 deletions(-) delete mode 100644 actionpack/lib/system_test_case.rb delete mode 100644 actionpack/lib/system_testing/driver_adapter.rb delete mode 100644 actionpack/lib/system_testing/driver_adapters.rb delete mode 100644 actionpack/lib/system_testing/driver_adapters/capybara_driver.rb delete mode 100644 actionpack/lib/system_testing/driver_adapters/rails_selenium_driver.rb delete mode 100644 actionpack/lib/system_testing/driver_adapters/web_server.rb delete mode 100644 actionpack/lib/system_testing/railtie.rb delete mode 100644 actionpack/lib/system_testing/test_helper.rb delete mode 100644 actionpack/lib/system_testing/test_helpers.rb delete mode 100644 actionpack/lib/system_testing/test_helpers/assertions.rb delete mode 100644 actionpack/lib/system_testing/test_helpers/form_helper.rb delete mode 100644 actionpack/lib/system_testing/test_helpers/screenshot_helper.rb delete mode 100644 actionpack/test/system_testing/capybara_driver_test.rb delete mode 100644 actionpack/test/system_testing/driver_adapter_test.rb delete mode 100644 actionpack/test/system_testing/rails_selenium_driver_test.rb delete mode 100644 actionpack/test/system_testing/screenshot_helper_test.rb create mode 100644 actionsystemtest/CHANGELOG.md create mode 100644 actionsystemtest/MIT-LICENSE create mode 100644 actionsystemtest/README.md create mode 100644 actionsystemtest/Rakefile create mode 100644 actionsystemtest/actionsystemtest.gemspec create mode 100644 actionsystemtest/lib/action_system_test.rb create mode 100644 actionsystemtest/lib/action_system_test/driver_adapter.rb create mode 100644 actionsystemtest/lib/action_system_test/driver_adapters.rb create mode 100644 actionsystemtest/lib/action_system_test/driver_adapters/capybara_driver.rb create mode 100644 actionsystemtest/lib/action_system_test/driver_adapters/rails_selenium_driver.rb create mode 100644 actionsystemtest/lib/action_system_test/driver_adapters/web_server.rb create mode 100644 actionsystemtest/lib/action_system_test/gem_version.rb create mode 100644 actionsystemtest/lib/action_system_test/railtie.rb create mode 100644 actionsystemtest/lib/action_system_test/test_helper.rb create mode 100644 actionsystemtest/lib/action_system_test/test_helpers.rb create mode 100644 actionsystemtest/lib/action_system_test/test_helpers/assertions.rb create mode 100644 actionsystemtest/lib/action_system_test/test_helpers/form_helper.rb create mode 100644 actionsystemtest/lib/action_system_test/test_helpers/screenshot_helper.rb create mode 100644 actionsystemtest/lib/action_system_test/version.rb create mode 100644 actionsystemtest/test/abstract_unit.rb create mode 100644 actionsystemtest/test/cases/capybara_driver_test.rb create mode 100644 actionsystemtest/test/cases/driver_adapter_test.rb create mode 100644 actionsystemtest/test/cases/rails_selenium_driver_test.rb create mode 100644 actionsystemtest/test/cases/screenshot_helper_test.rb diff --git a/.travis.yml b/.travis.yml index eafa06e44f..8fdef9e2a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,7 +36,7 @@ env: matrix: - "GEM=railties" - "GEM=ap,ac" - - "GEM=am,amo,as,av,aj" + - "GEM=am,amo,as,av,aj,ast" - "GEM=as PRESERVE_TIMEZONES=1" - "GEM=ar:mysql2" - "GEM=ar:sqlite3" diff --git a/Gemfile.lock b/Gemfile.lock index c3db5c67f8..870e23cb73 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -45,11 +45,14 @@ PATH actionpack (5.1.0.alpha) actionview (= 5.1.0.alpha) activesupport (= 5.1.0.alpha) - capybara (~> 2.7.0) rack (~> 2.0) rack-test (~> 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionsystemtest (5.1.0.alpha) + actionpack (= 5.1.0.alpha) + activesupport (= 5.1.0.alpha) + capybara (~> 2.7.0) actionview (5.1.0.alpha) activesupport (= 5.1.0.alpha) builder (~> 3.1) @@ -84,6 +87,7 @@ PATH sprockets-rails (>= 2.0.0) railties (5.1.0.alpha) actionpack (= 5.1.0.alpha) + actionsystemtest (= 5.1.0.alpha) activesupport (= 5.1.0.alpha) method_source rake (>= 0.8.7) @@ -126,7 +130,7 @@ GEM bunny (2.6.2) amq-protocol (>= 2.0.1) byebug (9.0.6) - capybara (2.7.0) + capybara (2.7.1) addressable mime-types (>= 1.16) nokogiri (>= 1.3.3) diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index bb9079dc1c..2c24a54305 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -26,7 +26,6 @@ Gem::Specification.new do |s| s.add_dependency "rails-html-sanitizer", "~> 1.0", ">= 1.0.2" s.add_dependency "rails-dom-testing", "~> 2.0" s.add_dependency "actionview", version - s.add_dependency "capybara", "~> 2.7.0" s.add_development_dependency "activemodel", version end diff --git a/actionpack/lib/system_test_case.rb b/actionpack/lib/system_test_case.rb deleted file mode 100644 index 373cb4f0d0..0000000000 --- a/actionpack/lib/system_test_case.rb +++ /dev/null @@ -1,57 +0,0 @@ -require "system_testing/test_helper" -require "system_testing/driver_adapter" - -module Rails - # System tests are similar to Integration tests in that they incorporate multiple - # controllers and actions, but can be used to simulate a real user experience. - # System tests are also known as Acceptance tests. - # - # To create a System Test in your application extend your test class from - # Rails::SystemTestCase. System tests use Capybara as a base and - # allows you to configure the driver. The default driver is - # RailsSeleniumDriver which provides Capybara with no-setup - # configuration of the Selenium Driver. If you prefer you can use the bare - # Selenium driver and set your own configuration. - # - # A system test looks like the following: - # - # require 'test_helper' - # - # class Users::CreateTest < Rails::SystemTestCase - # def adding_a_new_user - # visit users_path - # click_on 'New User' - # - # fill_in 'Name', with: 'Arya' - # click_on 'Create User' - # - # assert_text 'Arya' - # end - # end - # - # System test driver can be configured in your Rails configuration file for the - # test environment. - # - # config.system_testing.driver = :rails_selenium_driver - # - # You can also specify a driver by initializing a new driver object. This allows - # you to change the default settings for the driver you're setting. - # - # config.system_testing.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( - # browser: :firefox - # ) - # - # A list of supported adapters can be found in DriverAdapters. - # - # If you want to use one of the default drivers provided by Capybara you can - # set the driver in your config to one of those defaults: +:rack_test+, - # +:selenium+, +:webkit+, or +:poltergeist+. These 4 drivers use Capyara's - # driver defaults whereas the RailsSeleniumDriver has pre-set - # configuration for browser, server, port, etc. - class SystemTestCase < ActionDispatch::IntegrationTest - include SystemTesting::TestHelper - include SystemTesting::DriverAdapter - - ActiveSupport.run_load_hooks(:system_testing, self) - end -end diff --git a/actionpack/lib/system_testing/driver_adapter.rb b/actionpack/lib/system_testing/driver_adapter.rb deleted file mode 100644 index ccd702e967..0000000000 --- a/actionpack/lib/system_testing/driver_adapter.rb +++ /dev/null @@ -1,31 +0,0 @@ -require "system_testing/driver_adapters" - -module SystemTesting - # The SystemTesting::DriverAdapter module is used to load the driver - # set in your Rails' test configuration file. - # - # The default driver adapter is the +:rails_selenium_driver+. - module DriverAdapter - extend ActiveSupport::Concern - - module ClassMethods - def default_driver # :nodoc - :rails_selenium_driver - end - - # Returns the current driver that is set. If no driver is set in the - # Rails' configuration file then +:rails_selenium_driver+ will be - # initialized. - def driver - @driver ||= DriverAdapters.lookup(default_driver) - end - - # Specify the adapter and settings for the system test driver set in the - # Rails' configuration file. - def driver=(driver) - @driver = DriverAdapters.lookup(driver) - @driver.call - end - end - end -end diff --git a/actionpack/lib/system_testing/driver_adapters.rb b/actionpack/lib/system_testing/driver_adapters.rb deleted file mode 100644 index d246106717..0000000000 --- a/actionpack/lib/system_testing/driver_adapters.rb +++ /dev/null @@ -1,46 +0,0 @@ -module SystemTesting - # == System Testing Driver Adapters - # - # By default Rails supports Capybara with the Selenium Driver. Rails provides - # configuration setup for using the selenium driver with Capybara. - # Additionally Rails can be used as a layer between Capybara and its other - # supported drivers: +:rack_test+, +:selenium+, +:webkit+, or +:poltergeist+. - # - # *{RackTest}[https://github.com/jnicklas/capybara#racktest] - # *{Selenium}[http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver] - # *{Webkit}[https://github.com/thoughtbot/capybara-webkit] - # *{Poltergeist}[https://github.com/teampoltergeist/poltergeist] - # - # === Driver Features - # - # | | Default Browser | Supports Screenshots? | - # |-----------------|-----------------------|-----------------------| - # | Rails' Selenium | Chrome | Yes | - # | Rack Test | No JS Support | No | - # | Selenium | Firefox | Yes | - # | WebKit | Headless w/ Qt | Yes | - # | Poltergeist | Headless w/ PhantomJS | Yes | - module DriverAdapters - extend ActiveSupport::Autoload - - autoload :CapybaraDriver - autoload :RailsSeleniumDriver - - class << self - # Returns driver for specified name. - # - # SystemTesting::DriverAdapters.lookup(:rails_selenium_driver) - # # => SystemTesting::DriverAdapters::RailsSeleniumDriver - def lookup(driver) - if CapybaraDriver::CAPYBARA_DEFAULTS.include?(driver) - CapybaraDriver.new(name: driver) - elsif driver.is_a?(Symbol) - klass = const_get(driver.to_s.camelize) - klass.new - else - driver - end - end - end - end -end diff --git a/actionpack/lib/system_testing/driver_adapters/capybara_driver.rb b/actionpack/lib/system_testing/driver_adapters/capybara_driver.rb deleted file mode 100644 index 7755b9616a..0000000000 --- a/actionpack/lib/system_testing/driver_adapters/capybara_driver.rb +++ /dev/null @@ -1,83 +0,0 @@ -require "system_testing/driver_adapters/web_server" - -module SystemTesting - module DriverAdapters - # == CapybaraDriver for System Testing - # - # The CapybaraDriver is a shim that sits between Rails and - # Capybara. - # - # The drivers Capybara supports are: +:rack_test+, +:selenium+, +:webkit+, - # and +:poltergeist+. - # - # Rails provides its own defaults for Capybara with the Selenium driver - # through RailsSeleniumDriver, but allows users to use Selenium - # directly. - # - # To set your system tests to use one of Capybara's default drivers, add - # the following to yur Rails' configuration test environment: - # - # config.system_testing.driver = :rack_test - # - # The +:rack_test+ driver is a basic test driver that doesn't support - # JavaScript testing and doesn't require a server. - # - # The +:poltergeist+ and +:webkit+ drivers are headless, but require some - # extra environment setup. Because the default server for Rails is Puma, each - # of the Capybara drivers will default to using Puma. Changing the configuration - # to use Webrick is possible by initalizing a new driver object. - # - # The default settings for the CapybaraDriver are: - # - # # - # - # The settings for the CapybaraDriver can be changed from - # Rails' configuration file. - # - # config.system_testing.driver = SystemTesting::DriverAdapters::CapybaraDriver.new( - # name: :webkit, - # server: :webrick - # ) - class CapybaraDriver - include WebServer - - CAPYBARA_DEFAULTS = [ :rack_test, :selenium, :webkit, :poltergeist ] - - attr_reader :name, :server, :port - - def initialize(name: :rack_test, server: :puma, port: 28100) - @name = name - @server = server - @port = port - end - - def call - registration - setup - end - - def supports_screenshots? - @name != :rack_test - end - - private - def registration - register_server - end - - def setup - set_server - set_port - set_driver - end - - def set_driver - Capybara.default_driver = @name - end - end - end -end diff --git a/actionpack/lib/system_testing/driver_adapters/rails_selenium_driver.rb b/actionpack/lib/system_testing/driver_adapters/rails_selenium_driver.rb deleted file mode 100644 index aa67ba8029..0000000000 --- a/actionpack/lib/system_testing/driver_adapters/rails_selenium_driver.rb +++ /dev/null @@ -1,98 +0,0 @@ -require "system_testing/driver_adapters/web_server" - -module SystemTesting - module DriverAdapters - # == RailsSeleniumDriver for System Testing - # - # The RailsSeleniumDriver uses the Selenium 2.0 webdriver. The - # selenium-webdriver gem is required by this driver. - # - # The RailsSeleniumDriver is useful for real browser testing and - # supports Chrome and Firefox. - # - # By default Rails system testing will use Rails' configuration with Capybara - # and the Selenium driver. To explictly set the RailsSeleniumDriver - # add the following to your Rails' configuration test environment: - # - # config.system_testing.driver = :rails_selenium_driver - # - # Because this driver supports real browser testing it is required that a - # server is configured. - # - # If no server is specified when the driver is initialized, Puma will be used - # by default. The default settings for the RailsSeleniumDriver - # are as follows: - # - # # - # - # The settings for the RailsSeleniumDriver can be changed in the - # Rails configuration file. - # - # config.system_testing.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( - # server: :webrick, - # port: 28100, - # screen_size: [ 800, 800 ] - # ) - # - # The default browser is set to Chrome because the current version of - # Firefox does not work with selenium-webdriver. If you want to use Firefox, - # you will need to use Firefox 45.0esr or 47.0 and ensure - # that selenium-webdriver is version 2.53.4. To change the browser from - # +:chrome+ to +:firefox+, initialize the Selenium driver in your Rails' - # test environment: - # - # config.system_testing.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( - # browser: :firefox - # ) - class RailsSeleniumDriver - include WebServer - - attr_reader :browser, :server, :port, :screen_size - - def initialize(browser: :chrome, server: :puma, port: 28100, screen_size: [ 1400,1400 ]) # :nodoc: - @browser = browser - @server = server - @port = port - @screen_size = screen_size - end - - def call # :nodoc: - registration - setup - end - - def supports_screenshots? - true - end - - private - def registration - register_browser_driver - register_server - end - - def setup - set_server - set_port - set_driver - end - - def register_browser_driver - Capybara.register_driver @browser do |app| - Capybara::Selenium::Driver.new(app, browser: @browser).tap do |driver| - driver.browser.manage.window.size = Selenium::WebDriver::Dimension.new(*@screen_size) - end - end - end - - def set_driver - Capybara.default_driver = @browser.to_sym - end - end - end -end diff --git a/actionpack/lib/system_testing/driver_adapters/web_server.rb b/actionpack/lib/system_testing/driver_adapters/web_server.rb deleted file mode 100644 index 65d719d1ab..0000000000 --- a/actionpack/lib/system_testing/driver_adapters/web_server.rb +++ /dev/null @@ -1,45 +0,0 @@ -begin - require "rack/handler/puma" -rescue LoadError - false -end - -module SystemTesting - module DriverAdapters - module WebServer # :nodoc: - def register_server - Capybara.register_server @server do |app, port, host| - case @server - when :puma - register_puma(app, port) - when :webrick - register_webrick(app, port, host) - else - register_default(app, port) - end - end - end - - private - def register_default(app, port) - Capybara.run_default_server(app, port) - end - - def register_puma(app, port) - Rack::Handler::Puma.run(app, Port: port, Threads: "0:4") - end - - def register_webrick(app, port) - Rack::Handler::WEBrick.run(app, Port: port) - end - - def set_server - Capybara.server = @server - end - - def set_port - Capybara.server_port = @port - end - end - end -end diff --git a/actionpack/lib/system_testing/railtie.rb b/actionpack/lib/system_testing/railtie.rb deleted file mode 100644 index d8af69e5d3..0000000000 --- a/actionpack/lib/system_testing/railtie.rb +++ /dev/null @@ -1,17 +0,0 @@ -require "system_test_case" - -module SystemTesting - # = System Testing Railtie - class Railtie < Rails::Railtie # :nodoc: - config.system_testing = ActiveSupport::OrderedOptions.new - - initializer "system_testing.set_configs" do |app| - options = app.config.system_testing - options.driver ||= Rails::SystemTestCase.default_driver - - ActiveSupport.on_load(:system_testing) do - options.each { |k,v| send("#{k}=", v) } - end - end - end -end diff --git a/actionpack/lib/system_testing/test_helper.rb b/actionpack/lib/system_testing/test_helper.rb deleted file mode 100644 index 8bd49b2f4c..0000000000 --- a/actionpack/lib/system_testing/test_helper.rb +++ /dev/null @@ -1,23 +0,0 @@ -require "capybara/dsl" -require "system_testing/test_helpers" - -module SystemTesting - module TestHelper # :nodoc: - include TestHelpers::Assertions - include TestHelpers::FormHelper - include TestHelpers::ScreenshotHelper - include Capybara::DSL - - Capybara.app = Rack::Builder.new do - map "/" do - run Rails.application - end - end - - def after_teardown - take_screenshot if supported? - Capybara.reset_sessions! - super - end - end -end diff --git a/actionpack/lib/system_testing/test_helpers.rb b/actionpack/lib/system_testing/test_helpers.rb deleted file mode 100644 index 3c528a6953..0000000000 --- a/actionpack/lib/system_testing/test_helpers.rb +++ /dev/null @@ -1,9 +0,0 @@ -module SystemTesting - module TestHelpers - extend ActiveSupport::Autoload - - autoload :Assertions - autoload :FormHelper - autoload :ScreenshotHelper - end -end diff --git a/actionpack/lib/system_testing/test_helpers/assertions.rb b/actionpack/lib/system_testing/test_helpers/assertions.rb deleted file mode 100644 index 6e5b62e3c5..0000000000 --- a/actionpack/lib/system_testing/test_helpers/assertions.rb +++ /dev/null @@ -1,40 +0,0 @@ -module SystemTesting - module TestHelpers - # Assertions for system testing that aren't included by default in Capybara. - # These are assertions that are useful specifically for Rails applications. - module Assertions - # Asserts that all of the provided selectors are present on the given page. - # - # assert_all_of_selectors('p', 'td') - def assert_all_of_selectors(*items) - options = items.extract_options! - type = type_for_selector(items) - - items.each do |item| - assert_selector type, item, options - end - end - - # Asserts that none of the provided selectors are present on the page. - # - # assert_none_of_selectors('ul', 'ol') - def assert_none_of_selectors(*items) - options = items.extract_options! - type = type_for_selector(items) - - items.each do |item| - assert_no_selector type, item, options - end - end - - private - def type_for_selector(*items) - if items.first.is_a?(Symbol) - items.shift - else - Capybara.default_selector - end - end - end - end -end diff --git a/actionpack/lib/system_testing/test_helpers/form_helper.rb b/actionpack/lib/system_testing/test_helpers/form_helper.rb deleted file mode 100644 index 74a1516116..0000000000 --- a/actionpack/lib/system_testing/test_helpers/form_helper.rb +++ /dev/null @@ -1,58 +0,0 @@ -module SystemTesting - module TestHelpers - # Form helpers for system testing that aren't included by default in - # Capybara. - module FormHelper - # Finds all provided fields or text areas and fills in with supplied values. - # - # fill_in_all_fields('Name' => 'Eileen', 'Job Title' => 'Programmer') - def fill_in_all_fields(fields) - fields.each do |name, value| - fill_in name, with: value - end - end - - # Locates a checkbox that is present inside a label and checks it. When - # using styled boxes Selenium may not be able to see the checkbox. This - # form helper looks inside the checkbox and clicks the label instead of - # setting the value of the checkbox. - # - # click_checkbox_label 'Admin' - # - # By default +click_checkbox_label+ looks for checkboxes that are not - # checked by default. To locate an already checked box and uncheck it - # set checked to true: - # - # click_checkbox_label 'Admin', checked: true - def click_checkbox_label(name, checked: false) - field = find_checkbox(name, checked) - label = find_label_wrapper(field) - label.click - end - - # In lieu of locating a button and calling +click_on+, +press_enter+ will - # submit the form via enter. This method will only work for drivers that - # load a browser like Selenium. - # - # test 'Adding a User' do - # fill_in 'Name', with: 'Arya' - # - # press_enter - # - # assert_text 'Arya' - # end - def press_enter - page.driver.browser.action.send_keys(:enter).perform - end - - private - def find_checkbox(name, checked) - find(:field, name, visible: :all, checked: checked) - end - - def find_label_wrapper(field, location: "./ancestor::label") - field.find :xpath, location - end - end - end -end diff --git a/actionpack/lib/system_testing/test_helpers/screenshot_helper.rb b/actionpack/lib/system_testing/test_helpers/screenshot_helper.rb deleted file mode 100644 index eeade229df..0000000000 --- a/actionpack/lib/system_testing/test_helpers/screenshot_helper.rb +++ /dev/null @@ -1,47 +0,0 @@ -module SystemTesting - module TestHelpers - # Screenshot helper for system testing - module ScreenshotHelper - # Takes a screenshot of the current page in the browser if the system - # test driver supports screenshots and the test failed. - # - # Additionally +take_screenshot+ can be used within your tests at points - # you want to take a screenshot if the driver supports screenshots. The - # Rack Test driver does not support screenshots. - # - # You can check of the driver supports screenshots by running - # - # Rails::SystemTestCase.driver.supports_screenshots? - # => true - def take_screenshot - puts "[Screenshot]: #{image_path}" - puts find_image - end - - private - def supported? - Rails::SystemTestCase.driver.supports_screenshots? && !passed? - end - - def image_path - path = "tmp/screenshots/failures_#{method_name}.png" - page.save_screenshot(Rails.root.join(path)) - path - end - - def find_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 diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 3b35af6d3a..459b0d6c54 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -33,7 +33,6 @@ require "action_view/testing/resolvers" require "action_dispatch" require "active_support/dependencies" require "active_model" -require "system_test_case" require "pp" # require 'pp' early to prevent hidden_methods from not picking up the pretty-print methods until too late diff --git a/actionpack/test/system_testing/capybara_driver_test.rb b/actionpack/test/system_testing/capybara_driver_test.rb deleted file mode 100644 index 129fe95f25..0000000000 --- a/actionpack/test/system_testing/capybara_driver_test.rb +++ /dev/null @@ -1,39 +0,0 @@ -require "abstract_unit" - -class CapybaraDriverTest < ActiveSupport::TestCase - def setup - Rails::SystemTestCase.driver = :poltergeist - end - - def test_default_driver_adapter - assert_kind_of SystemTesting::DriverAdapters::CapybaraDriver, Rails::SystemTestCase.driver - end - - def test_default_settings - assert_equal :poltergeist, Rails::SystemTestCase.driver.name - assert_equal :puma, Rails::SystemTestCase.driver.server - assert_equal 28100, Rails::SystemTestCase.driver.port - end - - def test_setting_driver - Rails::SystemTestCase.driver = :webkit - - assert_equal :webkit, Rails::SystemTestCase.driver.name - end - - def test_setting_server - Rails::SystemTestCase.driver = SystemTesting::DriverAdapters::CapybaraDriver.new( - server: :webrick - ) - - assert_equal :webrick, Rails::SystemTestCase.driver.server - end - - def test_setting_port - Rails::SystemTestCase.driver = SystemTesting::DriverAdapters::CapybaraDriver.new( - port: 3000 - ) - - assert_equal 3000, Rails::SystemTestCase.driver.port - end -end diff --git a/actionpack/test/system_testing/driver_adapter_test.rb b/actionpack/test/system_testing/driver_adapter_test.rb deleted file mode 100644 index 035d018adf..0000000000 --- a/actionpack/test/system_testing/driver_adapter_test.rb +++ /dev/null @@ -1,13 +0,0 @@ -require "abstract_unit" - -class DriverAdapterTest < ActiveSupport::TestCase - test "only registered adapters are accepted" do - assert_raises(NameError) do - Rails::SystemTestCase.driver = :whatever - end - - assert_nothing_raised do - Rails::SystemTestCase.driver = :rack_test - end - end -end diff --git a/actionpack/test/system_testing/rails_selenium_driver_test.rb b/actionpack/test/system_testing/rails_selenium_driver_test.rb deleted file mode 100644 index 25fc6ca097..0000000000 --- a/actionpack/test/system_testing/rails_selenium_driver_test.rb +++ /dev/null @@ -1,58 +0,0 @@ -require "abstract_unit" - -class RailsSeleniumDriverTest < ActiveSupport::TestCase - def setup - Rails::SystemTestCase.driver = :rails_selenium_driver - end - - def test_default_driver_adapter - assert_kind_of SystemTesting::DriverAdapters::RailsSeleniumDriver, Rails::SystemTestCase.driver - end - - def test_default_settings - assert_equal :chrome, Rails::SystemTestCase.driver.browser - assert_equal :puma, Rails::SystemTestCase.driver.server - assert_equal 28100, Rails::SystemTestCase.driver.port - assert_equal [1400,1400], Rails::SystemTestCase.driver.screen_size - end - - def test_setting_browser - Rails::SystemTestCase.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( - browser: :firefox - ) - - assert_equal :firefox, Rails::SystemTestCase.driver.browser - end - - def test_setting_server - Rails::SystemTestCase.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( - server: :webrick - ) - - assert_equal :webrick, Rails::SystemTestCase.driver.server - end - - def test_setting_port - Rails::SystemTestCase.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( - port: 3000 - ) - - assert_equal 3000, Rails::SystemTestCase.driver.port - end - - def test_setting_screen_size - Rails::SystemTestCase.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( - screen_size: [ 800, 800 ] - ) - - assert_equal [ 800, 800 ], Rails::SystemTestCase.driver.screen_size - end - - def test_does_not_accept_nonsense_kwargs - assert_raises ArgumentError do - Rails::SystemTestCase.driver = SystemTesting::DriverAdapters::RailsSeleniumDriver.new( - made_up_arg: "x" - ) - end - end -end diff --git a/actionpack/test/system_testing/screenshot_helper_test.rb b/actionpack/test/system_testing/screenshot_helper_test.rb deleted file mode 100644 index 8060c499df..0000000000 --- a/actionpack/test/system_testing/screenshot_helper_test.rb +++ /dev/null @@ -1,20 +0,0 @@ -require "abstract_unit" - -class ScreenshotHelperTest < ActiveSupport::TestCase - def test_driver_support_for_screenshots - Rails::SystemTestCase.driver = :rails_selenium_driver - assert Rails::SystemTestCase.driver.supports_screenshots? - - Rails::SystemTestCase.driver = :rack_test - assert_not Rails::SystemTestCase.driver.supports_screenshots? - - Rails::SystemTestCase.driver = :selenium - assert Rails::SystemTestCase.driver.supports_screenshots? - - Rails::SystemTestCase.driver = :webkit - assert Rails::SystemTestCase.driver.supports_screenshots? - - Rails::SystemTestCase.driver = :poltergeist - assert Rails::SystemTestCase.driver.supports_screenshots? - end -end diff --git a/actionsystemtest/CHANGELOG.md b/actionsystemtest/CHANGELOG.md new file mode 100644 index 0000000000..3c7ea2c273 --- /dev/null +++ b/actionsystemtest/CHANGELOG.md @@ -0,0 +1,3 @@ +* Added to Rails! + + *Eileen M. Uchitelle* diff --git a/actionsystemtest/MIT-LICENSE b/actionsystemtest/MIT-LICENSE new file mode 100644 index 0000000000..7fddc6b222 --- /dev/null +++ b/actionsystemtest/MIT-LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2017 David Heinemeier Hansson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/actionsystemtest/README.md b/actionsystemtest/README.md new file mode 100644 index 0000000000..3710b8dbd4 --- /dev/null +++ b/actionsystemtest/README.md @@ -0,0 +1,108 @@ +# Action System Test + +Action System Test adds Capybara integration to your Rails application for +acceptance testing. This allows you to test the entire user experience +of your application rather than just your controllers, or just your models. + +Action System Test provides all of the setup out of the box for you to use +Capybara with the Selenium Driver in your Rails application. Changing the +default configuration is simple, yet flexible. + +## Examples + +### Usage + +By default Rails provides applications with system testing through Capybara +and defaults to using the Selenium driver. The configuration set by Rails +means that when you generate an application system tests will work out of +the box, without you having to change any of the configuration requirements. + +Action System Test uses all the helpers from Capybara, but abstracts away the +setup required to get running. Below is an example Action System Test. + +```ruby +class UsersTest < ActionSystemTestCase + setup do + visit users_path + end + + test 'creating a new user' do + click_on 'New User' + + fill_in 'Name', with: 'Arya' + + click_on 'Create User' + + assert_text 'Arya' + end +end +``` + +First we visit the +users_path+. From there we are going to use Action System +Test to create a new user. The test will click on the "New User" button. Then +it will fill in the "Name" field with "Arya" and click on the "Create User" +button. Lastly, we assert that the text on the Users show page is what we +expected, which in this case is "Arya". + +For more helpers and how to write Capybara tests visit Capybara's README. + +### Configuration + +When generating a new application Rails will include the Capybara gem, the +Selenium gem, and a system_test_helper.rb file. The +system_test_helper.rb file is where you can change the desired +configuration if Rails doesn't work out of the box for you. + +The system_test_helper.rb file provides a home for all of your Capybara +and Action System Test configuration. + +Rails preset configuration for Capybara with Selenium defaults to Puma for +the web server on port 28100, Chrome for the browser, and a screen size of +1400 x 1400. + +Changing the configuration is as simple as changing the driver in your +system_test_helper.rb + +If you want to change the default settings of the Rails provided Selenium +configuration options you can initialize a new RailsSeleniumDriver +object. + +```ruby +class ActionSystemTestCase < ActionSystemTest::Base + ActionSystemTest.driver = RailsSeleniumDriver.new( + browser: :firefox, + server: :webrick + ) +end +``` + +Capybara itself provides 4 drivers: RackTest, Selenium, Webkit, and Poltergeist. +Action System Test provides a shim between Rails and Capybara for these 4 drivers. +Please note, that Rails is set up to use the Puma server by default for these +4 drivers. Puma is the default in Rails and therefore is set as the default in +the Rails Capybara integration. + +To set your application tests to use any of Capybara's defaults with no configuration, +set the following in your system_test_helper.rb file and follow setup instructions +for environment requirements of these drivers. + +The possible settings are +:rack_test+, +:selenium+, +:webkit+, or +:poltergeist+. + +```ruby +class ActionSystemTestCase < ActionSystemTest::Base + ActionSystemTest.driver = :poltergeist +end +``` + +If you want to change the default server (puma) or port (28100) for Capbyara drivers +you can initialize a new object. + +```ruby +class ActionSystemTestCase < ActionSystemTest::Base + ActionSystemTest.driver = ActionSystemTest::DriverAdapters::CapybaraDriver.new( + name: :poltergeist, + server: :webkit, + port: 3000 + ) +end +``` diff --git a/actionsystemtest/Rakefile b/actionsystemtest/Rakefile new file mode 100644 index 0000000000..8b07e8f4af --- /dev/null +++ b/actionsystemtest/Rakefile @@ -0,0 +1,32 @@ +require "rake/testtask" + +test_files = Dir.glob("test/**/*_test.rb") + +desc "Default Task" +task default: :test + +task :package + +# Run the unit tests +Rake::TestTask.new do |t| + t.libs << "test" + t.test_files = test_files + + t.warning = true + t.verbose = true + t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION) +end + +namespace :test do + task :isolated do + test_files.all? do |file| + sh(Gem.ruby, "-w", "-Ilib:test", file) + end || raise("Failures") + end +end + +task :lines do + load File.expand_path("..", File.dirname(__FILE__)) + "/tools/line_statistics" + files = FileList["lib/**/*.rb"] + CodeTools::LineStatistics.new(files).print_loc +end diff --git a/actionsystemtest/actionsystemtest.gemspec b/actionsystemtest/actionsystemtest.gemspec new file mode 100644 index 0000000000..81293980c4 --- /dev/null +++ b/actionsystemtest/actionsystemtest.gemspec @@ -0,0 +1,24 @@ +version = File.read(File.expand_path("../../RAILS_VERSION", __FILE__)).strip + +Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = "actionsystemtest" + s.version = version + s.summary = "Acceptance test framework for Rails." + s.description = "Test framework for testing web applications by simulating how users interact with your application." + + s.required_ruby_version = ">= 2.2.2" + + s.license = "MIT" + + s.author = ["Eileen Uchitelle", "David Heinemeier Hansson"] + s.email = ["eileencodes@gmail.com", "david@loudthinking.com"] + s.homepage = "http://rubyonrails.org" + + s.files = Dir["CHANGELOG.md", "MIT-LICENSE", "README.md", "lib/**/*"] + s.require_path = "lib" + + s.add_dependency "capybara", "~> 2.7.0" + s.add_dependency "actionpack", version + s.add_dependency "activesupport", version +end diff --git a/actionsystemtest/lib/action_system_test.rb b/actionsystemtest/lib/action_system_test.rb new file mode 100644 index 0000000000..4a80e34695 --- /dev/null +++ b/actionsystemtest/lib/action_system_test.rb @@ -0,0 +1,59 @@ +require "action_system_test/test_helper" +require "action_system_test/driver_adapter" + +# System tests are similar to Integration tests in that they incorporate multiple +# controllers and actions, but can be used to simulate a real user experience. +# System tests are also known as Acceptance tests. +# +# To create a System Test in your application extend your test class from +# ActionSystemTestCase. System tests use Capybara as a base and +# allows you to configure the driver. The default driver is +# RailsSeleniumDriver which provides Capybara with no-setup +# configuration of the Selenium Driver. If you prefer you can use the bare +# Selenium driver and set your own configuration. +# +# A system test looks like the following: +# +# require 'test_helper' +# +# class Users::CreateTest < ActionSystemTestCase +# def adding_a_new_user +# visit users_path +# click_on 'New User' +# +# fill_in 'Name', with: 'Arya' +# click_on 'Create User' +# +# assert_text 'Arya' +# end +# end +# +# System test driver can be configured in your Rails configuration file for the +# test environment. +# +# config.system_testing.driver = :rails_selenium_driver +# +# You can also specify a driver by initializing a new driver object. This allows +# you to change the default settings for the driver you're setting. +# +# config.system_testing.driver = ActionSystemTest::DriverAdapters::RailsSeleniumDriver.new( +# browser: :firefox +# ) +# +# A list of supported adapters can be found in DriverAdapters. +# +# If you want to use one of the default drivers provided by Capybara you can +# set the driver in your config to one of those defaults: +:rack_test+, +# +:selenium+, +:webkit+, or +:poltergeist+. These 4 drivers use Capyara's +# driver defaults whereas the RailsSeleniumDriver has pre-set +# configuration for browser, server, port, etc. +module ActionSystemTest + include ActionSystemTest::TestHelper + include ActionSystemTest::DriverAdapter + + ActiveSupport.run_load_hooks(:system_testing, self) +end + +class ActionSystemTestCase < ActionDispatch::IntegrationTest + include ActionSystemTest +end diff --git a/actionsystemtest/lib/action_system_test/driver_adapter.rb b/actionsystemtest/lib/action_system_test/driver_adapter.rb new file mode 100644 index 0000000000..fe12ecaf80 --- /dev/null +++ b/actionsystemtest/lib/action_system_test/driver_adapter.rb @@ -0,0 +1,31 @@ +require "action_system_test/driver_adapters" + +module ActionSystemTest + # The ActionSystemTest::DriverAdapter module is used to load the driver + # set in your Rails' test configuration file. + # + # The default driver adapter is the +:rails_selenium_driver+. + module DriverAdapter + extend ActiveSupport::Concern + + module ClassMethods + def default_driver # :nodoc + :rails_selenium_driver + end + + # Returns the current driver that is set. If no driver is set in the + # Rails' configuration file then +:rails_selenium_driver+ will be + # initialized. + def driver + @driver ||= DriverAdapters.lookup(default_driver) + end + + # Specify the adapter and settings for the system test driver set in the + # Rails' configuration file. + def driver=(driver) + @driver = DriverAdapters.lookup(driver) + @driver.call + end + end + end +end diff --git a/actionsystemtest/lib/action_system_test/driver_adapters.rb b/actionsystemtest/lib/action_system_test/driver_adapters.rb new file mode 100644 index 0000000000..aead9d6f60 --- /dev/null +++ b/actionsystemtest/lib/action_system_test/driver_adapters.rb @@ -0,0 +1,46 @@ +module ActionSystemTest + # == System Testing Driver Adapters + # + # By default Rails supports Capybara with the Selenium Driver. Rails provides + # configuration setup for using the selenium driver with Capybara. + # Additionally Rails can be used as a layer between Capybara and its other + # supported drivers: +:rack_test+, +:selenium+, +:webkit+, or +:poltergeist+. + # + # *{RackTest}[https://github.com/jnicklas/capybara#racktest] + # *{Selenium}[http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver] + # *{Webkit}[https://github.com/thoughtbot/capybara-webkit] + # *{Poltergeist}[https://github.com/teampoltergeist/poltergeist] + # + # === Driver Features + # + # | | Default Browser | Supports Screenshots? | + # |-----------------|-----------------------|-----------------------| + # | Rails' Selenium | Chrome | Yes | + # | Rack Test | No JS Support | No | + # | Selenium | Firefox | Yes | + # | WebKit | Headless w/ Qt | Yes | + # | Poltergeist | Headless w/ PhantomJS | Yes | + module DriverAdapters + extend ActiveSupport::Autoload + + autoload :CapybaraDriver + autoload :RailsSeleniumDriver + + class << self + # Returns driver for specified name. + # + # ActionSystemTest::DriverAdapters.lookup(:rails_selenium_driver) + # # => ActionSystemTest::DriverAdapters::RailsSeleniumDriver + def lookup(driver) + if CapybaraDriver::CAPYBARA_DEFAULTS.include?(driver) + CapybaraDriver.new(name: driver) + elsif driver.is_a?(Symbol) + klass = const_get(driver.to_s.camelize) + klass.new + else + driver + end + end + end + end +end diff --git a/actionsystemtest/lib/action_system_test/driver_adapters/capybara_driver.rb b/actionsystemtest/lib/action_system_test/driver_adapters/capybara_driver.rb new file mode 100644 index 0000000000..5362f6db25 --- /dev/null +++ b/actionsystemtest/lib/action_system_test/driver_adapters/capybara_driver.rb @@ -0,0 +1,83 @@ +require "action_system_test/driver_adapters/web_server" + +module ActionSystemTest + module DriverAdapters + # == CapybaraDriver for System Testing + # + # The CapybaraDriver is a shim that sits between Rails and + # Capybara. + # + # The drivers Capybara supports are: +:rack_test+, +:selenium+, +:webkit+, + # and +:poltergeist+. + # + # Rails provides its own defaults for Capybara with the Selenium driver + # through RailsSeleniumDriver, but allows users to use Selenium + # directly. + # + # To set your system tests to use one of Capybara's default drivers, add + # the following to yur Rails' configuration test environment: + # + # config.system_testing.driver = :rack_test + # + # The +:rack_test+ driver is a basic test driver that doesn't support + # JavaScript testing and doesn't require a server. + # + # The +:poltergeist+ and +:webkit+ drivers are headless, but require some + # extra environment setup. Because the default server for Rails is Puma, each + # of the Capybara drivers will default to using Puma. Changing the configuration + # to use Webrick is possible by initalizing a new driver object. + # + # The default settings for the CapybaraDriver are: + # + # # + # + # The settings for the CapybaraDriver can be changed from + # Rails' configuration file. + # + # config.system_testing.driver = ActionSystemTest::DriverAdapters::CapybaraDriver.new( + # name: :webkit, + # server: :webrick + # ) + class CapybaraDriver + include WebServer + + CAPYBARA_DEFAULTS = [ :rack_test, :selenium, :webkit, :poltergeist ] + + attr_reader :name, :server, :port + + def initialize(name: :rack_test, server: :puma, port: 28100) + @name = name + @server = server + @port = port + end + + def call + registration + setup + end + + def supports_screenshots? + @name != :rack_test + end + + private + def registration + register_server + end + + def setup + set_server + set_port + set_driver + end + + def set_driver + Capybara.default_driver = @name + end + end + end +end diff --git a/actionsystemtest/lib/action_system_test/driver_adapters/rails_selenium_driver.rb b/actionsystemtest/lib/action_system_test/driver_adapters/rails_selenium_driver.rb new file mode 100644 index 0000000000..16e485398a --- /dev/null +++ b/actionsystemtest/lib/action_system_test/driver_adapters/rails_selenium_driver.rb @@ -0,0 +1,98 @@ +require "action_system_test/driver_adapters/web_server" + +module ActionSystemTest + module DriverAdapters + # == RailsSeleniumDriver for System Testing + # + # The RailsSeleniumDriver uses the Selenium 2.0 webdriver. The + # selenium-webdriver gem is required by this driver. + # + # The RailsSeleniumDriver is useful for real browser testing and + # supports Chrome and Firefox. + # + # By default Rails system testing will use Rails' configuration with Capybara + # and the Selenium driver. To explictly set the RailsSeleniumDriver + # add the following to your Rails' configuration test environment: + # + # config.system_testing.driver = :rails_selenium_driver + # + # Because this driver supports real browser testing it is required that a + # server is configured. + # + # If no server is specified when the driver is initialized, Puma will be used + # by default. The default settings for the RailsSeleniumDriver + # are as follows: + # + # # + # + # The settings for the RailsSeleniumDriver can be changed in the + # Rails configuration file. + # + # config.system_testing.driver = ActionSystemTest::DriverAdapters::RailsSeleniumDriver.new( + # server: :webrick, + # port: 28100, + # screen_size: [ 800, 800 ] + # ) + # + # The default browser is set to Chrome because the current version of + # Firefox does not work with selenium-webdriver. If you want to use Firefox, + # you will need to use Firefox 45.0esr or 47.0 and ensure + # that selenium-webdriver is version 2.53.4. To change the browser from + # +:chrome+ to +:firefox+, initialize the Selenium driver in your Rails' + # test environment: + # + # config.system_testing.driver = ActionSystemTest::DriverAdapters::RailsSeleniumDriver.new( + # browser: :firefox + # ) + class RailsSeleniumDriver + include WebServer + + attr_reader :browser, :server, :port, :screen_size + + def initialize(browser: :chrome, server: :puma, port: 28100, screen_size: [ 1400, 1400 ]) # :nodoc: + @browser = browser + @server = server + @port = port + @screen_size = screen_size + end + + def call # :nodoc: + registration + setup + end + + def supports_screenshots? + true + end + + private + def registration + register_browser_driver + register_server + end + + def setup + set_server + set_port + set_driver + end + + def register_browser_driver + Capybara.register_driver @browser do |app| + Capybara::Selenium::Driver.new(app, browser: @browser).tap do |driver| + driver.browser.manage.window.size = Selenium::WebDriver::Dimension.new(*@screen_size) + end + end + end + + def set_driver + Capybara.default_driver = @browser.to_sym + end + end + end +end diff --git a/actionsystemtest/lib/action_system_test/driver_adapters/web_server.rb b/actionsystemtest/lib/action_system_test/driver_adapters/web_server.rb new file mode 100644 index 0000000000..e115fe583c --- /dev/null +++ b/actionsystemtest/lib/action_system_test/driver_adapters/web_server.rb @@ -0,0 +1,45 @@ +begin + require "rack/handler/puma" +rescue LoadError + false +end + +module ActionSystemTest + module DriverAdapters + module WebServer # :nodoc: + def register_server + Capybara.register_server @server do |app, port, host| + case @server + when :puma + register_puma(app, port) + when :webrick + register_webrick(app, port) + else + register_default(app, port) + end + end + end + + private + def register_default(app, port) + Capybara.run_default_server(app, port) + end + + def register_puma(app, port) + Rack::Handler::Puma.run(app, Port: port, Threads: "0:4") + end + + def register_webrick(app, port) + Rack::Handler::WEBrick.run(app, Port: port) + end + + def set_server + Capybara.server = @server + end + + def set_port + Capybara.server_port = @port + end + end + end +end diff --git a/actionsystemtest/lib/action_system_test/gem_version.rb b/actionsystemtest/lib/action_system_test/gem_version.rb new file mode 100644 index 0000000000..c10fce2da0 --- /dev/null +++ b/actionsystemtest/lib/action_system_test/gem_version.rb @@ -0,0 +1,15 @@ +module ActionSystemTest + # Returns the version of the currently loaded Action System Test as a Gem::Version. + def self.gem_version + Gem::Version.new VERSION::STRING + end + + module VERSION + MAJOR = 5 + MINOR = 1 + TINY = 0 + PRE = "alpha" + + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") + end +end diff --git a/actionsystemtest/lib/action_system_test/railtie.rb b/actionsystemtest/lib/action_system_test/railtie.rb new file mode 100644 index 0000000000..6f4fe1b993 --- /dev/null +++ b/actionsystemtest/lib/action_system_test/railtie.rb @@ -0,0 +1,17 @@ +require "action_system_test" + +module ActionSystemTest + # = System Testing Railtie + class Railtie < Rails::Railtie # :nodoc: + config.system_testing = ActiveSupport::OrderedOptions.new + + initializer "system_testing.set_configs" do |app| + options = app.config.system_testing + options.driver ||= ActionSystemTest.default_driver + + ActiveSupport.on_load(:system_testing) do + options.each { |k,v| send("#{k}=", v) } + end + end + end +end diff --git a/actionsystemtest/lib/action_system_test/test_helper.rb b/actionsystemtest/lib/action_system_test/test_helper.rb new file mode 100644 index 0000000000..428f0faeca --- /dev/null +++ b/actionsystemtest/lib/action_system_test/test_helper.rb @@ -0,0 +1,23 @@ +require "capybara/dsl" +require "action_system_test/test_helpers" + +module ActionSystemTest + module TestHelper # :nodoc: + include TestHelpers::Assertions + include TestHelpers::FormHelper + include TestHelpers::ScreenshotHelper + include Capybara::DSL + + Capybara.app = Rack::Builder.new do + map "/" do + run Rails.application + end + end + + def after_teardown + take_screenshot if supported? + Capybara.reset_sessions! + super + end + end +end diff --git a/actionsystemtest/lib/action_system_test/test_helpers.rb b/actionsystemtest/lib/action_system_test/test_helpers.rb new file mode 100644 index 0000000000..10ddeff92f --- /dev/null +++ b/actionsystemtest/lib/action_system_test/test_helpers.rb @@ -0,0 +1,9 @@ +module ActionSystemTest + module TestHelpers + extend ActiveSupport::Autoload + + autoload :Assertions + autoload :FormHelper + autoload :ScreenshotHelper + end +end diff --git a/actionsystemtest/lib/action_system_test/test_helpers/assertions.rb b/actionsystemtest/lib/action_system_test/test_helpers/assertions.rb new file mode 100644 index 0000000000..edc8dbaa7f --- /dev/null +++ b/actionsystemtest/lib/action_system_test/test_helpers/assertions.rb @@ -0,0 +1,40 @@ +module ActionSystemTest + module TestHelpers + # Assertions for system testing that aren't included by default in Capybara. + # These are assertions that are useful specifically for Rails applications. + module Assertions + # Asserts that all of the provided selectors are present on the given page. + # + # assert_all_of_selectors('p', 'td') + def assert_all_of_selectors(*items) + options = items.extract_options! + type = type_for_selector(items) + + items.each do |item| + assert_selector type, item, options + end + end + + # Asserts that none of the provided selectors are present on the page. + # + # assert_none_of_selectors('ul', 'ol') + def assert_none_of_selectors(*items) + options = items.extract_options! + type = type_for_selector(items) + + items.each do |item| + assert_no_selector type, item, options + end + end + + private + def type_for_selector(*items) + if items.first.is_a?(Symbol) + items.shift + else + Capybara.default_selector + end + end + end + end +end diff --git a/actionsystemtest/lib/action_system_test/test_helpers/form_helper.rb b/actionsystemtest/lib/action_system_test/test_helpers/form_helper.rb new file mode 100644 index 0000000000..3c65c23f6d --- /dev/null +++ b/actionsystemtest/lib/action_system_test/test_helpers/form_helper.rb @@ -0,0 +1,58 @@ +module ActionSystemTest + module TestHelpers + # Form helpers for system testing that aren't included by default in + # Capybara. + module FormHelper + # Finds all provided fields or text areas and fills in with supplied values. + # + # fill_in_all_fields('Name' => 'Eileen', 'Job Title' => 'Programmer') + def fill_in_all_fields(fields) + fields.each do |name, value| + fill_in name, with: value + end + end + + # Locates a checkbox that is present inside a label and checks it. When + # using styled boxes Selenium may not be able to see the checkbox. This + # form helper looks inside the checkbox and clicks the label instead of + # setting the value of the checkbox. + # + # click_checkbox_label 'Admin' + # + # By default +click_checkbox_label+ looks for checkboxes that are not + # checked by default. To locate an already checked box and uncheck it + # set checked to true: + # + # click_checkbox_label 'Admin', checked: true + def click_checkbox_label(name, checked: false) + field = find_checkbox(name, checked) + label = find_label_wrapper(field) + label.click + end + + # In lieu of locating a button and calling +click_on+, +press_enter+ will + # submit the form via enter. This method will only work for drivers that + # load a browser like Selenium. + # + # test 'Adding a User' do + # fill_in 'Name', with: 'Arya' + # + # press_enter + # + # assert_text 'Arya' + # end + def press_enter + page.driver.browser.action.send_keys(:enter).perform + end + + private + def find_checkbox(name, checked) + find(:field, name, visible: :all, checked: checked) + end + + def find_label_wrapper(field, location: "./ancestor::label") + field.find :xpath, location + end + end + end +end diff --git a/actionsystemtest/lib/action_system_test/test_helpers/screenshot_helper.rb b/actionsystemtest/lib/action_system_test/test_helpers/screenshot_helper.rb new file mode 100644 index 0000000000..37336e976f --- /dev/null +++ b/actionsystemtest/lib/action_system_test/test_helpers/screenshot_helper.rb @@ -0,0 +1,47 @@ +module ActionSystemTest + module TestHelpers + # Screenshot helper for system testing + module ScreenshotHelper + # Takes a screenshot of the current page in the browser if the system + # test driver supports screenshots and the test failed. + # + # Additionally +take_screenshot+ can be used within your tests at points + # you want to take a screenshot if the driver supports screenshots. The + # Rack Test driver does not support screenshots. + # + # You can check of the driver supports screenshots by running + # + # ActionSystemTest.driver.supports_screenshots? + # => true + def take_screenshot + puts "[Screenshot]: #{image_path}" + puts find_image + end + + private + def supported? + ActionSystemTest.driver.supports_screenshots? && !passed? + end + + def image_path + path = "tmp/screenshots/failures_#{method_name}.png" + page.save_screenshot(Rails.root.join(path)) + path + end + + def find_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 diff --git a/actionsystemtest/lib/action_system_test/version.rb b/actionsystemtest/lib/action_system_test/version.rb new file mode 100644 index 0000000000..a0fda7d9da --- /dev/null +++ b/actionsystemtest/lib/action_system_test/version.rb @@ -0,0 +1,8 @@ +require_relative "gem_version" + +module ActionSystemTest + # Returns the version of the currently loaded Action System Test as a Gem::Version + def self.version + gem_version + end +end diff --git a/actionsystemtest/test/abstract_unit.rb b/actionsystemtest/test/abstract_unit.rb new file mode 100644 index 0000000000..26da9c7ccb --- /dev/null +++ b/actionsystemtest/test/abstract_unit.rb @@ -0,0 +1,13 @@ +require "active_support/testing/autorun" +require "action_controller" +require "action_dispatch" +require "action_system_test" + +# Skips the current run on Rubinius using Minitest::Assertions#skip +def rubinius_skip(message = "") + skip message if RUBY_ENGINE == "rbx" +end +# Skips the current run on JRuby using Minitest::Assertions#skip +def jruby_skip(message = "") + skip message if defined?(JRUBY_VERSION) +end diff --git a/actionsystemtest/test/cases/capybara_driver_test.rb b/actionsystemtest/test/cases/capybara_driver_test.rb new file mode 100644 index 0000000000..33337ad18b --- /dev/null +++ b/actionsystemtest/test/cases/capybara_driver_test.rb @@ -0,0 +1,39 @@ +require "abstract_unit" + +class CapybaraDriverTest < ActiveSupport::TestCase + def setup + ActionSystemTest.driver = :poltergeist + end + + def test_default_driver_adapter + assert_kind_of ActionSystemTest::DriverAdapters::CapybaraDriver, ActionSystemTest.driver + end + + def test_default_settings + assert_equal :poltergeist, ActionSystemTest.driver.name + assert_equal :puma, ActionSystemTest.driver.server + assert_equal 28100, ActionSystemTest.driver.port + end + + def test_setting_driver + ActionSystemTest.driver = :webkit + + assert_equal :webkit, ActionSystemTest.driver.name + end + + def test_setting_server + ActionSystemTest.driver = ActionSystemTest::DriverAdapters::CapybaraDriver.new( + server: :webrick + ) + + assert_equal :webrick, ActionSystemTest.driver.server + end + + def test_setting_port + ActionSystemTest.driver = ActionSystemTest::DriverAdapters::CapybaraDriver.new( + port: 3000 + ) + + assert_equal 3000, ActionSystemTest.driver.port + end +end diff --git a/actionsystemtest/test/cases/driver_adapter_test.rb b/actionsystemtest/test/cases/driver_adapter_test.rb new file mode 100644 index 0000000000..cecaa5b958 --- /dev/null +++ b/actionsystemtest/test/cases/driver_adapter_test.rb @@ -0,0 +1,13 @@ +require "abstract_unit" + +class DriverAdapterTest < ActiveSupport::TestCase + test "only registered adapters are accepted" do + assert_raises(NameError) do + ActionSystemTest.driver = :whatever + end + + assert_nothing_raised do + ActionSystemTest.driver = :rack_test + end + end +end diff --git a/actionsystemtest/test/cases/rails_selenium_driver_test.rb b/actionsystemtest/test/cases/rails_selenium_driver_test.rb new file mode 100644 index 0000000000..1a8e875f52 --- /dev/null +++ b/actionsystemtest/test/cases/rails_selenium_driver_test.rb @@ -0,0 +1,11 @@ +require "abstract_unit" + +class RailsSeleniumDriverTest < ActiveSupport::TestCase + def setup + ActionSystemTest.driver = :rails_selenium_driver + end + + def test_default_driver_adapter + assert_kind_of ActionSystemTest::DriverAdapters::RailsSeleniumDriver, ActionSystemTest.driver + end +end diff --git a/actionsystemtest/test/cases/screenshot_helper_test.rb b/actionsystemtest/test/cases/screenshot_helper_test.rb new file mode 100644 index 0000000000..43b24cba21 --- /dev/null +++ b/actionsystemtest/test/cases/screenshot_helper_test.rb @@ -0,0 +1,20 @@ +require "abstract_unit" + +class ScreenshotHelperTest < ActiveSupport::TestCase + def test_driver_support_for_screenshots + ActionSystemTest.driver = :rails_selenium_driver + assert ActionSystemTest.driver.supports_screenshots? + + ActionSystemTest.driver = :rack_test + assert_not ActionSystemTest.driver.supports_screenshots? + + ActionSystemTest.driver = :selenium + assert ActionSystemTest.driver.supports_screenshots? + + ActionSystemTest.driver = :webkit + assert ActionSystemTest.driver.supports_screenshots? + + ActionSystemTest.driver = :poltergeist + assert ActionSystemTest.driver.supports_screenshots? + end +end diff --git a/ci/travis.rb b/ci/travis.rb index c49a87d864..2958b5b0f5 100755 --- a/ci/travis.rb +++ b/ci/travis.rb @@ -24,6 +24,7 @@ class Build "av" => "actionview", "aj" => "activejob", "ac" => "actioncable", + "ast" => "actionsystemtest", "guides" => "guides" } @@ -154,7 +155,6 @@ ENV["GEM"].split(",").each do |gem| build = Build.new(gem, isolated: isolated) results[build.key] = build.run! - end end diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb index 73d6efdc9f..2cc33ceb5e 100644 --- a/railties/lib/rails/all.rb +++ b/railties/lib/rails/all.rb @@ -9,7 +9,7 @@ require "rails" action_cable/engine rails/test_unit/railtie sprockets/railtie - system_testing/railtie + action_system_test/railtie ).each do |railtie| begin require railtie diff --git a/railties/lib/rails/generators/rails/app/templates/config/application.rb b/railties/lib/rails/generators/rails/app/templates/config/application.rb index 2488c79da3..c0a0bd0a3e 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/application.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/application.rb @@ -14,7 +14,6 @@ require "action_view/railtie" <%= comment_if :skip_action_cable %>require "action_cable/engine" <%= comment_if :skip_sprockets %>require "sprockets/railtie" <%= comment_if :skip_test %>require "rails/test_unit/railtie" -<%= comment_if :skip_system_test %>require "system_testing/railtie" <% end -%> # Require the gems listed in Gemfile, including any gems diff --git a/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb index 2dc9cc67a6..d03b1be878 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/rails/application.rb @@ -11,7 +11,6 @@ require "action_view/railtie" require "active_job/railtie" <%= comment_if :skip_action_cable %>require "action_cable/engine" <%= comment_if :skip_test %>require "rails/test_unit/railtie" -<%= comment_if :skip_system_test %>require "system_testing/railtie" <%= comment_if :skip_sprockets %>require "sprockets/railtie" <% end -%> diff --git a/railties/lib/rails/generators/test_unit/system/templates/system_test.rb b/railties/lib/rails/generators/test_unit/system/templates/system_test.rb index 75825c880d..a74e0bb23d 100644 --- a/railties/lib/rails/generators/test_unit/system/templates/system_test.rb +++ b/railties/lib/rails/generators/test_unit/system/templates/system_test.rb @@ -1,6 +1,6 @@ require 'test_helper' -class <%= class_name.pluralize %>Test < Rails::SystemTestCase +class <%= class_name.pluralize %>Test < ActionSystemTestCase # test 'the truth' do # assert true # end diff --git a/railties/lib/rails/test_help.rb b/railties/lib/rails/test_help.rb index ab4d371b49..68fc317a60 100644 --- a/railties/lib/rails/test_help.rb +++ b/railties/lib/rails/test_help.rb @@ -7,7 +7,7 @@ require "active_support/test_case" require "action_controller" require "action_controller/test_case" require "action_dispatch/testing/integration" -require "system_test_case" +require "action_system_test" require "rails/generators/test_case" require "active_support/testing/autorun" @@ -46,7 +46,7 @@ class ActionDispatch::IntegrationTest end end -class Rails::SystemTestCase +class ActionSystemTestCase def before_setup # :nodoc: @routes = Rails.application.routes super diff --git a/railties/railties.gemspec b/railties/railties.gemspec index 76de2b4639..fb8e666f40 100644 --- a/railties/railties.gemspec +++ b/railties/railties.gemspec @@ -25,6 +25,7 @@ Gem::Specification.new do |s| s.add_dependency "activesupport", version s.add_dependency "actionpack", version + s.add_dependency "actionsystemtest", version s.add_dependency "rake", ">= 0.8.7" s.add_dependency "thor", ">= 0.18.1", "< 2.0" diff --git a/railties/test/generators/scaffold_generator_test.rb b/railties/test/generators/scaffold_generator_test.rb index d523b93ac1..43b8ce99ed 100644 --- a/railties/test/generators/scaffold_generator_test.rb +++ b/railties/test/generators/scaffold_generator_test.rb @@ -64,7 +64,7 @@ class ScaffoldGeneratorTest < Rails::Generators::TestCase # System tests assert_file "test/system/product_lines_test.rb" do |test| - assert_match(/class ProductLinesTest < Rails::SystemTestCase/, test) + assert_match(/class ProductLinesTest < ActionSystemTestCase/, test) end # Views diff --git a/railties/test/generators/system_test_generator_test.rb b/railties/test/generators/system_test_generator_test.rb index 3a9733556e..b6cf75b586 100644 --- a/railties/test/generators/system_test_generator_test.rb +++ b/railties/test/generators/system_test_generator_test.rb @@ -7,6 +7,6 @@ class SystemTestGeneratorTest < Rails::Generators::TestCase def test_system_test_skeleton_is_created run_generator - assert_file "test/system/users_test.rb", /class UsersTest < Rails::SystemTestCase/ + assert_file "test/system/users_test.rb", /class UsersTest < ActionSystemTestCase/ end end -- cgit v1.2.3