Skip to content

Commit d5f2ad2

Browse files
committed
remove the require for chromedriver
* Travis: change travis back to selenium * Default: switch to no animations for poltergeist * accept confirm * Added article link
1 parent f33d257 commit d5f2ad2

File tree

8 files changed

+111
-40
lines changed

8 files changed

+111
-40
lines changed

.travis.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,13 @@ install:
3131
- npm install
3232
- npm run build:client && npm run build:server
3333
- rake db:setup
34-
# No need to run xvfb if running headless testing
34+
35+
# Tip: No need to run xvfb if running headless testing. However, we're going to start with
36+
# Poltergeist and switch to selenium if a test fails.
3537
before_script:
3638
- export DISPLAY=:99.0
3739
- sh -e /etc/init.d/xvfb start
3840

3941
script:
4042
- bundle exec rake db:schema:load
41-
- DRIVER=poltergeist_errors_ok bundle exec rake
43+
- DRIVER=selenium bundle exec rake

Gemfile

+2-2
Original file line numberDiff line numberDiff line change
@@ -95,12 +95,12 @@ group :test do
9595
gem "capybara"
9696
gem "capybara-screenshot"
9797
gem "capybara-webkit"
98-
gem "chromedriver-helper", require: ["selenium_chrome"].include?(ENV["DRIVER"])
98+
gem "chromedriver-helper"
9999
gem "database_cleaner"
100100
gem "generator_spec"
101101
gem "launchy"
102102
gem "poltergeist"
103103
gem "rspec-rails", "~> 3"
104104
gem "rspec-retry"
105-
gem "selenium-webdriver", "<3.0.0", require: !["poltergeist", "poltergeist_errors_ok", "webkit"].include?(ENV["DRIVER"])
105+
gem "selenium-webdriver", "<3.0.0"
106106
end

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ Save a change to a JSX file and see it update immediately in the browser! Note,
144144
```
145145

146146
## Testing
147+
+ See [Yak Shaving Failing Integration Tests with React and Rails](https://blog.shakacode.com/yak-shaving-failing-integration-tests-with-react-a93444886c8c#.io9464uvz)
147148

148149
+ Be sure to see [Integration Test Notes](./docs/integration-test-notes.md) for advice on running your integration tests.
149150

docs/integration-test-notes.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# Integration Test Notes
22

3+
See [Yak Shaving Failing Integration Tests with React and Rails](https://blog.shakacode.com/yak-shaving-failing-integration-tests-with-react-a93444886c8c#.io9464uvz)
34

45
## CI
56
See the .travis.yml file, at the bottom, to see what driver is used by Travis.
67

7-
`DRIVER=poltergeist_errors_ok bundle exec rake`
8+
`DRIVER=selenium bundle exec rake`
89

910
Codeship is set to use the default driver.
1011

@@ -18,6 +19,7 @@ Support is included for the following drivers:
1819
1. Poltergeist (`DRIVER=poltergeist rspec`)
1920
1. Poltergeist no animations (`DRIVER=poltergeist_no_animations rspec`)
2021
1. Poltergeist errors ok (`DRIVER=poltergeist_errors_ok rspec`)
22+
1. Webkit (`DRIVER=webkit rspec`). Note, webkit has more errors than the other drivers.
2123

2224
You may want to experiment with using the different drivers.
2325

spec/factories.rb

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# This will guess the User class
2+
FactoryGirl.define do
3+
factory :comment do
4+
author "John"
5+
text "This is a comment text."
6+
end
7+
end

spec/features/destroy_comment_spec.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
let(:comment) { Comment.first }
77

88
scenario "clicking destroy link destroys comment" do
9-
click_link "Destroy", href: comment_path(comment)
9+
accept_confirm do
10+
click_link "Destroy", href: comment_path(comment)
11+
end
1012
expect(page).to_not have_css(".comment", text: comment.author)
1113
expect(page).to_not have_css(".comment", text: comment.text)
1214
end

spec/rails_helper.rb

+59-29
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }
3737

3838
RSpec.configure do |config|
39+
config.include FactoryGirl::Syntax::Methods
40+
3941
# Next line will ensure that assets are built if webpack -w is not running
4042
ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)
4143

@@ -44,12 +46,14 @@
4446

4547
# Using errors_ok as there is a timing issue causing crashes without this setting
4648
# https://github.com/teampoltergeist/poltergeist/issues/830
47-
default_driver = :poltergeist_errors_ok
49+
50+
default_driver = :poltergeist_no_animations
4851

4952
supported_drivers = %i( poltergeist poltergeist_errors_ok
5053
poltergeist_no_animations webkit
5154
selenium_chrome selenium_firefox selenium)
5255
driver = ENV["DRIVER"].try(:to_sym) || default_driver
56+
Capybara.default_driver = driver
5357

5458
unless supported_drivers.include?(driver)
5559
raise "Unsupported driver: #{driver} (supported = #{supported_drivers})"
@@ -59,6 +63,7 @@
5963
when :poltergeist, :poltergeist_errors_ok, :poltergeist_no_animations
6064
basic_opts = {
6165
window_size: [1300, 1800],
66+
screen_size: [1400, 1900],
6267
phantomjs_options: ["--load-images=no", "--ignore-ssl-errors=true"],
6368
timeout: 180
6469
}
@@ -78,6 +83,16 @@
7883
Capybara.register_driver :poltergeist_errors_ok do |app|
7984
Capybara::Poltergeist::Driver.new(app, no_animation_opts.merge(js_errors: false))
8085
end
86+
Capybara::Screenshot.register_driver(:poltergeist) do |js_driver, path|
87+
js_driver.browser.save_screenshot(path)
88+
end
89+
Capybara::Screenshot.register_driver(:poltergeist_no_animations) do |js_driver, path|
90+
js_driver.render(path, full: true)
91+
end
92+
Capybara::Screenshot.register_driver(:poltergeist_errors_ok) do |js_driver, path|
93+
js_driver.render(path, full: true)
94+
end
95+
8196
when :selenium_chrome
8297
DriverRegistration.register_selenium_chrome
8398
when :selenium_firefox, :selenium
@@ -86,6 +101,7 @@
86101
end
87102

88103
Capybara.javascript_driver = driver
104+
Capybara.default_driver = driver
89105

90106
Capybara.register_server(Capybara.javascript_driver) do |app, port|
91107
require "rack/handler/puma"
@@ -98,13 +114,49 @@
98114
Capybara.save_path = Rails.root.join("tmp", "capybara")
99115
Capybara::Screenshot.prune_strategy = { keep: 10 }
100116

101-
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
102-
# config.fixture_path = "#{::Rails.root}/spec/fixtures"
117+
config.use_transactional_fixtures = false
103118

104-
# If you're not using ActiveRecord, or you'd prefer not to run each of your
105-
# examples within a transaction, remove the following line or assign false
106-
# instead of true.
107-
config.use_transactional_fixtures = true
119+
config.before(:suite) do
120+
if config.use_transactional_fixtures?
121+
raise(<<-MSG)
122+
Delete line `config.use_transactional_fixtures = true` from rails_helper.rb
123+
(or set it to false) to prevent uncommitted transactions being used in
124+
JavaScript-dependent specs.
125+
126+
During testing, the app-under-test that the browser driver connects to
127+
uses a different database connection to the database connection used by
128+
the spec. The app's database connection would not be able to access
129+
uncommitted transaction data setup over the spec's database connection.
130+
MSG
131+
end
132+
DatabaseCleaner.clean_with(:truncation)
133+
end
134+
135+
config.before(:each) do
136+
DatabaseCleaner.strategy = :transaction
137+
end
138+
139+
config.before(:each, type: :feature) do
140+
# :rack_test driver's Rack app under test shares database connection
141+
# with the specs, so continue to use transaction strategy for speed.
142+
driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test
143+
144+
unless driver_shares_db_connection_with_specs
145+
# Driver is probably for an external browser with an app
146+
# under test that does *not* share a database connection with the
147+
# specs, so use truncation strategy.
148+
DatabaseCleaner.strategy = :truncation
149+
end
150+
end
151+
152+
config.before(:each) do
153+
DatabaseCleaner.start
154+
end
155+
156+
config.append_after(:each) do
157+
DatabaseCleaner.clean
158+
Capybara.reset_sessions!
159+
end
108160

109161
# RSpec Rails can automatically mix in different behaviours to your tests
110162
# based on their file location, for example enabling you to call `get` and
@@ -126,28 +178,6 @@
126178
# development server if it is running.
127179
Capybara.asset_host = "http://localhost:3000"
128180

129-
# config taken directly from RSpec example in the DatabaseCleaner README
130-
config.before(:suite) do
131-
DatabaseCleaner.strategy = :transaction
132-
DatabaseCleaner.clean_with :truncation
133-
end
134-
135-
config.around(:each) do |example|
136-
DatabaseCleaner.cleaning do
137-
example.run
138-
end
139-
end
140-
141-
config.after(:each) do
142-
# Experimental to fix failing poltergeist tests
143-
# page.driver.restart if defined?(page.driver.restart)
144-
Capybara.reset_sessions!
145-
end
146-
147-
config.append_after(:each) do
148-
DatabaseCleaner.clean
149-
end
150-
151181
def js_errors_driver
152182
Capybara.javascript_driver == :poltergeist ? :poltergeist_errors_ok : Capybara.javascript_driver
153183
end

spec/support/poltergeist.rb

+32-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,33 @@
1+
# This file supports 2 strategies:
2+
# 1. switch_to_selenium: switch drivers
3+
# 2. restart_poltergeist
4+
5+
RESTART_PHANTOMJS = ENV["RESTART_PHANTOMJS"] &&
6+
%w(TRUE YES).include?(ENV["RESTART_PHANTOMJS"].upcase)
7+
puts "RESTART_PHANTOMJS = #{RESTART_PHANTOMJS}"
8+
19
CAPYBARA_TIMEOUT_RETRIES = 5
210

311
# HACK: workaround for Capybara Poltergeist StatusFailErrors, simply retries
412
# based on https://gist.github.com/afn/c04ccfe71d648763b306
513
RSpec.configure do |config|
614
config.around(:each, type: :feature) do |ex|
715
example = RSpec.current_example
16+
use_selenium = false
17+
original_driver = Capybara.default_driver
818
CAPYBARA_TIMEOUT_RETRIES.times do
919
example.instance_variable_set("@exception", nil)
20+
21+
# Private method in rspec:
22+
# rspec-core-3.5.4/lib/rspec/core/memoized_helpers.rb:139
1023
__init_memoized
24+
25+
if use_selenium
26+
puts "Switching to selenium from #{Capybara.current_driver}"
27+
Capybara.current_driver = js_selenium_driver
28+
Capybara.javascript_driver = js_selenium_driver
29+
end
30+
1131
ex.run
1232

1333
example_ex = example.exception
@@ -36,18 +56,25 @@
3656
puts "=" * 80
3757
puts "Exception caught! #{example_ex.ai}"
3858
puts "when running example:\n #{example.full_description}"
39-
puts "at #{example.location}"
40-
puts "Restarting phantomjs and retrying..."
41-
puts " -> If this doesn't work, put a modest sleep before your last assertion."
42-
PhantomJSRestart.call
59+
puts " at #{example.location} with driver #{Capybara.current_driver}."
60+
61+
if RESTART_PHANTOMJS
62+
PhantomJSRestart.call
63+
else
64+
use_selenium = true
65+
end
4366
puts "=" * 80
4467
end
68+
Capybara.current_driver = original_driver
69+
Capybara.javascript_driver = original_driver
70+
Capybara.use_default_driver
4571
end
4672
end
4773

74+
# Rather than using switching to use selenium, we could have restarted Phantomjs
4875
module PhantomJSRestart
4976
def self.call
50-
puts "-> Restarting phantomjs: iterating through capybara sessions..."
77+
puts "Restarting phantomjs: iterating through capybara sessions..."
5178
session_pool = Capybara.send("session_pool")
5279
session_pool.each do |mode, session|
5380
msg = " => #{mode} -- "

0 commit comments

Comments
 (0)