aboutsummaryrefslogtreecommitdiffstats
path: root/actionsystemtest
diff options
context:
space:
mode:
authoreileencodes <eileencodes@gmail.com>2016-11-06 18:55:15 -0500
committereileencodes <eileencodes@gmail.com>2017-02-20 15:07:33 -0500
commit5bf0aa6745db27c45c0778f9f6e9046f9ee9fb94 (patch)
tree7ba85a8ea15146725c68ce6b9e5a94ebac6d0c9c /actionsystemtest
parenta21e18d5080a2c4808330271885f5664a725d3f3 (diff)
downloadrails-5bf0aa6745db27c45c0778f9f6e9046f9ee9fb94.tar.gz
rails-5bf0aa6745db27c45c0778f9f6e9046f9ee9fb94.tar.bz2
rails-5bf0aa6745db27c45c0778f9f6e9046f9ee9fb94.zip
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.
Diffstat (limited to 'actionsystemtest')
-rw-r--r--actionsystemtest/CHANGELOG.md3
-rw-r--r--actionsystemtest/MIT-LICENSE20
-rw-r--r--actionsystemtest/README.md108
-rw-r--r--actionsystemtest/Rakefile32
-rw-r--r--actionsystemtest/actionsystemtest.gemspec24
-rw-r--r--actionsystemtest/lib/action_system_test.rb59
-rw-r--r--actionsystemtest/lib/action_system_test/driver_adapter.rb31
-rw-r--r--actionsystemtest/lib/action_system_test/driver_adapters.rb46
-rw-r--r--actionsystemtest/lib/action_system_test/driver_adapters/capybara_driver.rb83
-rw-r--r--actionsystemtest/lib/action_system_test/driver_adapters/rails_selenium_driver.rb98
-rw-r--r--actionsystemtest/lib/action_system_test/driver_adapters/web_server.rb45
-rw-r--r--actionsystemtest/lib/action_system_test/gem_version.rb15
-rw-r--r--actionsystemtest/lib/action_system_test/railtie.rb17
-rw-r--r--actionsystemtest/lib/action_system_test/test_helper.rb23
-rw-r--r--actionsystemtest/lib/action_system_test/test_helpers.rb9
-rw-r--r--actionsystemtest/lib/action_system_test/test_helpers/assertions.rb40
-rw-r--r--actionsystemtest/lib/action_system_test/test_helpers/form_helper.rb58
-rw-r--r--actionsystemtest/lib/action_system_test/test_helpers/screenshot_helper.rb47
-rw-r--r--actionsystemtest/lib/action_system_test/version.rb8
-rw-r--r--actionsystemtest/test/abstract_unit.rb13
-rw-r--r--actionsystemtest/test/cases/capybara_driver_test.rb39
-rw-r--r--actionsystemtest/test/cases/driver_adapter_test.rb13
-rw-r--r--actionsystemtest/test/cases/rails_selenium_driver_test.rb11
-rw-r--r--actionsystemtest/test/cases/screenshot_helper_test.rb20
24 files changed, 862 insertions, 0 deletions
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 <tt>system_test_helper.rb</tt> file. The
+<tt>system_test_helper.rb</tt> file is where you can change the desired
+configuration if Rails doesn't work out of the box for you.
+
+The <tt>system_test_helper.rb</tt> 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
+<tt>system_test_helper.rb</tt>
+
+If you want to change the default settings of the Rails provided Selenium
+configuration options you can initialize a new <tt>RailsSeleniumDriver</tt>
+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 <tt>system_test_helper.rb</tt> 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
+# <tt>ActionSystemTestCase</tt>. System tests use Capybara as a base and
+# allows you to configure the driver. The default driver is
+# <tt>RailsSeleniumDriver</tt> 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 <tt>RailsSeleniumDriver</tt> 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 <tt>ActionSystemTest::DriverAdapter</tt> 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 <tt>CapybaraDriver</tt> 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 <tt>RailsSeleniumDriver</tt>, 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 <tt>CapybaraDriver</tt> are:
+ #
+ # #<ActionSystemTest::DriverAdapters::CapybaraDriver:0x007ff0e992c1d8
+ # @name=:rack_test,
+ # @server=:puma,
+ # @port=28100
+ # >
+ #
+ # The settings for the <tt>CapybaraDriver</tt> 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 <tt>RailsSeleniumDriver</tt> uses the Selenium 2.0 webdriver. The
+ # selenium-webdriver gem is required by this driver.
+ #
+ # The <tt>RailsSeleniumDriver</tt> 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 <tt>RailsSeleniumDriver</tt>
+ # 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 <tt>RailsSeleniumDriver</tt>
+ # are as follows:
+ #
+ # #<ActionSystemTest::DriverAdapters::RailsSeleniumDriver:0x007ff0e992c1d8
+ # @browser=:chrome,
+ # @server=:puma,
+ # @port=28100,
+ # @screen_size=[ 1400, 1400 ]
+ # >
+ #
+ # The settings for the <tt>RailsSeleniumDriver</tt> 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 <tt>Gem::Version</tt>.
+ 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 <tt>Gem::Version</tt>
+ 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