Permalink
Browse files

Merge commit '1.1.2'

  • Loading branch information...
2 parents 95c40ba + e7dc237 commit 73e0dc2dd2ec85ca09806271148cb081e8fb7270 @jcoglan committed Apr 14, 2012
Showing with 487 additions and 103 deletions.
  1. +1 −0 .gitignore
  2. +35 −0 History.txt
  3. +36 −8 README.rdoc
  4. +2 −2 capybara.gemspec
  5. +6 −1 lib/capybara.rb
  6. +4 −0 lib/capybara/driver/base.rb
  7. +23 −1 lib/capybara/dsl.rb
  8. +19 −3 lib/capybara/node/base.rb
  9. +39 −16 lib/capybara/node/element.rb
  10. +20 −28 lib/capybara/node/finders.rb
  11. +6 −6 lib/capybara/node/matchers.rb
  12. +3 −7 lib/capybara/node/simple.rb
  13. +21 −13 lib/capybara/rack_test/browser.rb
  14. +5 −2 lib/capybara/rack_test/driver.rb
  15. +2 −1 lib/capybara/rack_test/node.rb
  16. +8 −1 lib/capybara/selenium/driver.rb
  17. +4 −0 lib/capybara/selenium/node.rb
  18. +16 −3 lib/capybara/session.rb
  19. +5 −5 lib/capybara/spec/driver.rb
  20. +5 −0 lib/capybara/spec/public/test.js
  21. +6 −0 lib/capybara/spec/session/click_link_spec.rb
  22. +6 −0 lib/capybara/spec/session/current_host_spec.rb
  23. +6 −0 lib/capybara/spec/session/find_spec.rb
  24. +67 −0 lib/capybara/spec/session/javascript.rb
  25. +18 −0 lib/capybara/spec/session/within_spec.rb
  26. +13 −1 lib/capybara/spec/test_app.rb
  27. +1 −0 lib/capybara/spec/views/with_html.erb
  28. +5 −0 lib/capybara/spec/views/with_js.erb
  29. +1 −1 lib/capybara/util/save_and_open_page.rb
  30. +1 −1 lib/capybara/version.rb
  31. +6 −0 spec/driver/rack_test_driver_spec.rb
  32. +21 −0 spec/driver/selenium_driver_spec.rb
  33. +44 −0 spec/dsl_spec.rb
  34. +8 −0 spec/fixtures/selenium_driver_rspec_failure.rb
  35. +8 −0 spec/fixtures/selenium_driver_rspec_success.rb
  36. +0 −1 spec/rspec_spec.rb
  37. +1 −1 spec/save_and_open_page_spec.rb
  38. +11 −0 spec/session/rack_test_session_spec.rb
  39. +3 −0 spec/spec_helper.rb
  40. +1 −1 xpath
View
@@ -12,3 +12,4 @@ capybara-*.html
doc
.bundle
Gemfile.lock
+chromedriver.log
View
@@ -1,3 +1,38 @@
+# Version 1.1.0
+
+Release date: 2011-09-02
+
+### Fixed
+
+* Sensible inspect for Capybara::Session [Jo Liss]
+* Fix headers and host on redirect [Matt Colyer, Jonas Nicklas, Kim Burgestrand]
+* using_driver now restores the old driver instead of reverting to the default [Carol Nichols]
+* Errors when following links relative to the root path under rack-test [Jonas Nicklas, Kim Burgestrand]
+* Make sure exit codes are propagated properly [Edgar Beigarts]
+
+### Changed
+
+* resynchronization is off by default under Selenium
+
+### Added
+
+* Elements are automatically reloaded (including parents) during wait [Jonas Nicklas]
+* Rescue driver specific element errors, such as the dreaded ObsoleteElementError and retry [Jonas Nicklas]
+* Raise an error if something has frozen time [Jonas Nicklas]
+* Allow within to take a node instead of a selector [Peter Williams]
+* Using wait_time_time to change wait time for a block of code [Jonas Nicklas, Kim Burgestrand]
+* Option for rack-test driver to disable data-method hack [Jonas Nicklas, Kim Burgestrand]
+
+# Version 1.0.1
+
+Release date: 2011-08-12
+
+### Fixed
+
+* Dependend on selenium-webdriver ~>2.0 and fix deprecations [Thomas Walpole, Jo Liss]
+* Depend on Launch 2.0 [Jeremy Hinegardner]
+* Rack-Test ignores fill in on fields with maxlength=""
+
# Version 1.0.0
Release date: 2011-06-14
View
@@ -8,7 +8,7 @@ Capybara aims to simplify the process of integration testing Rack applications,
such as Rails, Sinatra or Merb. Capybara simulates how a real user would
interact with a web application. It is agnostic about the driver running your
tests and currently comes with Rack::Test and Selenium support built in.
-HtmlUnit and env.js are supported through external gems.
+HtmlUnit, WebKit and env.js are supported through external gems.
A complete reference is available at
{at rubydoc.info}[http://rubydoc.info/github/jnicklas/capybara/master].
@@ -36,7 +36,7 @@ create a topic branch for every separate change you make.
Capybara uses bundler in development. To set up a development environment, simply do:
git submodule update --init
- gem install bundler --pre
+ gem install bundler
bundle install
== Using Capybara with Cucumber
@@ -240,10 +240,11 @@ At the moment, Capybara supports {Selenium 2.0
*not* Selenium RC. Provided Firefox is installed, everything is set up for you,
and you should be able to start using Selenium right away.
-By default Capybara tries to synchronize Ajax requests, so it will wait for
-Ajax requests to finish after you've interacted with the page. You can switch
-off this behaviour by setting the driver option <tt>:resynchronize</tt> to
-<tt>false</tt>. See the section on configuring drivers.
+Capybara can block and wait for Ajax requests to finish after you've interacted
+with the page. To enable this behaviour, set the <tt>:resynchronize</tt> driver
+option to <tt>true</tt>. This should normally not be necessary, since
+Capybara's automatic reloading should take care of any asynchronicity problems.
+See the section on Asynchronous JavaScript for details.
Note: Selenium does not support transactional fixtures; see the section
"Transactional Fixtures" below.
@@ -282,6 +283,21 @@ Ruby 1.8.7 at this time.
Note: Envjs does not support transactional fixtures; see the section
"Transactional Fixtures" below.
+=== Capybara-webkit
+
+The {capybara-webkit drive}[https://github.com/thoughtbot/capybara-webkit] is for true headless
+testing. It uses WebKitQt to start a rendering engine process. It can execute JavaScript as well.
+It is significantly faster than drivers like Selenium since it does not load an entire browser.
+
+You can install it with:
+
+ gem install capybara-webkit
+
+And you can use it by:
+
+ Capybara.javascript_driver = :webkit
+
+
== The DSL
Capybara's DSL (domain-specific language) is inspired by Webrat. While
@@ -468,9 +484,9 @@ When issuing instructions to the DSL such as:
click_link('bar')
page.should have_content('baz')
-If clicking on the *foo* link causes triggers an asynchronous process, such as
+If clicking on the *foo* link triggers an asynchronous process, such as
an Ajax request, which, when complete will add the *bar* link to the page,
-clicking on the *bar* link would be expeced to fail, since that link doesn't
+clicking on the *bar* link would be expected to fail, since that link doesn't
exist yet. However Capybara is smart enought to retry finding the link for a
brief period of time before giving up and throwing an error. The same is true of
the next line, which looks for the content *baz* on the page; it will retry
@@ -490,6 +506,18 @@ asynchronous process has not yet removed the element from the page, it would
therefore fail, even though the code might be working correctly. The latter
correctly waits for the element to disappear from the page.
+Capybara's waiting behaviour is quite advanced, and can deal with situations
+such as the following line of code:
+
+ find('#sidebar').find('h1').should have_content('Something')
+
+Even if JavaScript causes <tt>#sidebar</tt> to disappear off the page, Capybara
+will automatically reload it and any elements it contains. So if an AJAX
+request causes the contents of <tt>#sidebar</tt> to change, which would update
+the text of the <tt>h1</tt> to "Something", and this happened, this test would
+pass. If you do not want this behaviour, you can set
+<tt>Capybara.automatic_reload</tt> to <tt>false</tt>.
+
== Using the DSL in unsupported testing frameworks
You can mix the DSL into any context by including +Capybara::DSL+:
View
@@ -24,14 +24,14 @@ Gem::Specification.new do |s|
s.add_runtime_dependency("nokogiri", [">= 1.3.3"])
s.add_runtime_dependency("mime-types", [">= 1.16"])
- s.add_runtime_dependency("selenium-webdriver", ["~> 2.0.0"])
+ s.add_runtime_dependency("selenium-webdriver", ["~> 2.0"])
s.add_runtime_dependency("rack", [">= 1.0.0"])
s.add_runtime_dependency("rack-test", [">= 0.5.4"])
s.add_runtime_dependency("xpath", ["~> 0.1.4"])
s.add_development_dependency("sinatra", [">= 0.9.4"])
s.add_development_dependency("rspec", [">= 2.0.0"])
- s.add_development_dependency("launchy", [">= 0.3.5"])
+ s.add_development_dependency("launchy", ["~> 2.0.4"])
s.add_development_dependency("yard", [">= 0.5.8"])
s.add_development_dependency("fuubar", [">= 0.0.1"])
s.add_development_dependency("cucumber", [">= 0.10"])
View
@@ -4,7 +4,9 @@
module Capybara
class CapybaraError < StandardError; end
class DriverNotFoundError < CapybaraError; end
+ class FrozenInTime < CapybaraError; end
class ElementNotFound < CapybaraError; end
+ class ExpectationNotMet < ElementNotFound; end
class FileNotFound < CapybaraError; end
class UnselectNotAllowed < CapybaraError; end
class NotSupportedByDriverError < CapybaraError; end
@@ -16,7 +18,7 @@ class << self
attr_accessor :asset_root, :app_host, :run_server, :default_host
attr_accessor :server_port, :server_boot_timeout
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements, :prefer_visible_elements
- attr_accessor :save_and_open_page_path
+ attr_accessor :save_and_open_page_path, :automatic_reload
##
#
@@ -36,6 +38,8 @@ class << self
# [default_wait_time = Integer] The number of seconds to wait for asynchronous processes to finish (Default: 2)
# [ignore_hidden_elements = Boolean] Whether to ignore hidden elements on the page (Default: false)
# [prefer_visible_elements = Boolean] Whether to prefer visible elements over hidden elements (Default: true)
+ # [automatic_reload = Boolean] Whether to automatically reload elements as Capybara is waiting (Default: true)
+ # [save_and_open_page_path = String] Where to put pages saved through save_and_open_page (Default: Dir.pwd)
#
# === DSL Options
#
@@ -236,6 +240,7 @@ module Selenium
config.ignore_hidden_elements = false
config.prefer_visible_elements = true
config.default_host = "http://www.example.com"
+ config.automatic_reload = true
end
Capybara.register_driver :rack_test do |app|
@@ -43,6 +43,10 @@ def within_window(handle)
raise Capybara::NotSupportedByDriverError
end
+ def invalid_element_errors
+ []
+ end
+
def wait?
false
end
View
@@ -49,10 +49,23 @@ def use_default_driver
# Yield a block using a specific driver
#
def using_driver(driver)
+ previous_driver = Capybara.current_driver
Capybara.current_driver = driver
yield
ensure
- Capybara.use_default_driver
+ @current_driver = previous_driver
+ end
+
+ ##
+ #
+ # Yield a block using a specific wait time
+ #
+ def using_wait_time(seconds)
+ previous_wait_time = Capybara.default_wait_time
+ Capybara.default_wait_time = seconds
+ yield
+ ensure
+ Capybara.default_wait_time = previous_wait_time
end
##
@@ -116,6 +129,15 @@ def using_session(name, &block)
##
#
+ # Shortcut to working in a different session. This is useful when Capybara is included
+ # in a class or module.
+ #
+ def using_wait_time(seconds, &block)
+ Capybara.using_wait_time(seconds, &block)
+ end
+
+ ##
+ #
# Shortcut to accessing the current session. This is useful when Capybara is included in a
# class or module.
#
View
@@ -22,7 +22,7 @@ module Node
# session.has_css?('#foobar') # from Capybara::Node::Matchers
#
class Base
- attr_reader :session, :base
+ attr_reader :session, :base, :parent
include Capybara::Node::Finders
include Capybara::Node::Actions
@@ -33,10 +33,26 @@ def initialize(session, base)
@base = base
end
+ def reload
+ self
+ end
+
protected
- def wait?
- driver.wait?
+ def wait_until(seconds=Capybara.default_wait_time)
+ start_time = Time.now
+
+ begin
+ yield
+ rescue => e
+ raise e unless driver.wait?
+ raise e unless (driver.respond_to?(:invalid_element_errors) and driver.invalid_element_errors.include?(e.class)) or e.is_a?(Capybara::ElementNotFound)
+ raise e if (Time.now - start_time) >= seconds
+ sleep(0.05)
+ raise Capybara::FrozenInTime, "time appears to be frozen, Capybara does not work with libraries which freeze time, consider using time travelling instead" if Time.now == start_time
+ reload if Capybara.automatic_reload
+ retry
+ end
end
def driver
Oops, something went wrong.

0 comments on commit 73e0dc2

Please sign in to comment.