RailsCasts - Ruby on Rails Screencasts

RailsCasts Pro episodes are now free!

Learn more or hide this

Testing JavaScript with PhantomJS

#391 Testing JavaScript with PhantomJS pro

Nov 07, 2012 | 10 minutes | Testing, Tools, Plugins
PhantomJS allows us to test JavaScript without going through a browser window. Here I show how to do this using Capybara and Poltergeist. I also give some tips on handling database transactions and skipping javascript tests.
Click to Play Video ▶
Tweet
  • Download:
  • source code Project Files in Zip (57 KB)
  • mp4 Full Size H.264 Video (27.3 MB)
  • m4v Smaller H.264 Video (12.3 MB)
  • webm Full Size VP8 Video (13.5 MB)
  • ogv Full Size Theora Video (28.5 MB)
Browse_code Browse Source Code

Resources

Note: In the episode I mention the Rails app is running in a separate process, but it is actually a separate thread. Also some have reported concurrency issues with the shared database connection hack, therefore you may want to use truncation with Database Cleaner instead (thanks Jon Leighton).

terminal
brew install phantomjs
phantomjs try_phantom.coffee
rake spec
rspec . --tag '~js'
Gemfile
group :test do
 gem 'capybara'
 gem 'poltergeist'
end
spec/spec_helper.rb
require 'capybara/poltergeist'
Capybara.javascript_driver = :poltergeist
spec/support/shared_db_connection.rb
class ActiveRecord::Base
 mattr_accessor :shared_connection
 @@shared_connection = nil
 
 def self.connection
 @@shared_connection || retrieve_connection
 end
end
 
# Forces all threads to share the same connection. This works on
# Capybara because it starts the web server in a thread.
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
spec/requests/orders_spec.rb
describe "Orders" do
 it "validates card number", js: true do
 visit new_order_path
 fill_in "Credit Card Number", with: "1234"
 page.should have_content("Invalid card number")
 end
 
 it "fetches more orders when scrolling to bottom", js: true do
 11.times { |n| Order.create! number: n+1 }
 visit orders_path
 page.should have_content('Order #1')
 page.should_not have_content('Order #11')
 page.evaluate_script("window.scrollTo(0, document.height)")
 page.should have_content('Order #11')
 end
end
try_phantom.coffee
page = require('webpage').create()
page.open 'http://localhost:3000', (status) ->
 title = page.evaluate -> document.title
 console.log "Title: #{title}"
 phantom.exit()
loading

AltStyle によって変換されたページ (->オリジナル) /