Permalink
Browse files

Call system test driver per-instance rather than globally

Previously the system test subclasses would call `driven_by` when the
app booted and not again when the test was initialized which resulted in
the driver from whichever class was called last to be used in tests.

In rails/rails#28144 the `driven_by` method was changed to run `use` on
setup and `reset` on teardown. While this was a viable fix this really
pointed to the problem that system test `driven_by` was a global
setting, rather than a per-class setting.

To alieviate this problem calling the driver should be done on an
instance level, rather than on the global level. I added an `initialize`
method to `SystemTestCase` which will call `use` on the superclass
driver. Running the server has been moved to `start_application` so that
it only needs to be called once on boot and no options from `driven_by`
were being passed to it.

This required a largish rewrite of the tests. Each test needs to utilize
the subclass so that it can properly test the drivers.
`ActionDispatch::SystemTestCase` shouldn't be called directly anymore.
  • Loading branch information...
eileencodes committed Mar 6, 2017
1 parent 4dbebe4 commit 7c9af60e5c26941dc9ec6a263f5fc5fe10050cba
@@ -83,12 +83,19 @@ class SystemTestCase < IntegrationTest
include SystemTesting::TestHelpers::SetupAndTeardown
include SystemTesting::TestHelpers::ScreenshotHelper
def initialize(*) # :nodoc:
super
self.class.superclass.driver.use
end
def self.start_application # :nodoc:
Capybara.app = Rack::Builder.new do
map "/" do
run Rails.application
end
end
SystemTesting::Server.new.run
end
# System Test configuration options
@@ -104,12 +111,12 @@ def self.start_application # :nodoc:
#
# driven_by :selenium, screen_size: [800, 800]
def self.driven_by(driver, using: :chrome, screen_size: [1400, 1400])
driver = SystemTesting::Driver.new(driver, using: using, screen_size: screen_size)
setup { driver.use }
teardown { driver.reset }
@driver = SystemTesting::Driver.new(driver, using: using, screen_size: screen_size)
end
SystemTesting::Server.new.run
# Returns the driver object for the initialized system test
def self.driver
@driver ||= SystemTestCase.driven_by(:selenium)
end
end
@@ -12,10 +12,6 @@ def use
setup
end
def reset
Capybara.current_driver = @current
end
private
def selenium?
@name == :selenium
@@ -31,7 +27,6 @@ def register
def setup
Capybara.current_driver = @name
@current = Capybara.current_driver
end
end
end
@@ -57,7 +57,7 @@ def failed?
end
def supports_screenshot?
page.driver.public_methods(false).include?(:save_screenshot)
Capybara.current_driver != :rack_test
end
end
end
@@ -439,3 +439,11 @@ class ActiveSupport::TestCase
skip message if defined?(JRUBY_VERSION)
end
end
class DrivenByRackTest < ActionDispatch::SystemTestCase
driven_by :rack_test
end
class DrivenBySeleniumWithChrome < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome
end
@@ -8,10 +8,10 @@ class DriverTest < ActiveSupport::TestCase
end
test "initializing the driver with a browser" do
driver = ActionDispatch::SystemTesting::Driver.new(:selenium, using: :chrome, screen_size: [ 1400, 1400 ])
driver = ActionDispatch::SystemTesting::Driver.new(:selenium, using: :chrome, screen_size: [1400, 1400])
assert_equal :selenium, driver.instance_variable_get(:@name)
assert_equal :chrome, driver.instance_variable_get(:@using)
assert_equal [ 1400, 1400 ], driver.instance_variable_get(:@screen_size)
assert_equal :chrome, driver.instance_variable_get(:@browser)
assert_equal [1400, 1400], driver.instance_variable_get(:@screen_size)
end
test "selenium? returns false if driver is poltergeist" do
@@ -4,50 +4,38 @@
class ScreenshotHelperTest < ActiveSupport::TestCase
test "image path is saved in tmp directory" do
new_test = ActionDispatch::SystemTestCase.new("x")
new_test = DrivenBySeleniumWithChrome.new("x")
assert_equal "tmp/screenshots/x.png", new_test.send(:image_path)
end
test "image path includes failures text if test did not pass" do
new_test = ActionDispatch::SystemTestCase.new("x")
new_test = DrivenBySeleniumWithChrome.new("x")
new_test.stub :passed?, false do
assert_equal "tmp/screenshots/failures_x.png", new_test.send(:image_path)
end
end
test "image path does not include failures text if test skipped" do
new_test = ActionDispatch::SystemTestCase.new("x")
new_test = DrivenBySeleniumWithChrome.new("x")
new_test.stub :passed?, false do
new_test.stub :skipped?, true do
assert_equal "tmp/screenshots/x.png", new_test.send(:image_path)
end
end
end
end
class RackTestScreenshotsTest < DrivenByRackTest
test "rack_test driver does not support screenshot" do
begin
original_driver = Capybara.current_driver
Capybara.current_driver = :rack_test
new_test = ActionDispatch::SystemTestCase.new("x")
assert_not new_test.send(:supports_screenshot?)
ensure
Capybara.current_driver = original_driver
end
assert_not self.send(:supports_screenshot?)
end
end
class SeleniumScreenshotsTest < DrivenBySeleniumWithChrome
test "selenium driver supports screenshot" do
begin
original_driver = Capybara.current_driver
Capybara.current_driver = :selenium
new_test = ActionDispatch::SystemTestCase.new("x")
assert new_test.send(:supports_screenshot?)
ensure
Capybara.current_driver = original_driver
end
assert self.send(:supports_screenshot?)
end
end
@@ -1,17 +1,13 @@
require "abstract_unit"
class DrivenByRackTestTest < ActionDispatch::SystemTestCase
driven_by :rack_test
class SetDriverToRackTestTest < DrivenByRackTest
test "uses rack_test" do
assert_equal :rack_test, Capybara.current_driver
end
end
class DrivenBySeleniumWithChromeTest < ActionDispatch::SystemTestCase
driven_by :selenium, using: :chrome
class SetDriverToSeleniumTest < DrivenBySeleniumWithChrome
test "uses selenium" do
assert_equal :chrome, Capybara.current_driver
assert_equal :selenium, Capybara.current_driver
end
end

0 comments on commit 7c9af60

Please sign in to comment.