Skip to content

remove the require for chromedriver #345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 26, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@ install:
- npm install
- npm run build:client && npm run build:server
- rake db:setup
# No need to run xvfb if running headless testing

# Tip: No need to run xvfb if running headless testing. However, we're going to start with
# Poltergeist and switch to selenium if a test fails.
before_script:
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start

script:
- bundle exec rake db:schema:load
- DRIVER=poltergeist_errors_ok bundle exec rake
- DRIVER=selenium bundle exec rake
4 changes: 2 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,12 @@ group :test do
gem "capybara"
gem "capybara-screenshot"
gem "capybara-webkit"
gem "chromedriver-helper", require: ["selenium_chrome"].include?(ENV["DRIVER"])
gem "chromedriver-helper"
gem "database_cleaner"
gem "generator_spec"
gem "launchy"
gem "poltergeist"
gem "rspec-rails", "~> 3"
gem "rspec-retry"
gem "selenium-webdriver", "<3.0.0", require: !["poltergeist", "poltergeist_errors_ok", "webkit"].include?(ENV["DRIVER"])
gem "selenium-webdriver", "<3.0.0"
end
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ Save a change to a JSX file and see it update immediately in the browser! Note,
```

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

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

Expand Down
4 changes: 3 additions & 1 deletion docs/integration-test-notes.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Integration Test Notes

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

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

`DRIVER=poltergeist_errors_ok bundle exec rake`
`DRIVER=selenium bundle exec rake`

Codeship is set to use the default driver.

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

You may want to experiment with using the different drivers.

Expand Down
7 changes: 7 additions & 0 deletions spec/factories.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# This will guess the User class
FactoryGirl.define do
factory :comment do
author "John"
text "This is a comment text."
end
end
4 changes: 3 additions & 1 deletion spec/features/destroy_comment_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
let(:comment) { Comment.first }

scenario "clicking destroy link destroys comment" do
click_link "Destroy", href: comment_path(comment)
accept_confirm do
click_link "Destroy", href: comment_path(comment)
end
expect(page).to_not have_css(".comment", text: comment.author)
expect(page).to_not have_css(".comment", text: comment.text)
end
Expand Down
88 changes: 59 additions & 29 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

RSpec.configure do |config|
config.include FactoryGirl::Syntax::Methods

# Next line will ensure that assets are built if webpack -w is not running
ReactOnRails::TestHelper.configure_rspec_to_compile_assets(config)

Expand All @@ -44,12 +46,14 @@

# Using errors_ok as there is a timing issue causing crashes without this setting
# https://github.com/teampoltergeist/poltergeist/issues/830
default_driver = :poltergeist_errors_ok

default_driver = :poltergeist_no_animations

supported_drivers = %i( poltergeist poltergeist_errors_ok
poltergeist_no_animations webkit
selenium_chrome selenium_firefox selenium)
driver = ENV["DRIVER"].try(:to_sym) || default_driver
Capybara.default_driver = driver

unless supported_drivers.include?(driver)
raise "Unsupported driver: #{driver} (supported = #{supported_drivers})"
Expand All @@ -59,6 +63,7 @@
when :poltergeist, :poltergeist_errors_ok, :poltergeist_no_animations
basic_opts = {
window_size: [1300, 1800],
screen_size: [1400, 1900],
phantomjs_options: ["--load-images=no", "--ignore-ssl-errors=true"],
timeout: 180
}
Expand All @@ -78,6 +83,16 @@
Capybara.register_driver :poltergeist_errors_ok do |app|
Capybara::Poltergeist::Driver.new(app, no_animation_opts.merge(js_errors: false))
end
Capybara::Screenshot.register_driver(:poltergeist) do |js_driver, path|
js_driver.browser.save_screenshot(path)
end
Capybara::Screenshot.register_driver(:poltergeist_no_animations) do |js_driver, path|
js_driver.render(path, full: true)
end
Capybara::Screenshot.register_driver(:poltergeist_errors_ok) do |js_driver, path|
js_driver.render(path, full: true)
end

when :selenium_chrome
DriverRegistration.register_selenium_chrome
when :selenium_firefox, :selenium
Expand All @@ -86,6 +101,7 @@
end

Capybara.javascript_driver = driver
Capybara.default_driver = driver

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

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

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true
config.before(:suite) do
if config.use_transactional_fixtures?
raise(<<-MSG)
Delete line `config.use_transactional_fixtures = true` from rails_helper.rb
(or set it to false) to prevent uncommitted transactions being used in
JavaScript-dependent specs.

During testing, the app-under-test that the browser driver connects to
uses a different database connection to the database connection used by
the spec. The app's database connection would not be able to access
uncommitted transaction data setup over the spec's database connection.
MSG
end
DatabaseCleaner.clean_with(:truncation)
end

config.before(:each) do
DatabaseCleaner.strategy = :transaction
end

config.before(:each, type: :feature) do
# :rack_test driver's Rack app under test shares database connection
# with the specs, so continue to use transaction strategy for speed.
driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test

unless driver_shares_db_connection_with_specs
# Driver is probably for an external browser with an app
# under test that does *not* share a database connection with the
# specs, so use truncation strategy.
DatabaseCleaner.strategy = :truncation
end
end

config.before(:each) do
DatabaseCleaner.start
end

config.append_after(:each) do
DatabaseCleaner.clean
Capybara.reset_sessions!
end

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

# config taken directly from RSpec example in the DatabaseCleaner README
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with :truncation
end

config.around(:each) do |example|
DatabaseCleaner.cleaning do
example.run
end
end

config.after(:each) do
# Experimental to fix failing poltergeist tests
# page.driver.restart if defined?(page.driver.restart)
Capybara.reset_sessions!
end

config.append_after(:each) do
DatabaseCleaner.clean
end

def js_errors_driver
Capybara.javascript_driver == :poltergeist ? :poltergeist_errors_ok : Capybara.javascript_driver
end
Expand Down
37 changes: 32 additions & 5 deletions spec/support/poltergeist.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,33 @@
# This file supports 2 strategies:
# 1. switch_to_selenium: switch drivers
# 2. restart_poltergeist

RESTART_PHANTOMJS = ENV["RESTART_PHANTOMJS"] &&
%w(TRUE YES).include?(ENV["RESTART_PHANTOMJS"].upcase)
puts "RESTART_PHANTOMJS = #{RESTART_PHANTOMJS}"

CAPYBARA_TIMEOUT_RETRIES = 5

# HACK: workaround for Capybara Poltergeist StatusFailErrors, simply retries
# based on https://gist.github.com/afn/c04ccfe71d648763b306
RSpec.configure do |config|
config.around(:each, type: :feature) do |ex|
example = RSpec.current_example
use_selenium = false
original_driver = Capybara.default_driver
CAPYBARA_TIMEOUT_RETRIES.times do
example.instance_variable_set("@exception", nil)

# Private method in rspec:
# rspec-core-3.5.4/lib/rspec/core/memoized_helpers.rb:139
__init_memoized

if use_selenium
puts "Switching to selenium from #{Capybara.current_driver}"
Capybara.current_driver = js_selenium_driver
Capybara.javascript_driver = js_selenium_driver
end

ex.run

example_ex = example.exception
Expand Down Expand Up @@ -36,18 +56,25 @@
puts "=" * 80
puts "Exception caught! #{example_ex.ai}"
puts "when running example:\n #{example.full_description}"
puts "at #{example.location}"
puts "Restarting phantomjs and retrying..."
puts " -> If this doesn't work, put a modest sleep before your last assertion."
PhantomJSRestart.call
puts " at #{example.location} with driver #{Capybara.current_driver}."

if RESTART_PHANTOMJS
PhantomJSRestart.call
else
use_selenium = true
end
puts "=" * 80
end
Capybara.current_driver = original_driver
Capybara.javascript_driver = original_driver
Capybara.use_default_driver
end
end

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