[DRE-commits] [ruby-capybara] 01/06: Imported Upstream version 2.2.1
Jérémy Bobbio
lunar at moszumanska.debian.org
Sun May 4 11:59:17 UTC 2014
This is an automated email from the git hooks/post-receive script.
lunar pushed a commit to annotated tag debian/2.2.1-1
in repository ruby-capybara.
commit d2492711da0da6c80d99299fb7548e14760245ae
Author: Jérémy Bobbio <lunar at debian.org>
Date: Sun May 4 13:18:53 2014 +0200
Imported Upstream version 2.2.1
---
History.md | 49 +++++++-
README.md | 40 +++---
checksums.yaml.gz | Bin 0 -> 268 bytes
checksums.yaml.gz.sig | Bin 0 -> 256 bytes
data.tar.gz.sig | Bin 256 -> 256 bytes
lib/capybara.rb | 29 ++++-
lib/capybara/cucumber.rb | 2 -
lib/capybara/driver/base.rb | 10 +-
lib/capybara/node/actions.rb | 2 +-
lib/capybara/node/finders.rb | 6 +-
lib/capybara/node/matchers.rb | 40 +++---
lib/capybara/node/simple.rb | 8 +-
lib/capybara/query.rb | 1 +
lib/capybara/rack_test/browser.rb | 9 +-
lib/capybara/rack_test/form.rb | 7 +-
lib/capybara/rack_test/node.rb | 3 +-
lib/capybara/result.rb | 3 +-
lib/capybara/rspec.rb | 7 ++
lib/capybara/rspec/features.rb | 2 +
lib/capybara/rspec/matchers.rb | 12 +-
lib/capybara/selector.rb | 4 +-
lib/capybara/selenium/driver.rb | 14 ++-
lib/capybara/selenium/node.rb | 23 +++-
lib/capybara/server.rb | 10 +-
lib/capybara/session.rb | 76 +++++++++---
lib/capybara/spec/public/test.js | 2 +-
lib/capybara/spec/session/assert_selector.rb | 18 +++
lib/capybara/spec/session/attach_file_spec.rb | 7 +-
lib/capybara/spec/session/check_spec.rb | 14 +++
lib/capybara/spec/session/choose_spec.rb | 14 +++
lib/capybara/spec/session/click_button_spec.rb | 21 +++-
lib/capybara/spec/session/fill_in_spec.rb | 20 ++-
lib/capybara/spec/session/go_back_spec.rb | 10 ++
lib/capybara/spec/session/go_forward_spec.rb | 12 ++
lib/capybara/spec/session/has_button_spec.rb | 24 ++++
lib/capybara/spec/session/has_field_spec.rb | 48 ++++++++
lib/capybara/spec/session/has_text_spec.rb | 18 +++
lib/capybara/spec/session/node_spec.rb | 37 +++++-
lib/capybara/spec/session/reset_session_spec.rb | 10 +-
lib/capybara/spec/session/save_page_spec.rb | 14 ++-
lib/capybara/spec/session/visit_spec.rb | 16 +++
lib/capybara/spec/session/within_frame_spec.rb | 7 ++
lib/capybara/spec/session/within_window_spec.rb | 7 ++
lib/capybara/spec/test_app.rb | 1 +
lib/capybara/spec/views/form.erb | 40 ++++++
lib/capybara/spec/views/with_html.erb | 5 +
lib/capybara/spec/views/with_js.erb | 8 ++
lib/capybara/version.rb | 2 +-
metadata.gz.sig | Bin 256 -> 256 bytes
metadata.yml | 155 +++++++++---------------
spec/capybara_spec.rb | 2 +-
spec/result_spec.rb | 14 +++
spec/rspec/features_spec.rb | 15 +++
spec/rspec/matchers_spec.rb | 25 +++-
spec/selenium_spec.rb | 11 +-
spec/selenium_spec_chrome.rb | 21 ++++
spec/server_spec.rb | 18 ++-
57 files changed, 758 insertions(+), 215 deletions(-)
diff --git a/History.md b/History.md
index 8ee6b61..fbe9815 100644
--- a/History.md
+++ b/History.md
@@ -1,6 +1,53 @@
+# Version 2.2.0
+
+Release date: 2013-11-21
+
+### Added
+
+* Add `go_back` and `go_forward` methods. [Vasiliy Ermolovich]
+* Support RSpec 3 [Thomas Holmes]
+* `has_button?`, `has_checked_field?` and `has_unchecked_field?` accept
+ options, like other matchers. [Carol Nichols]
+* The `assert_selector` and `has_text?` methods now support the `:wait` option
+ [Vasiliy Ermolovich]
+* RackTest's visible? method now checks for the HTML5 `hidden` attribute.
+* Results from `#all` now delegate the `sample` method. [Phil Lee]
+* The `set` method now works for contenteditable attributes under Selenium.
+ [Jon Rowe]
+* radio buttons and check boxes can be filtered by option value, useful when
+ selecting by name [Jonas Nicklas]
+* feature blocks can be nested within other feature blocks in RSpec tests
+ [Travis Gaff]
+
+### Fixed
+
+* Fixed race conditions causing stale element errors when filtering by text.
+ [Jonas Nicklas]
+* Resetting the page is now synchronous and navigates to an empty HTML file,
+ instead of `about:blank`, fixing hanging issues in JRuby. [Jonas Nicklas]
+* Fixed cookies not being set when path is blank under RackTest [Thomas Walpole]
+* Clearing fields now correctly causes change events [Jonas Nicklas]
+* Navigating to an absolut URI without trailing slash now works as expected
+ under RackTest [Jonas Nicklas]
+* Checkboxes without assigned value default to `on` under RackTest [Nigel Sheridan-Smith]
+* Clicks on buttons with no form associated with them are ignored in RackTest
+ instead of raising an obscure exception. [Thomas Walpole]
+* execute_script is now a session method [Andrey Botalov]
+* Nesting `within_window` and `within_frame` inside `within` resets the scope
+ so that they behave like a user would expect [Thomas Walpole]
+* Improve handling of newlines in textareas [Thomas Walpole]
+* `Capybara::Result` delegates its inspect method, so as not to confuse users
+ [Sam Rawlins]
+* save_page always returns a full path, fixes problems with Launchy [Jonas Nicklas]
+* Selenium driver's `quit` method does nothing when browser hasn't been loaded
+ [randoum]
+* Capybara's WEBRick server now propertly respects the server_host option
+ [Dmitry Vorotilin]
+* gemspec now includes license information [Jonas Nicklas]
+
# Version 2.1.0
-Release date: Unreleased
+Release date: 2013-04-09
### Changed
diff --git a/README.md b/README.md
index 0474122..e7485ce 100644
--- a/README.md
+++ b/README.md
@@ -2,7 +2,7 @@
[![Build Status](https://secure.travis-ci.org/jnicklas/capybara.png)](http://travis-ci.org/jnicklas/capybara)
[![Dependency Status](https://gemnasium.com/jnicklas/capybara.png)](https://gemnasium.com/jnicklas/capybara)
-[![Code Quality](https://codeclimate.com/badge.png)](https://codeclimate.com/github/jnicklas/capybara)
+[![Code Climate](https://codeclimate.com/github/jnicklas/capybara.png)](https://codeclimate.com/github/jnicklas/capybara)
Capybara helps you test web applications by simulating how a real user would
interact with your app. It is agnostic about the driver running your tests and
@@ -96,7 +96,7 @@ Capybara with `:type => :feature`.
You can now write your specs like so:
```ruby
-describe "the signup process", :type => :feature do
+describe "the signin process", :type => :feature do
before :each do
User.make(:email => 'user at example.com', :password => 'caplin')
end
@@ -108,7 +108,7 @@ describe "the signup process", :type => :feature do
fill_in 'Password', :with => 'password'
end
click_link 'Sign in'
- page.should have_content 'Success'
+ expect(page).to have_content 'Success'
end
end
```
@@ -127,7 +127,7 @@ end
Finally, Capybara also comes with a built in DSL for creating descriptive acceptance tests:
```ruby
-feature "Signing up" do
+feature "Signing in" do
background do
User.make(:email => 'user at example.com', :password => 'caplin')
end
@@ -139,7 +139,7 @@ feature "Signing up" do
fill_in 'Password', :with => 'caplin'
end
click_link 'Sign in'
- page.should have_content 'Success'
+ expect(page).to have_content 'Success'
end
given(:other_user) { User.make(:email => 'other at example.com', :password => 'rous') }
@@ -151,7 +151,7 @@ feature "Signing up" do
fill_in 'Password', :with => other_user.password
end
click_link 'Sign in'
- page.should have_content 'Invalid email or password'
+ expect(page).to have_content 'Invalid email or password'
end
end
```
@@ -162,7 +162,7 @@ end
## Using Capybara with Test::Unit
-* If you are using Rails, add the following code in your `test_helper.rb`
+* If you are using Rails, add the following code in your `test_helper.rb`
file to make Capybara available in all test cases deriving from
`ActionDispatch::IntegrationTest`:
@@ -209,7 +209,7 @@ end
Set up your base class as with Test::Unit. (On Rails, the right base class
could be something other than ActionDispatch::IntegrationTest.)
-The capybara_minitest_spec gem ([Github](https://github.com/ordinaryzelig/capybara_minitest_spec),
+The capybara_minitest_spec gem ([GitHub](https://github.com/ordinaryzelig/capybara_minitest_spec),
[rubygems.org](https://rubygems.org/gems/capybara_minitest_spec)) provides MiniTest::Spec
expectations for Capybara. For example:
@@ -271,7 +271,7 @@ RackTest can be configured with a set of headers like this:
```ruby
Capybara.register_driver :rack_test do |app|
- Capybara::RackTest::Driver.new(app, :browser => :chrome)
+ Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_USER_AGENT' => 'Capybara' })
end
```
@@ -281,10 +281,12 @@ See the section on adding and configuring drivers.
At the moment, Capybara supports [Selenium 2.0
(Webdriver)](http://seleniumhq.org/docs/01_introducing_selenium.html#selenium-2-aka-selenium-webdriver),
-*not* Selenium RC. Provided Firefox is installed, everything is set up for you,
-and you should be able to start using Selenium right away.
+*not* Selenium RC. In order to use Selenium, you'll need to install the
+`selenium-webdriver` gem, and add it to your Gemfile if you're using bundler.
+Provided Firefox is installed, everything is set up for you, and you should be
+able to start using Selenium right away.
-**Note**: drivers which run the server in a different thread may not work share the
+**Note**: drivers which run the server in a different thread may not share the
same transaction as your tests, causing data not to be shared between your test
and test server, see "Transactions and database setup" below.
@@ -325,7 +327,7 @@ Capybara heavily uses XPath, which doesn't support case insensitivity.
### Navigating
You can use the
-[#visit](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#visit-instance_method)
+<tt>[visit](http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Session#visit-instance_method)</tt>
method to navigate to other pages:
```ruby
@@ -450,8 +452,6 @@ within(:xpath, "//li[@id='employee']") do
end
```
-**Note**: `within` will scope the actions to the _first_ (not _any_) element that matches the selector.
-
There are special methods for restricting the scope to a specific fieldset,
identified by either an id or the text of the fieldset's legend tag, and to a
specific table, identified by either id or text of the table's caption tag.
@@ -794,7 +794,7 @@ end
Capybara makes it convenient to switch between different drivers. It also exposes
an API to tweak those drivers with whatever settings you want, or to add your own
-drivers. This is how to switch the selenium driver to use chrome:
+drivers. This is how to override the selenium driver configuration to use chrome:
```ruby
Capybara.register_driver :selenium do |app|
@@ -802,8 +802,7 @@ Capybara.register_driver :selenium do |app|
end
```
-However, it's also possible to give this a different name, so tests can switch
-between using different browsers effortlessly:
+However, it's also possible to give this configuration a different name.
```ruby
Capybara.register_driver :selenium_chrome do |app|
@@ -811,6 +810,11 @@ Capybara.register_driver :selenium_chrome do |app|
end
```
+Then tests can switch between using different browsers effortlessly:
+```ruby
+Capybara.current_driver = :selenium_chrome
+```
+
Whatever is returned from the block should conform to the API described by
Capybara::Driver::Base, it does not however have to inherit from this class.
Gems can use this API to add their own drivers to Capybara.
diff --git a/checksums.yaml.gz b/checksums.yaml.gz
new file mode 100644
index 0000000..b8fd3c6
Binary files /dev/null and b/checksums.yaml.gz differ
diff --git a/checksums.yaml.gz.sig b/checksums.yaml.gz.sig
new file mode 100644
index 0000000..61201be
Binary files /dev/null and b/checksums.yaml.gz.sig differ
diff --git a/data.tar.gz.sig b/data.tar.gz.sig
index e6c7bc3..979d6ce 100644
Binary files a/data.tar.gz.sig and b/data.tar.gz.sig differ
diff --git a/lib/capybara.rb b/lib/capybara.rb
index 5ec55ce..efa2545 100644
--- a/lib/capybara.rb
+++ b/lib/capybara.rb
@@ -16,10 +16,10 @@ module Capybara
class << self
attr_accessor :asset_host, :app_host, :run_server, :default_host, :always_include_port
- attr_accessor :server_host, :server_port, :exact, :match, :exact_options, :visible_text_only
+ attr_accessor :server_port, :exact, :match, :exact_options, :visible_text_only
attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements
attr_accessor :save_and_open_page_path, :automatic_reload, :raise_server_errors
- attr_writer :default_driver, :current_driver, :javascript_driver, :session_name
+ attr_writer :default_driver, :current_driver, :javascript_driver, :session_name, :server_host
attr_accessor :app
##
@@ -166,7 +166,7 @@ module Capybara
#
def run_default_server(app, port)
require 'rack/handler/webrick'
- Rack::Handler::WEBrick.run(app, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0))
+ Rack::Handler::WEBrick.run(app, :Host => server_host, :Port => port, :AccessLog => [], :Logger => WEBrick::Log::new(nil, 0))
end
##
@@ -216,6 +216,14 @@ module Capybara
##
#
+ # @return [String] The IP address bound by default server
+ #
+ def server_host
+ @server_host || '127.0.0.1'
+ end
+
+ ##
+ #
# Yield a block using a specific wait time
#
def using_wait_time(seconds)
@@ -267,6 +275,21 @@ module Capybara
self.session_name = :default
end
+ ##
+ #
+ # Parse raw html into a document using Nokogiri, and adjust textarea contents as defined by the spec.
+ #
+ # @param [String] html The raw html
+ # @return [Nokogiri::HTML::Document] HTML document
+ #
+ def HTML(html)
+ Nokogiri::HTML(html).tap do |document|
+ document.xpath('//textarea').each do |textarea|
+ textarea.content=textarea.content.sub(/\A\n/,'')
+ end
+ end
+ end
+
def included(base)
base.send(:include, Capybara::DSL)
warn "`include Capybara` is deprecated. Please use `include Capybara::DSL` instead."
diff --git a/lib/capybara/cucumber.rb b/lib/capybara/cucumber.rb
index c8c470d..7923d26 100644
--- a/lib/capybara/cucumber.rb
+++ b/lib/capybara/cucumber.rb
@@ -1,6 +1,4 @@
require 'capybara'
-
-require 'capybara/dsl'
require 'capybara/rspec/matchers'
World(Capybara::DSL)
diff --git a/lib/capybara/driver/base.rb b/lib/capybara/driver/base.rb
index 414fc44..9fd20d0 100644
--- a/lib/capybara/driver/base.rb
+++ b/lib/capybara/driver/base.rb
@@ -10,7 +10,7 @@ class Capybara::Driver::Base
def find_xpath(query)
raise NotImplementedError
end
-
+
def find_css(query)
raise NotImplementedError
end
@@ -19,6 +19,14 @@ class Capybara::Driver::Base
raise NotImplementedError
end
+ def go_back
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#go_back'
+ end
+
+ def go_forward
+ raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#go_forward'
+ end
+
def execute_script(script)
raise Capybara::NotSupportedByDriverError, 'Capybara::Driver::Base#execute_script'
end
diff --git a/lib/capybara/node/actions.rb b/lib/capybara/node/actions.rb
index 00a0bde..b29d3b2 100644
--- a/lib/capybara/node/actions.rb
+++ b/lib/capybara/node/actions.rb
@@ -19,7 +19,7 @@ module Capybara
# Finds a link by id or text and clicks it. Also looks at image
# alt text inside the link.
#
- # @param [String] locator Text, id or text of link
+ # @param [String] locator Text or id of link
# @param options
# @option options [String] :href The value the href attribute must be
#
diff --git a/lib/capybara/node/finders.rb b/lib/capybara/node/finders.rb
index 7eb22e7..a47b3e2 100644
--- a/lib/capybara/node/finders.rb
+++ b/lib/capybara/node/finders.rb
@@ -147,16 +147,16 @@ module Capybara
private
def resolve_query(query, exact=nil)
- elements = synchronize do
- if query.selector.format==:css
+ synchronize do
+ elements = if query.selector.format==:css
base.find_css(query.css)
else
base.find_xpath(query.xpath(exact))
end.map do |node|
Capybara::Node::Element.new(session, node, self, query)
end
+ Capybara::Result.new(elements, query)
end
- Capybara::Result.new(elements, query)
end
end
end
diff --git a/lib/capybara/node/matchers.rb b/lib/capybara/node/matchers.rb
index 3a6c312..4975a2a 100644
--- a/lib/capybara/node/matchers.rb
+++ b/lib/capybara/node/matchers.rb
@@ -85,7 +85,8 @@ module Capybara
# @raise [Capybara::ExpectationNotMet] If the selector does not exist
#
def assert_selector(*args)
- synchronize do
+ query = Capybara::Query.new(*args)
+ synchronize(query.wait) do
result = all(*args)
result.matches_count? or raise Capybara::ExpectationNotMet, result.failure_message
end
@@ -101,7 +102,8 @@ module Capybara
# @raise [Capybara::ExpectationNotMet] If the selector exists
#
def assert_no_selector(*args)
- synchronize do
+ query = Capybara::Query.new(*args)
+ synchronize(query.wait) do
result = all(*args)
result.matches_count? and raise Capybara::ExpectationNotMet, result.negative_failure_message
end
@@ -215,7 +217,8 @@ module Capybara
# @return [Boolean] Whether it exists
#
def has_text?(*args)
- synchronize do
+ query = Capybara::Query.new(*args)
+ synchronize(query.wait) do
raise ExpectationNotMet unless text_found?(*args)
end
return true
@@ -233,7 +236,8 @@ module Capybara
# @return [Boolean] Whether it doesn't exist
#
def has_no_text?(*args)
- synchronize do
+ query = Capybara::Query.new(*args)
+ synchronize(query.wait) do
raise ExpectationNotMet if text_found?(*args)
end
return true
@@ -276,8 +280,8 @@ module Capybara
# @param [String] locator The text, value or id of a button to check for
# @return [Boolean] Whether it exists
#
- def has_button?(locator)
- has_selector?(:button, locator)
+ def has_button?(locator, options={})
+ has_selector?(:button, locator, options)
end
##
@@ -288,8 +292,8 @@ module Capybara
# @param [String] locator The text, value or id of a button to check for
# @return [Boolean] Whether it doesn't exist
#
- def has_no_button?(locator)
- has_no_selector?(:button, locator)
+ def has_no_button?(locator, options={})
+ has_no_selector?(:button, locator, options)
end
##
@@ -341,8 +345,8 @@ module Capybara
# @param [String] locator The label, name or id of a checked field
# @return [Boolean] Whether it exists
#
- def has_checked_field?(locator)
- has_selector?(:field, locator, :checked => true)
+ def has_checked_field?(locator, options={})
+ has_selector?(:field, locator, options.merge(:checked => true))
end
##
@@ -352,10 +356,10 @@ module Capybara
# checked.
#
# @param [String] locator The label, name or id of a checked field
- # @return [Boolean] Whether it doesn't exists
+ # @return [Boolean] Whether it doesn't exist
#
- def has_no_checked_field?(locator)
- has_no_selector?(:field, locator, :checked => true)
+ def has_no_checked_field?(locator, options={})
+ has_no_selector?(:field, locator, options.merge(:checked => true))
end
##
@@ -367,8 +371,8 @@ module Capybara
# @param [String] locator The label, name or id of an unchecked field
# @return [Boolean] Whether it exists
#
- def has_unchecked_field?(locator)
- has_selector?(:field, locator, :unchecked => true)
+ def has_unchecked_field?(locator, options={})
+ has_selector?(:field, locator, options.merge(:unchecked => true))
end
##
@@ -378,10 +382,10 @@ module Capybara
# unchecked.
#
# @param [String] locator The label, name or id of an unchecked field
- # @return [Boolean] Whether it doesn't exists
+ # @return [Boolean] Whether it doesn't exist
#
- def has_no_unchecked_field?(locator)
- has_no_selector?(:field, locator, :unchecked => true)
+ def has_no_unchecked_field?(locator, options={})
+ has_no_selector?(:field, locator, options.merge(:unchecked => true))
end
##
diff --git a/lib/capybara/node/simple.rb b/lib/capybara/node/simple.rb
index 4e4b6c9..d55b410 100644
--- a/lib/capybara/node/simple.rb
+++ b/lib/capybara/node/simple.rb
@@ -18,7 +18,7 @@ module Capybara
attr_reader :native
def initialize(native)
- native = Nokogiri::HTML(native) if native.is_a?(String)
+ native = Capybara::HTML(native) if native.is_a?(String)
@native = native
end
@@ -74,7 +74,7 @@ module Capybara
#
def value
if tag_name == 'textarea'
- native.content.sub(/\A\n/, '')
+ native.content
elsif tag_name == 'select'
if native['multiple'] == 'multiple'
native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content }
@@ -82,6 +82,8 @@ module Capybara
option = native.xpath(".//option[@selected='selected']").first || native.xpath(".//option").first
option[:value] || option.content if option
end
+ elsif tag_name == 'input' && %w(radio checkbox).include?(native[:type])
+ native[:value] || 'on'
else
native[:value]
end
@@ -95,7 +97,7 @@ module Capybara
# @return [Boolean] Whether the element is visible
#
def visible?
- native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or name()='script' or name()='head']").size == 0
+ native.xpath("./ancestor-or-self::*[contains(@style, 'display:none') or contains(@style, 'display: none') or @hidden or name()='script' or name()='head']").size == 0
end
##
diff --git a/lib/capybara/query.rb b/lib/capybara/query.rb
index 17abd1c..21eb933 100644
--- a/lib/capybara/query.rb
+++ b/lib/capybara/query.rb
@@ -32,6 +32,7 @@ module Capybara
def description
@description = "#{label} #{locator.inspect}"
@description << " with text #{options[:text].inspect}" if options[:text]
+ @description << " with value #{options[:with].inspect}" if options[:with]
@description
end
diff --git a/lib/capybara/rack_test/browser.rb b/lib/capybara/rack_test/browser.rb
index 5c92df8..128c353 100644
--- a/lib/capybara/rack_test/browser.rb
+++ b/lib/capybara/rack_test/browser.rb
@@ -46,6 +46,7 @@ class Capybara::RackTest::Browser
method.downcase! unless method.is_a? Symbol
new_uri.path = request_path if path.start_with?("?")
+ new_uri.path = "/" if new_uri.path.empty?
new_uri.path = request_path.sub(%r(/[^/]*$), '/') + new_uri.path unless new_uri.path.start_with?('/')
new_uri.scheme ||= @current_scheme
new_uri.host ||= @current_host
@@ -77,7 +78,7 @@ class Capybara::RackTest::Browser
end
def dom
- @dom ||= Nokogiri::HTML(html)
+ @dom ||= Capybara::HTML(html)
end
def find(format, selector)
@@ -93,11 +94,11 @@ class Capybara::RackTest::Browser
rescue Rack::Test::Error
""
end
-
+
def title
dom.xpath("//title").text
end
-
+
protected
def build_rack_mock_session
@@ -108,6 +109,6 @@ protected
def request_path
last_request.path
rescue Rack::Test::Error
- ""
+ "/"
end
end
diff --git a/lib/capybara/rack_test/form.rb b/lib/capybara/rack_test/form.rb
index 5525493..31c55ae 100644
--- a/lib/capybara/rack_test/form.rb
+++ b/lib/capybara/rack_test/form.rb
@@ -28,7 +28,10 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
case field.name
when 'input'
if %w(radio checkbox).include? field['type']
- merge_param!(params, field['name'].to_s, field['value'].to_s) if field['checked']
+ if field['checked']
+ node=Capybara::RackTest::Node.new(self.driver, field)
+ merge_param!(params, field['name'].to_s, node.value.to_s)
+ end
elsif %w(submit image).include? field['type']
# TO DO identify the click button here (in document order, rather
# than leaving until the end of the params)
@@ -60,7 +63,7 @@ class Capybara::RackTest::Form < Capybara::RackTest::Node
merge_param!(params, field['name'].to_s, (option['value'] || option.text).to_s) if option
end
when 'textarea'
- merge_param!(params, field['name'].to_s, field.text.to_s)
+ merge_param!(params, field['name'].to_s, field.text.to_s.gsub(/\n/, "\r\n"))
end
end
merge_param!(params, button[:name], button[:value] || "") if button[:name]
diff --git a/lib/capybara/rack_test/node.rb b/lib/capybara/rack_test/node.rb
index ac4320e..37ea24a 100644
--- a/lib/capybara/rack_test/node.rb
+++ b/lib/capybara/rack_test/node.rb
@@ -52,7 +52,8 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
driver.follow(method, self[:href].to_s)
elsif (tag_name == 'input' and %w(submit image).include?(type)) or
((tag_name == 'button') and type.nil? or type == "submit")
- Capybara::RackTest::Form.new(driver, form).submit(self)
+ associated_form = form
+ Capybara::RackTest::Form.new(driver, associated_form).submit(self) if associated_form
end
end
diff --git a/lib/capybara/result.rb b/lib/capybara/result.rb
index 0dc4340..bd4dac1 100644
--- a/lib/capybara/result.rb
+++ b/lib/capybara/result.rb
@@ -29,7 +29,8 @@ module Capybara
@query = query
end
- def_delegators :@result, :each, :[], :at, :size, :count, :length, :first, :last, :empty?
+ def_delegators :@result, :each, :[], :at, :size, :count, :length,
+ :first, :last, :values_at, :empty?, :inspect, :sample, :index
def matches_count?
Capybara::Helpers.matches_count?(@result.size, @query.options)
diff --git a/lib/capybara/rspec.rb b/lib/capybara/rspec.rb
index 1a91765..f3bc2ca 100644
--- a/lib/capybara/rspec.rb
+++ b/lib/capybara/rspec.rb
@@ -7,6 +7,12 @@ require 'capybara/rspec/features'
RSpec.configure do |config|
config.include Capybara::DSL, :type => :feature
config.include Capybara::RSpecMatchers, :type => :feature
+
+ # A work-around to support accessing the current example that works in both
+ # RSpec 2 and RSpec 3.
+ fetch_current_example = RSpec.respond_to?(:current_example) ?
+ proc { RSpec.current_example } : proc { |context| context.example }
+
# The before and after blocks must run instantaneously, because Capybara
# might not actually be used in all examples where it's included.
config.after do
@@ -17,6 +23,7 @@ RSpec.configure do |config|
end
config.before do
if self.class.include?(Capybara::DSL)
+ example = fetch_current_example.call(self)
Capybara.current_driver = Capybara.javascript_driver if example.metadata[:js]
Capybara.current_driver = example.metadata[:driver] if example.metadata[:driver]
end
diff --git a/lib/capybara/rspec/features.rb b/lib/capybara/rspec/features.rb
index 9b81aab..bb5e1e1 100644
--- a/lib/capybara/rspec/features.rb
+++ b/lib/capybara/rspec/features.rb
@@ -7,11 +7,13 @@ module Capybara
alias :xscenario :xit
alias :given :let
alias :given! :let!
+ alias :feature :describe
end
end
end
end
+
def self.feature(*args, &block)
options = if args.last.is_a?(Hash) then args.pop else {} end
options[:capybara_feature] = true
diff --git a/lib/capybara/rspec/matchers.rb b/lib/capybara/rspec/matchers.rb
index 4267acc..b6529cf 100644
--- a/lib/capybara/rspec/matchers.rb
+++ b/lib/capybara/rspec/matchers.rb
@@ -126,20 +126,20 @@ module Capybara
HaveSelector.new(:link, locator, options)
end
- def have_button(locator)
- HaveSelector.new(:button, locator)
+ def have_button(locator, options={})
+ HaveSelector.new(:button, locator, options)
end
def have_field(locator, options={})
HaveSelector.new(:field, locator, options)
end
- def have_checked_field(locator)
- HaveSelector.new(:field, locator, :checked => true)
+ def have_checked_field(locator, options={})
+ HaveSelector.new(:field, locator, options.merge(:checked => true))
end
- def have_unchecked_field(locator)
- HaveSelector.new(:field, locator, :unchecked => true)
+ def have_unchecked_field(locator, options={})
+ HaveSelector.new(:field, locator, options.merge(:unchecked => true))
end
def have_select(locator, options={})
diff --git a/lib/capybara/selector.rb b/lib/capybara/selector.rb
index a1b2572..d6e51f5 100644
--- a/lib/capybara/selector.rb
+++ b/lib/capybara/selector.rb
@@ -103,7 +103,7 @@ Capybara.add_selector(:field) do
filter(:checked) { |node, value| not(value ^ node.checked?) }
filter(:unchecked) { |node, value| (value ^ node.checked?) }
filter(:disabled, :default => false) { |node, value| not(value ^ node.disabled?) }
- filter(:with) { |node, with| node.value == with }
+ filter(:with) { |node, with| node.value == with.to_s }
filter(:type) do |node, type|
if ['textarea', 'select'].include?(type)
node.tag_name == type
@@ -146,6 +146,7 @@ Capybara.add_selector(:radio_button) do
xpath { |locator| XPath::HTML.radio_button(locator) }
filter(:checked) { |node, value| not(value ^ node.checked?) }
filter(:unchecked) { |node, value| (value ^ node.checked?) }
+ filter(:option) { |node, value| node.value == value.to_s }
filter(:disabled, :default => false) { |node, value| not(value ^ node.disabled?) }
end
@@ -153,6 +154,7 @@ Capybara.add_selector(:checkbox) do
xpath { |locator| XPath::HTML.checkbox(locator) }
filter(:checked) { |node, value| not(value ^ node.checked?) }
filter(:unchecked) { |node, value| (value ^ node.checked?) }
+ filter(:option) { |node, value| node.value == value.to_s }
filter(:disabled, :default => false) { |node, value| not(value ^ node.disabled?) }
end
diff --git a/lib/capybara/selenium/driver.rb b/lib/capybara/selenium/driver.rb
index 9941eea..ddf3552 100644
--- a/lib/capybara/selenium/driver.rb
+++ b/lib/capybara/selenium/driver.rb
@@ -1,3 +1,5 @@
+require "uri"
+
class Capybara::Selenium::Driver < Capybara::Driver::Base
DEFAULT_OPTIONS = {
:browser => :firefox
@@ -43,6 +45,14 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
browser.navigate.to(path)
end
+ def go_back
+ browser.navigate.back
+ end
+
+ def go_forward
+ browser.navigate.forward
+ end
+
def html
browser.page_source
end
@@ -87,7 +97,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
# to about:blank, so we rescue this error and do nothing
# instead.
end
- @browser.navigate.to('about:blank')
+ @browser.navigate.to("about:blank")
end
end
@@ -137,7 +147,7 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
end
def quit
- @browser.quit
+ @browser.quit if @browser
rescue Errno::ECONNREFUSED
# Browser must have already gone
end
diff --git a/lib/capybara/selenium/node.rb b/lib/capybara/selenium/node.rb
index 1de5bbe..cb96774 100644
--- a/lib/capybara/selenium/node.rb
+++ b/lib/capybara/selenium/node.rb
@@ -37,8 +37,21 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
path_names = value.to_s.empty? ? [] : value
native.send_keys(*path_names)
elsif tag_name == 'textarea' or tag_name == 'input'
- #script can change a readonly element which user input cannot, so dont execute if readonly
- driver.browser.execute_script "arguments[0].value = ''", native unless self[:readonly]
+ if value.to_s.empty?
+ native.clear
+ else
+ #script can change a readonly element which user input cannot, so dont execute if readonly
+ driver.browser.execute_script "arguments[0].value = ''", native unless self[:readonly]
+ native.send_keys(value.to_s)
+ end
+ elsif native.attribute('isContentEditable')
+ #ensure we are focused on the element
+ script = <<-JS
+ var range = document.createRange();
+ range.selectNodeContents(arguments[0]);
+ window.getSelection().addRange(range);
+ JS
+ driver.browser.execute_script script, native
native.send_keys(value.to_s)
end
end
@@ -61,7 +74,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
def hover
driver.browser.action.move_to(native).perform
end
-
+
def drag_to(element)
driver.browser.action.drag_and_drop(native, element.native).perform
end
@@ -89,11 +102,11 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
def find_xpath(locator)
native.find_elements(:xpath, locator).map { |n| self.class.new(driver, n) }
end
-
+
def find_css(locator)
native.find_elements(:css, locator).map { |n| self.class.new(driver, n) }
end
-
+
def ==(other)
native == other.native
end
diff --git a/lib/capybara/server.rb b/lib/capybara/server.rb
index e5182e5..efd52f0 100644
--- a/lib/capybara/server.rb
+++ b/lib/capybara/server.rb
@@ -31,13 +31,13 @@ module Capybara
end
end
- attr_reader :app, :port
+ attr_reader :app, :port, :host
- def initialize(app, port=Capybara.server_port)
+ def initialize(app, port=Capybara.server_port, host=Capybara.server_host)
@app = app
@middleware = Middleware.new(@app)
@server_thread = nil # supress warnings
- @port = port
+ @host, @port = host, port
@port ||= Capybara::Server.ports[@app.object_id]
@port ||= find_available_port
end
@@ -50,10 +50,6 @@ module Capybara
@middleware.error
end
- def host
- Capybara.server_host || "127.0.0.1"
- end
-
def responsive?
return false if @server_thread && @server_thread.join(0)
diff --git a/lib/capybara/session.rb b/lib/capybara/session.rb
index 933addd..6860135 100644
--- a/lib/capybara/session.rb
+++ b/lib/capybara/session.rb
@@ -37,10 +37,11 @@ module Capybara
:has_no_unchecked_field?, :query, :assert_selector, :assert_no_selector
]
SESSION_METHODS = [
- :body, :html, :current_url, :current_host, :evaluate_script, :source,
- :visit, :within, :within_fieldset, :within_table, :within_frame,
- :within_window, :current_path, :save_page, :save_and_open_page,
- :save_screenshot, :reset_session!, :response_headers, :status_code,
+ :body, :html, :source, :current_url, :current_host, :current_path,
+ :execute_script, :evaluate_script, :visit, :go_back, :go_forward,
+ :within, :within_fieldset, :within_table, :within_frame, :within_window,
+ :save_page, :save_and_open_page, :save_screenshot,
+ :reset_session!, :response_headers, :status_code,
:title, :has_title?, :has_no_title?, :current_scope
]
DSL_METHODS = NODE_METHODS + SESSION_METHODS
@@ -74,8 +75,11 @@ module Capybara
# Reset the session, removing all cookies.
#
def reset!
- driver.reset! if @touched
- @touched = false
+ if @touched
+ driver.reset!
+ @touched = false
+ assert_no_selector :xpath, "/html/body/*"
+ end
raise @server.error if Capybara.raise_server_errors and @server and @server.error
ensure
@server.reset_error! if @server
@@ -195,27 +199,54 @@ module Capybara
##
#
- # Execute the given block for a particular scope on the page. Within will find the first
- # element matching the given selector and execute the block scoped to that element:
+ # Move back a single entry in the browser's history.
+ #
+ def go_back
+ driver.go_back
+ end
+
+ ##
+ #
+ # Move forward a single entry in the browser's history.
+ #
+ def go_forward
+ driver.go_forward
+ end
+
+ ##
+ #
+ # Executes the given block within the context of a node. `within` takes the
+ # same options as `find`, as well as a block. For the duration of the
+ # block, any command to Capybara will be handled as though it were scoped
+ # to the given element.
#
# within(:xpath, '//div[@id="delivery-address"]') do
# fill_in('Street', :with => '12 Main Street')
# end
#
- # It is possible to omit the first parameter, in that case, the selector is assumed to be
- # of the type set in Capybara.default_selector.
+ # Just as with `find`, if multiple elements match the selector given to
+ # `within`, an error will be raised, and just as with `find`, this
+ # behaviour can be controlled through the `:match` and `:exact` options.
+ #
+ # It is possible to omit the first parameter, in that case, the selector is
+ # assumed to be of the type set in Capybara.default_selector.
#
# within('div#delivery-address') do
# fill_in('Street', :with => '12 Main Street')
# end
#
+ # Note that a lot of uses of `within` can be replaced more succinctly with
+ # chaining:
+ #
+ # find('div#delivery-address').fill_in('Street', :with => '12 Main Street')
+ #
# @overload within(*find_args)
# @param (see Capybara::Node::Finders#all)
#
# @overload within(a_node)
# @param [Capybara::Node::Base] a_node The node in whose scope the block should be evaluated
#
- # @raise [Capybara::ElementNotFound] If the scope can't be found before time expires
+ # @raise [Capybara::ElementNotFound] If the scope can't be found before time expires
#
def within(*args)
new_scope = if args.first.is_a?(Capybara::Node::Base) then args.first else find(*args) end
@@ -262,9 +293,12 @@ module Capybara
# @param [String] name name of a frame
#
def within_frame(frame_handle)
+ scopes.push(nil)
driver.within_frame(frame_handle) do
yield
end
+ ensure
+ scopes.pop
end
##
@@ -275,7 +309,10 @@ module Capybara
# @param [String] handle of the window
#
def within_window(handle, &blk)
+ scopes.push(nil)
driver.within_window(handle, &blk)
+ ensure
+ scopes.pop
end
##
@@ -313,7 +350,7 @@ module Capybara
#
def save_page(path=nil)
path ||= "capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}#{rand(10**10)}.html"
- path = File.expand_path(path, Capybara.save_and_open_page_path) if Capybara.save_and_open_page_path
+ path = File.expand_path(path, Capybara.save_and_open_page_path)
FileUtils.mkdir_p(File.dirname(path))
@@ -328,10 +365,15 @@ module Capybara
# @param [String] file_name The path to where it should be saved [optional]
#
def save_and_open_page(file_name=nil)
- require "launchy"
- Launchy.open(save_page(file_name))
- rescue LoadError
- warn "Please install the launchy gem to open page with save_and_open_page"
+ file_name = save_page(file_name)
+
+ begin
+ require "launchy"
+ Launchy.open(file_name)
+ rescue LoadError
+ warn "Page saved to #{file_name} with save_and_open_page."
+ warn "Please install the launchy gem to open page automatically."
+ end
end
##
@@ -382,7 +424,7 @@ module Capybara
end
def current_scope
- scopes.last
+ scopes.last || document
end
private
diff --git a/lib/capybara/spec/public/test.js b/lib/capybara/spec/public/test.js
index 5980e6d..b55b8c9 100644
--- a/lib/capybara/spec/public/test.js
+++ b/lib/capybara/spec/public/test.js
@@ -35,7 +35,7 @@ $(function() {
$('body').append('<p id="focus_event_triggered">Focus Event triggered</p>');
});
$('#with_change_event').change(function() {
- if($(this).val() == '') $(this).val("Can't be empty");
+ $('body').append($('<p class="change_event_triggered"></p>').text(this.value));
});
$('#checkbox_with_event').click(function() {
$('body').append('<p id="checkbox_event_triggered">Checkbox event triggered</p>');
diff --git a/lib/capybara/spec/session/assert_selector.rb b/lib/capybara/spec/session/assert_selector.rb
index f34d04b..4274d5a 100644
--- a/lib/capybara/spec/session/assert_selector.rb
+++ b/lib/capybara/spec/session/assert_selector.rb
@@ -58,6 +58,16 @@ Capybara::SpecHelper.spec '#assert_selector' do
expect { @session.assert_selector("//p//a", :text => /Red$/) }.to raise_error(Capybara::ElementNotFound)
end
end
+
+ context "with wait", :requires => [:js] do
+ it "should find element if it appears before given wait duration" do
+ Capybara.using_wait_time(0.1) do
+ @session.visit('/with_js')
+ @session.click_link('Click me')
+ @session.assert_selector(:css, "a#has-been-clicked", :text => "Has been clicked", :wait => 0.9)
+ end
+ end
+ end
end
Capybara::SpecHelper.spec '#assert_no_selector' do
@@ -120,4 +130,12 @@ Capybara::SpecHelper.spec '#assert_no_selector' do
@session.assert_no_selector("//p//a", :text => /Red$/)
end
end
+
+ context "with wait", :requires => [:js] do
+ it "should not find element if it appears after given wait duration" do
+ @session.visit('/with_js')
+ @session.click_link('Click me')
+ @session.assert_no_selector(:css, "a#has-been-clicked", :text => "Has been clicked", :wait => 0.1)
+ end
+ end
end
diff --git a/lib/capybara/spec/session/attach_file_spec.rb b/lib/capybara/spec/session/attach_file_spec.rb
index 4aa5841..ab8bb34 100644
--- a/lib/capybara/spec/session/attach_file_spec.rb
+++ b/lib/capybara/spec/session/attach_file_spec.rb
@@ -64,13 +64,18 @@ Capybara::SpecHelper.spec "#attach_file" do
end
it "should not break when using HTML5 multiple file input uploading multiple files" do
- pending "Selenium is buggy on this, see http://code.google.com/p/selenium/issues/detail?id=2239" if @session.respond_to?(:mode) && @session.mode == :selenium
+ pending "Selenium is buggy on this, see http://code.google.com/p/selenium/issues/detail?id=2239" if @session.respond_to?(:mode) && @session.mode.to_s =~ /^selenium/
@session.attach_file "Multiple Documents", [@test_file_path, @another_test_file_path]
@session.click_button('Upload Multiple')
@session.body.should include("2 | ")#number of files
@session.body.should include(File.read(@test_file_path))
@session.body.should include(File.read(@another_test_file_path))
end
+
+ it "should not send anything when attaching no files to a multiple upload field" do
+ @session.click_button('Upload Empty Multiple')
+ @session.body.should include("Successfully ignored empty file field")
+ end
end
context "with a locator that doesn't exist" do
diff --git a/lib/capybara/spec/session/check_spec.rb b/lib/capybara/spec/session/check_spec.rb
index 18b2cc6..30d38fb 100644
--- a/lib/capybara/spec/session/check_spec.rb
+++ b/lib/capybara/spec/session/check_spec.rb
@@ -96,4 +96,18 @@ Capybara::SpecHelper.spec "#check" do
end.to raise_error(Capybara::ElementNotFound)
end
end
+
+ context "with `option` option" do
+ it "can check boxes by their value" do
+ @session.check('form[pets][]', :option => "cat")
+ @session.click_button('awesome')
+ extract_results(@session)['pets'].should include('cat')
+ end
+
+ it "should raise an error if option not found" do
+ expect do
+ @session.check('form[pets][]', :option => "elephant")
+ end.to raise_error(Capybara::ElementNotFound)
+ end
+ end
end
diff --git a/lib/capybara/spec/session/choose_spec.rb b/lib/capybara/spec/session/choose_spec.rb
index ce471c3..8cbf77d 100644
--- a/lib/capybara/spec/session/choose_spec.rb
+++ b/lib/capybara/spec/session/choose_spec.rb
@@ -51,4 +51,18 @@ Capybara::SpecHelper.spec "#choose" do
end.to raise_error(Capybara::ElementNotFound)
end
end
+
+ context "with `option` option" do
+ it "can check radio buttons by their value" do
+ @session.choose('form[gender]', :option => "male")
+ @session.click_button('awesome')
+ extract_results(@session)['gender'].should == "male"
+ end
+
+ it "should raise an error if option not found" do
+ expect do
+ @session.choose('form[gender]', :option => "hermaphrodite")
+ end.to raise_error(Capybara::ElementNotFound)
+ end
+ end
end
diff --git a/lib/capybara/spec/session/click_button_spec.rb b/lib/capybara/spec/session/click_button_spec.rb
index 5b6c13e..bc979a7 100644
--- a/lib/capybara/spec/session/click_button_spec.rb
+++ b/lib/capybara/spec/session/click_button_spec.rb
@@ -102,10 +102,18 @@ Capybara::SpecHelper.spec '#click_button' do
@results['gender'].should == 'female'
end
+ it "should default radio value to 'on' if none specified" do
+ @results['valueless_radio'].should == 'on'
+ end
+
it "should serialize check boxes" do
@results['pets'].should include('dog', 'hamster')
@results['pets'].should_not include('cat')
end
+
+ it "should default checkbox value to 'on' if none specififed" do
+ @results['valueless_checkbox'].should == 'on'
+ end
it "should serialize text areas" do
@results['description'].should == 'Descriptive text goes here'
@@ -126,7 +134,11 @@ Capybara::SpecHelper.spec '#click_button' do
it "should not serialize a select tag without options" do
@results['tendency'].should be_nil
end
-
+
+ it "should convert lf to cr/lf in submitted textareas" do
+ @results['newline'].should == "\r\nNew line after and before textarea tag\r\n"
+ end
+
it "should not submit disabled fields" do
@results['disabled_text_field'].should be_nil
@results['disabled_textarea'].should be_nil
@@ -225,6 +237,12 @@ Capybara::SpecHelper.spec '#click_button' do
end
end
+ context "with submit button not associated with any form" do
+ it "should not error when clicked" do
+ lambda { @session.click_button('no_form_button') }.should_not raise_error
+ end
+ end
+
context "with alt given on an image button" do
it "should submit the associated form" do
@session.click_button('oh hai thar')
@@ -236,6 +254,7 @@ Capybara::SpecHelper.spec '#click_button' do
extract_results(@session)['first_name'].should == 'John'
end
end
+
context "with value given on an image button" do
it "should submit the associated form" do
diff --git a/lib/capybara/spec/session/fill_in_spec.rb b/lib/capybara/spec/session/fill_in_spec.rb
index 4b8eda8..5b2daab 100644
--- a/lib/capybara/spec/session/fill_in_spec.rb
+++ b/lib/capybara/spec/session/fill_in_spec.rb
@@ -57,6 +57,12 @@ Capybara::SpecHelper.spec "#fill_in" do
extract_results(@session)['description'].should == 'is <strong>very</strong> secret!'
end
+ it "should handle newlines in a textarea" do
+ @session.fill_in('form_description', :with => "\nSome text\n")
+ @session.click_button('awesome')
+ extract_results(@session)['description'].should == "\r\nSome text\r\n"
+ end
+
it "should fill in a field with a custom type" do
@session.fill_in('Schmooo', :with => 'Schmooo is the game')
@session.click_button('awesome')
@@ -109,7 +115,7 @@ Capybara::SpecHelper.spec "#fill_in" do
extract_results(@session)['first_name'].should == 'Harry'
end
- it "casts to string if field has maxlength", :focus => true do
+ it "casts to string if field has maxlength" do
@session.fill_in(:'form_zipcode', :with => 1234567)
@session.click_button('awesome')
extract_results(@session)['zipcode'].should == '12345'
@@ -119,7 +125,17 @@ Capybara::SpecHelper.spec "#fill_in" do
it 'should only trigger onchange once' do
@session.visit('/with_js')
@session.fill_in('with_change_event', :with => 'some value')
- @session.find(:css, '#with_change_event').value.should == 'some value'
+ # click outside the field to trigger the change event
+ @session.find(:css, 'body').click
+ @session.find(:css, '.change_event_triggered', :match => :one).should have_text 'some value'
+ end
+
+ it 'should trigger change when clearing field' do
+ @session.visit('/with_js')
+ @session.fill_in('with_change_event', :with => '')
+ # click outside the field to trigger the change event
+ @session.find(:css, 'body').click
+ @session.should have_selector(:css, '.change_event_triggered', :match => :one)
end
end
diff --git a/lib/capybara/spec/session/go_back_spec.rb b/lib/capybara/spec/session/go_back_spec.rb
new file mode 100644
index 0000000..1debd40
--- /dev/null
+++ b/lib/capybara/spec/session/go_back_spec.rb
@@ -0,0 +1,10 @@
+Capybara::SpecHelper.spec '#go_back', :requires => [:js] do
+ it "should fetch a response from the driver from the previous page" do
+ @session.visit('/')
+ @session.should have_content('Hello world!')
+ @session.visit('/foo')
+ @session.should have_content('Another World')
+ @session.go_back
+ @session.should have_content('Hello world!')
+ end
+end
diff --git a/lib/capybara/spec/session/go_forward_spec.rb b/lib/capybara/spec/session/go_forward_spec.rb
new file mode 100644
index 0000000..2314ef4
--- /dev/null
+++ b/lib/capybara/spec/session/go_forward_spec.rb
@@ -0,0 +1,12 @@
+Capybara::SpecHelper.spec '#go_forward', :requires => [:js] do
+ it "should fetch a response from the driver from the previous page" do
+ @session.visit('/')
+ @session.should have_content('Hello world!')
+ @session.visit('/foo')
+ @session.should have_content('Another World')
+ @session.go_back
+ @session.should have_content('Hello world!')
+ @session.go_forward
+ @session.should have_content('Another World')
+ end
+end
diff --git a/lib/capybara/spec/session/has_button_spec.rb b/lib/capybara/spec/session/has_button_spec.rb
index d1ba42b..8c5338e 100644
--- a/lib/capybara/spec/session/has_button_spec.rb
+++ b/lib/capybara/spec/session/has_button_spec.rb
@@ -9,9 +9,21 @@ Capybara::SpecHelper.spec '#has_button?' do
@session.should have_button(:'crap321')
end
+ it "should be true for disabled buttons if :disabled => true" do
+ @session.should have_button('Disabled button', :disabled => true)
+ end
+
it "should be false if the given button is not on the page" do
@session.should_not have_button('monkey')
end
+
+ it "should be false for disabled buttons by default" do
+ @session.should_not have_button('Disabled button')
+ end
+
+ it "should be false for disabled buttons if :disabled => false" do
+ @session.should_not have_button('Disabled button', :disabled => false)
+ end
end
Capybara::SpecHelper.spec '#has_no_button?' do
@@ -24,7 +36,19 @@ Capybara::SpecHelper.spec '#has_no_button?' do
@session.should_not have_no_button('crap321')
end
+ it "should be true for disabled buttons if :disabled => true" do
+ @session.should_not have_no_button('Disabled button', :disabled => true)
+ end
+
it "should be false if the given button is not on the page" do
@session.should have_no_button('monkey')
end
+
+ it "should be false for disabled buttons by default" do
+ @session.should have_no_button('Disabled button')
+ end
+
+ it "should be false for disabled buttons if :disabled => false" do
+ @session.should have_no_button('Disabled button', :disabled => false)
+ end
end
diff --git a/lib/capybara/spec/session/has_field_spec.rb b/lib/capybara/spec/session/has_field_spec.rb
index abc1df0..619856b 100644
--- a/lib/capybara/spec/session/has_field_spec.rb
+++ b/lib/capybara/spec/session/has_field_spec.rb
@@ -121,6 +121,10 @@ Capybara::SpecHelper.spec '#has_checked_field?' do
@session.should have_checked_field('Hamster')
end
+ it "should be true for disabled checkboxes if :disabled => true" do
+ @session.should have_checked_field('Disabled Checkbox', :disabled => true)
+ end
+
it "should be false if an unchecked field is on the page" do
@session.should_not have_checked_field('form_pets_cat')
@session.should_not have_checked_field('Male')
@@ -130,6 +134,14 @@ Capybara::SpecHelper.spec '#has_checked_field?' do
@session.should_not have_checked_field('Does Not Exist')
end
+ it "should be false for disabled checkboxes by default" do
+ @session.should_not have_checked_field('Disabled Checkbox')
+ end
+
+ it "should be false for disabled checkboxes if :disabled => false" do
+ @session.should_not have_checked_field('Disabled Checkbox', :disabled => false)
+ end
+
it "should be true after an unchecked checkbox is checked" do
@session.check('form_pets_cat')
@session.should have_checked_field('form_pets_cat')
@@ -159,6 +171,10 @@ Capybara::SpecHelper.spec '#has_no_checked_field?' do
@session.should_not have_no_checked_field('Hamster')
end
+ it "should be false for disabled checkboxes if :disabled => true" do
+ @session.should_not have_no_checked_field('Disabled Checkbox', :disabled => true)
+ end
+
it "should be true if an unchecked field is on the page" do
@session.should have_no_checked_field('form_pets_cat')
@session.should have_no_checked_field('Male')
@@ -167,6 +183,14 @@ Capybara::SpecHelper.spec '#has_no_checked_field?' do
it "should be true if no field is on the page" do
@session.should have_no_checked_field('Does Not Exist')
end
+
+ it "should be true for disabled checkboxes by default" do
+ @session.should have_no_checked_field('Disabled Checkbox')
+ end
+
+ it "should be true for disabled checkboxes if :disabled => false" do
+ @session.should have_no_checked_field('Disabled Checkbox', :disabled => false)
+ end
end
Capybara::SpecHelper.spec '#has_unchecked_field?' do
@@ -182,10 +206,22 @@ Capybara::SpecHelper.spec '#has_unchecked_field?' do
@session.should have_unchecked_field('Male')
end
+ it "should be true for disabled unchecked fields if :disabled => true" do
+ @session.should have_unchecked_field('Disabled Unchecked Checkbox', :disabled => true)
+ end
+
it "should be false if no field is on the page" do
@session.should_not have_unchecked_field('Does Not Exist')
end
+ it "should be false for disabled unchecked fields by default" do
+ @session.should_not have_unchecked_field('Disabled Unchecked Checkbox')
+ end
+
+ it "should be false for disabled unchecked fields if :disabled => false" do
+ @session.should_not have_unchecked_field('Disabled Unchecked Checkbox', :disabled => false)
+ end
+
it "should be false after an unchecked checkbox is checked" do
@session.check('form_pets_cat')
@session.should_not have_unchecked_field('form_pets_cat')
@@ -220,7 +256,19 @@ Capybara::SpecHelper.spec '#has_no_unchecked_field?' do
@session.should_not have_no_unchecked_field('Male')
end
+ it "should be false for disabled unchecked fields if :disabled => true" do
+ @session.should_not have_no_unchecked_field('Disabled Unchecked Checkbox', :disabled => true)
+ end
+
it "should be true if no field is on the page" do
@session.should have_no_unchecked_field('Does Not Exist')
end
+
+ it "should be true for disabled unchecked fields by default" do
+ @session.should have_no_unchecked_field('Disabled Unchecked Checkbox')
+ end
+
+ it "should be true for disabled unchecked fields if :disabled => false" do
+ @session.should have_no_unchecked_field('Disabled Unchecked Checkbox', :disabled => false)
+ end
end
diff --git a/lib/capybara/spec/session/has_text_spec.rb b/lib/capybara/spec/session/has_text_spec.rb
index 7bd46d3..b71febb 100644
--- a/lib/capybara/spec/session/has_text_spec.rb
+++ b/lib/capybara/spec/session/has_text_spec.rb
@@ -190,6 +190,16 @@ Capybara::SpecHelper.spec '#has_text?' do
@session.should_not have_text('count', minimum: '3')
end
end
+
+ context "with wait", :requires => [:js] do
+ it "should find element if it appears before given wait duration" do
+ Capybara.using_wait_time(0.1) do
+ @session.visit('/with_js')
+ @session.click_link('Click me')
+ @session.should have_text('Has been clicked', :wait => 0.9)
+ end
+ end
+ end
end
Capybara::SpecHelper.spec '#has_no_text?' do
@@ -288,4 +298,12 @@ Capybara::SpecHelper.spec '#has_no_text?' do
@session.click_link('Click me')
@session.should have_no_text("I changed it")
end
+
+ context "with wait", :requires => [:js] do
+ it "should not find element if it appears after given wait duration" do
+ @session.visit('/with_js')
+ @session.click_link('Click me')
+ @session.should have_no_text('Has been clicked', :wait => 0.1)
+ end
+ end
end
diff --git a/lib/capybara/spec/session/node_spec.rb b/lib/capybara/spec/session/node_spec.rb
index c015c8e..e576fe7 100644
--- a/lib/capybara/spec/session/node_spec.rb
+++ b/lib/capybara/spec/session/node_spec.rb
@@ -58,10 +58,25 @@ Capybara::SpecHelper.spec "node" do
@session.find('//textarea[@id="additional_newline"]').value.should == "\nbanana"
end
+ it "should not swallow leading newlines for set content in textarea" do
+ @session.find('//textarea[@id="normal"]').set("\nbanana")
+ @session.find('//textarea[@id="normal"]').value.should == "\nbanana"
+ end
+
it "return any HTML content in textarea" do
@session.find('//textarea[1]').set("some <em>html</em> here")
@session.find('//textarea[1]').value.should == "some <em>html</em> here"
end
+
+ it "defaults to 'on' for checkbox" do
+ @session.visit('/form')
+ @session.find('//input[@id="valueless_checkbox"]').value.should == 'on'
+ end
+
+ it "defaults to 'on' for radio buttons" do
+ @session.visit('/form')
+ @session.find('//input[@id="valueless_radio"]').value.should == 'on'
+ end
end
describe "#set" do
@@ -88,6 +103,25 @@ Capybara::SpecHelper.spec "node" do
@session.first('//textarea[@readonly]').set('changed')
@session.first('//textarea[@readonly]').value.should == 'textarea should not change'
end
+
+ it 'should allow me to change the contents of a contenteditable element', :requires => [:js] do
+ @session.visit('/with_js')
+ @session.find(:css,'#existing_content_editable').set('WYSIWYG')
+ @session.find(:css,'#existing_content_editable').text.should == 'WYSIWYG'
+ end
+
+ it 'should allow me to set the contents of a contenteditable element', :requires => [:js] do
+ @session.visit('/with_js')
+ @session.find(:css,'#blank_content_editable').set('WYSIWYG')
+ @session.find(:css,'#blank_content_editable').text.should == 'WYSIWYG'
+ end
+
+ it 'should allow me to change the contents of a contenteditable elements child', :requires => [:js] do
+ pending "Selenium doesn't like editing nested contents"
+ @session.visit('/with_js')
+ @session.find(:css,'#existing_content_editable_child').set('WYSIWYG')
+ @session.find(:css,'#existing_content_editable_child').text.should == 'WYSIWYG'
+ end
end
describe "#tag_name" do
@@ -125,6 +159,8 @@ Capybara::SpecHelper.spec "node" do
@session.find('//div[@id="hidden"]').should_not be_visible
@session.find('//div[@id="hidden_via_ancestor"]').should_not be_visible
+ @session.find('//div[@id="hidden_attr"]').should_not be_visible
+ @session.find('//a[@id="hidden_attr_via_ancestor"]').should_not be_visible
end
end
@@ -178,7 +214,6 @@ Capybara::SpecHelper.spec "node" do
describe '#hover', :requires => [:hover] do
it "should allow hovering on an element" do
- pending "Selenium with firefox doesn't currently work with this (selenium with chrome does)" if @session.respond_to?(:mode) && @session.mode == :selenium && @session.driver.browser.browser == :firefox
@session.visit('/with_hover')
@session.find(:css,'.hidden_until_hover', :visible => false).should_not be_visible
@session.find(:css,'.wrapper').hover
diff --git a/lib/capybara/spec/session/reset_session_spec.rb b/lib/capybara/spec/session/reset_session_spec.rb
index 95bd672..98345be 100644
--- a/lib/capybara/spec/session/reset_session_spec.rb
+++ b/lib/capybara/spec/session/reset_session_spec.rb
@@ -16,9 +16,9 @@ Capybara::SpecHelper.spec '#reset_session!' do
@session.current_path.should == '/foo'
@session.reset_session!
- [nil, '', 'about:blank'].should include @session.current_url
+ [nil, '', 'about:blank'].should include(@session.current_url)
+ ['', nil].should include(@session.current_path)
@session.current_host.should be_nil
- @session.current_path.should be_nil
end
it "resets page body" do
@@ -31,6 +31,12 @@ Capybara::SpecHelper.spec '#reset_session!' do
@session.should have_no_selector('.//h1')
end
+ it "is synchronous" do
+ @session.visit("/with_html")
+ @session.reset_session!
+ @session.should have_no_selector :xpath, "/html/body/*", wait: false
+ end
+
it "raises any errors caught inside the server", :requires => [:server] do
quietly { @session.visit("/error") }
expect do
diff --git a/lib/capybara/spec/session/save_page_spec.rb b/lib/capybara/spec/session/save_page_spec.rb
index 2ee2544..a68984b 100644
--- a/lib/capybara/spec/session/save_page_spec.rb
+++ b/lib/capybara/spec/session/save_page_spec.rb
@@ -37,11 +37,17 @@ Capybara::SpecHelper.spec '#save_page' do
File.read("capybara-001122.html").should include("Another World")
end
- it "returns the filename" do
+ it "returns an absolute path in pwd" do
result = @session.save_page
- path = Dir.glob("capybara-*.html").first
- filename = path.split("/").last
- result.should == filename
+ path = File.expand_path(Dir.glob("capybara-*.html").first, Dir.pwd)
+ result.should == path
+ end
+
+ it "returns an absolute path in given directory" do
+ Capybara.save_and_open_page_path = alternative_path
+ result = @session.save_page
+ path = File.expand_path(Dir.glob(alternative_path + "/capybara-*.html").first, alternative_path)
+ result.should == path
end
context "asset_host contains a string" do
diff --git a/lib/capybara/spec/session/visit_spec.rb b/lib/capybara/spec/session/visit_spec.rb
index 34e0c98..82ae7a1 100644
--- a/lib/capybara/spec/session/visit_spec.rb
+++ b/lib/capybara/spec/session/visit_spec.rb
@@ -17,6 +17,15 @@ Capybara::SpecHelper.spec '#visit' do
@session.should have_content('Another World')
end
+ it "should fetch a response when absolute URI doesn't have a trailing slash" do
+ # Preparation
+ @session.visit('/foo/bar')
+ root_uri = URI.parse(@session.current_url)
+
+ @session.visit("http://localhost:#{root_uri.port}")
+ @session.should have_content('Hello world!')
+ end
+
context "when Capybara.always_include_port is true" do
let(:root_uri) do
@@ -86,4 +95,11 @@ Capybara::SpecHelper.spec '#visit' do
@session.find('//input').click
@session.should have_content %r{http://.*/referer_base}
end
+
+ it "can set cookie if a blank path is specified" do
+ @session.visit("")
+ @session.visit('/get_cookie')
+ @session.should have_content('root cookie')
+ end
+
end
diff --git a/lib/capybara/spec/session/within_frame_spec.rb b/lib/capybara/spec/session/within_frame_spec.rb
index bca668c..c64fabc 100644
--- a/lib/capybara/spec/session/within_frame_spec.rb
+++ b/lib/capybara/spec/session/within_frame_spec.rb
@@ -42,4 +42,11 @@ Capybara::SpecHelper.spec '#within_frame', :requires => [:frames] do
end
end
end
+ it "should reset scope when changing frames" do
+ @session.within(:css, '#divInMainWindow') do
+ @session.within_frame 'parentFrame' do
+ @session.has_selector?(:css, "iframe#childFrame").should be_true
+ end
+ end
+ end
end
diff --git a/lib/capybara/spec/session/within_window_spec.rb b/lib/capybara/spec/session/within_window_spec.rb
index b031371..d5f2fce 100644
--- a/lib/capybara/spec/session/within_window_spec.rb
+++ b/lib/capybara/spec/session/within_window_spec.rb
@@ -35,4 +35,11 @@ Capybara::SpecHelper.spec '#within_window', :requires => [:windows] do
end
@session.find("//*[@id='divInMainWindow']").text.should eql 'This is the text for divInMainWindow'
end
+ it "should reset scope when switching windows" do
+ @session.within(:css, '#divInMainWindow') do
+ @session.within_window("secondPopup") do
+ @session.find("//*[@id='divInPopupTwo']").text.should eql 'This is the text of divInPopupTwo'
+ end
+ end
+ end
end
diff --git a/lib/capybara/spec/test_app.rb b/lib/capybara/spec/test_app.rb
index 0f3e7d3..4c2df3f 100644
--- a/lib/capybara/spec/test_app.rb
+++ b/lib/capybara/spec/test_app.rb
@@ -13,6 +13,7 @@ class TestApp < Sinatra::Base
# Also check lib/capybara/spec/views/*.erb for pages not listed here
get '/' do
+ response.set_cookie('capybara', { value: 'root cookie', domain: request.host, path: request.path} )
'Hello world! <a href="with_html">Relative</a>'
end
diff --git a/lib/capybara/spec/views/form.erb b/lib/capybara/spec/views/form.erb
index fb9b186..e67f94f 100644
--- a/lib/capybara/spec/views/form.erb
+++ b/lib/capybara/spec/views/form.erb
@@ -137,6 +137,14 @@
<p>
<p>
+ <label for="form_newline">NewLine</label></br>
+ <textarea name="form[newline]" id="form_newline">
+
+New line after and before textarea tag
+</textarea>
+ </p>
+
+ <p>
<input type="radio" name="form[gender]" value="male" id="gender_male"/>
<label for="gender_male">Male</label>
<input type="radio" name="form[gender]" value="female" id="gender_female" checked="checked"/>
@@ -153,6 +161,13 @@
<input type="checkbox" value="hamster" name="form[pets][]" id="form_pets_hamster" checked="checked"/>
<label for="form_pets_hamster">Hamster</label>
</p>
+
+ <p>
+ <input type="checkbox" name="form[valueless_checkbox]" id="valueless_checkbox" checked="checked"/>
+ <label for="valueless_checkbox">Valueless Checkbox</label>
+ <input type="radio" name="form[valueless_radio]" id="valueless_radio" checked="checked"/>
+ <label for="valueless_radio">Valueless Radio</label>
+ </p>
<p>
<label for="form_languages">Languages</label>
@@ -235,6 +250,13 @@
</p>
<p>
+ <label for="form_disabled_unchecked_checkbox">
+ Disabled Unchecked Checkbox
+ <input type="checkbox" name="form[disabled_unchecked_checkbox]" value="Should not see me" id="form_disabled_unchecked_checkbox" disabled="disabled" />
+ </label>
+ </p>
+
+ <p>
<label for="form_disabled_radio">
Disabled Radio
<input type="radio" name="form[disabled_radio]" value="Should not see me" id="form_disabled_radio" checked="checked" disabled="disabled" />
@@ -283,6 +305,8 @@
<button type="submit" name="form[other_form_button]" value="other_form_button" form="form1">Form1</button>
</form>
+<button type="submit" name="form[no_form_button]" value="no_form_button">No Form</button>
+
<textarea name="form[outside_textarea]" form="form1">Some text here</textarea>
<select name="form[outside_select]" form="form1">
<option>Lisp</option>
@@ -317,6 +341,20 @@
<p>
</form>
+<form action="/upload_empty" method="post" enctype="multipart/form-data">
+ <p>
+ <label>
+ <input type="file" name="form[file]" multiple="multiple"/>
+ Multiple empty files
+ </label>
+ </p>
+
+ <p>
+ <input type="hidden" name="form[dummy]" value="ensure params[:form] exists"/>
+ <input type="submit" value="Upload Empty Multiple"/>
+ <p>
+</form>
+
<form action="/upload" method="post" enctype="multipart/form-data">
<p>
<label for="form_file_name">File Name</label>
@@ -402,3 +440,5 @@
<input type="submit" name="form[no_action]" value="No Action" />
</p>
</form>
+
+
diff --git a/lib/capybara/spec/views/with_html.erb b/lib/capybara/spec/views/with_html.erb
index d68a54b..0bb9cc4 100644
--- a/lib/capybara/spec/views/with_html.erb
+++ b/lib/capybara/spec/views/with_html.erb
@@ -66,6 +66,11 @@ banana</textarea>
<a href="/with_simple_html" title="hidden link" class="simple">hidden link</a>
</div>
+<div id="hidden_attr" hidden="hidden">
+ <a id="hidden_attr_via_ancestor">hidden attribute ancestor link</a>
+</div>
+
+
<div id="hidden-text">
Some of this text is <em style="display:none">hidden!</em>
</div>
diff --git a/lib/capybara/spec/views/with_js.erb b/lib/capybara/spec/views/with_js.erb
index 1fdb228..47ffcd1 100644
--- a/lib/capybara/spec/views/with_js.erb
+++ b/lib/capybara/spec/views/with_js.erb
@@ -37,6 +37,14 @@
</p>
<p>
+ <div contenteditable='true' id='existing_content_editable'>Editable content</div>
+ <div contenteditable='true' id='blank_content_editable' style='height: 1em;'></div>
+ <div contenteditable='true' style='height: 1em;'>
+ <div id='existing_content_editable_child' style='height: 1em;'>Content</div>
+ </div>
+ </p>
+
+ <p>
<input type="checkbox" id="checkbox_with_event"/>
</p>
diff --git a/lib/capybara/version.rb b/lib/capybara/version.rb
index 03a4595..560cc3d 100644
--- a/lib/capybara/version.rb
+++ b/lib/capybara/version.rb
@@ -1,3 +1,3 @@
module Capybara
- VERSION = '2.1.0'
+ VERSION = '2.2.1'
end
diff --git a/metadata.gz.sig b/metadata.gz.sig
index 972dcef..806383c 100644
Binary files a/metadata.gz.sig and b/metadata.gz.sig differ
diff --git a/metadata.yml b/metadata.yml
index 9fae951..3a4282c 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,112 +1,95 @@
--- !ruby/object:Gem::Specification
name: capybara
version: !ruby/object:Gem::Version
- version: 2.1.0
- prerelease:
+ version: 2.2.1
platform: ruby
authors:
- Jonas Nicklas
autorequire:
bindir: bin
cert_chain:
-- !binary |-
- LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURQRENDQWlTZ0F3SUJB
- Z0lCQURBTkJna3Foa2lHOXcwQkFRVUZBREJFTVJZd0ZBWURWUVFEREExcWIy
- NWgKY3k1dWFXTnJiR0Z6TVJVd0V3WUtDWkltaVpQeUxHUUJHUllGWjIxaGFX
- d3hFekFSQmdvSmtpYUprL0lzWkFFWgpGZ05qYjIwd0hoY05NVE13TWpFMU1q
- RTFOVE0yV2hjTk1UUXdNakUxTWpFMU5UTTJXakJFTVJZd0ZBWURWUVFECkRB
- MXFiMjVoY3k1dWFXTnJiR0Z6TVJVd0V3WUtDWkltaVpQeUxHUUJHUllGWjIx
- aGFXd3hFekFSQmdvSmtpYUoKay9Jc1pBRVpGZ05qYjIwd2dnRWlNQTBHQ1Nx
- R1NJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURiOUFaagpnTmRVS0lF
- Rmt0blJUZXJmWXNDcXBBRlk5N3F0VGJydWo0dUVLSmV5SFJMUjRGTTNzVWU0
- TjZZYjQ4YTNKTHBBCkhRMUVMaDVjU2RKZHl4OFRFWG1Lc2NycUVjYzJsWFNn
- YmtvRnB5bzZJQWNFT1NwQzl2bEFleUdwd2tLSS8rYlAKYld3M2pWMjM2cTBD
- cjdhRk1INm5tVXZKSnNhZE93TnlVWVpXQVRxT3Q2WDNRb0xpRXBoZjdTd2hM
- ekFaSnI2ZgpIaHZqSjBYbzJ5L0xpSmo5TjBnb09oVUw2dEM1d3M1ajR3eFA4
- WitZRlkwUTd4N1E2UlFCV2NDVWhjL0dBV2V4CjBlWFJqMlFPVHpWcnJJT25Q
- TjFqcWlmbnFxVTMwWW9NRk1oL2U2bzN4L3ppWU1uN3pBYkZYU2J0WERLQ0s0
- QlQKM3pHWmdDaXVlY3NwSHk5L0FnTUJBQUdqT1RBM01Ba0dBMVVkRXdRQ01B
- QXdIUVlEVlIwT0JCWUVGUGI4K0RZMApmbTlCWmxkYy9lYUtaeGZJNlh1Y01B
- c0dBMVVkRHdRRUF3SUVzREFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBCkp0
- WnJqZDlEczVyY0JWUDJMOXZFYTZGMm9zZXE3eWU4YmF2UW85VWg4MWZEQ2JW
- ZG5hWlBoeU10aDVRaGRJQkwKcEcrdWFmQ01BZmdVMHZRZU5YbkF6SXhtbHRu
- UDQrZTNJd1IwT2UyMWVVRDZsU1BTdkNvSWFRMmVEVnhvSFBQSgo1TnJKS3hq
- MnV1TlYxeUdMbVZoWFVGRVQwT2tWdkJnZHhObXRiRTJyUmJ4WGp2NXhxVzZu
- QnNnVkF6MHFTeEIzCjl5RFRaS1c3KytFbSt5RnVmTWxEcjcrMXJsOGNUeHYx
- S2o0M0dldTVMVno3bi9sSFlLQWRqZTR1SjNlQnRhZ0kKZHdDSTZtbGVYT3I0
- TVNSZXpmMTlaVUZyMENxbEZjcnBCU3lPYWtTdFFMTThMYTNFQW1oT0VVYTJV
- RTJGSWdxNQpSMVNIMW5pKzNiSDdCNHRBa2JXc2tnPT0KLS0tLS1FTkQgQ0VS
- VElGSUNBVEUtLS0tLQo=
-date: 2013-04-09 00:00:00.000000000 Z
+- |
+ -----BEGIN CERTIFICATE-----
+ MIIDPDCCAiSgAwIBAgIBADANBgkqhkiG9w0BAQUFADBEMRYwFAYDVQQDDA1qb25h
+ cy5uaWNrbGFzMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJk/IsZAEZ
+ FgNjb20wHhcNMTMwMjE1MjE1NTM2WhcNMTQwMjE1MjE1NTM2WjBEMRYwFAYDVQQD
+ DA1qb25hcy5uaWNrbGFzMRUwEwYKCZImiZPyLGQBGRYFZ21haWwxEzARBgoJkiaJ
+ k/IsZAEZFgNjb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDb9AZj
+ gNdUKIEFktnRTerfYsCqpAFY97qtTbruj4uEKJeyHRLR4FM3sUe4N6Yb48a3JLpA
+ HQ1ELh5cSdJdyx8TEXmKscrqEcc2lXSgbkoFpyo6IAcEOSpC9vlAeyGpwkKI/+bP
+ bWw3jV236q0Cr7aFMH6nmUvJJsadOwNyUYZWATqOt6X3QoLiEphf7SwhLzAZJr6f
+ HhvjJ0Xo2y/LiJj9N0goOhUL6tC5ws5j4wxP8Z+YFY0Q7x7Q6RQBWcCUhc/GAWex
+ 0eXRj2QOTzVrrIOnPN1jqifnqqU30YoMFMh/e6o3x/ziYMn7zAbFXSbtXDKCK4BT
+ 3zGZgCiuecspHy9/AgMBAAGjOTA3MAkGA1UdEwQCMAAwHQYDVR0OBBYEFPb8+DY0
+ fm9BZldc/eaKZxfI6XucMAsGA1UdDwQEAwIEsDANBgkqhkiG9w0BAQUFAAOCAQEA
+ JtZrjd9Ds5rcBVP2L9vEa6F2oseq7ye8bavQo9Uh81fDCbVdnaZPhyMth5QhdIBL
+ pG+uafCMAfgU0vQeNXnAzIxmltnP4+e3IwR0Oe21eUD6lSPSvCoIaQ2eDVxoHPPJ
+ 5NrJKxj2uuNV1yGLmVhXUFET0OkVvBgdxNmtbE2rRbxXjv5xqW6nBsgVAz0qSxB3
+ 9yDTZKW7++Em+yFufMlDr7+1rl8cTxv1Kj43Geu5LVz7n/lHYKAdje4uJ3eBtagI
+ dwCI6mleXOr4MSRezf19ZUFr0CqlFcrpBSyOakStQLM8La3EAmhOEUa2UE2FIgq5
+ R1SH1ni+3bH7B4tAkbWskg==
+ -----END CERTIFICATE-----
+date: 2014-01-06 00:00:00.000000000 Z
dependencies:
- !ruby/object:Gem::Dependency
name: nokogiri
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 1.3.3
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 1.3.3
- !ruby/object:Gem::Dependency
name: mime-types
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: '1.16'
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: '1.16'
- !ruby/object:Gem::Dependency
name: rack
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 1.0.0
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 1.0.0
- !ruby/object:Gem::Dependency
name: rack-test
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.5.4
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.5.4
- !ruby/object:Gem::Dependency
name: xpath
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - ~>
- !ruby/object:Gem::Version
@@ -114,7 +97,6 @@ dependencies:
type: :runtime
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - ~>
- !ruby/object:Gem::Version
@@ -122,7 +104,6 @@ dependencies:
- !ruby/object:Gem::Dependency
name: selenium-webdriver
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - ~>
- !ruby/object:Gem::Version
@@ -130,7 +111,6 @@ dependencies:
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - ~>
- !ruby/object:Gem::Version
@@ -138,129 +118,113 @@ dependencies:
- !ruby/object:Gem::Dependency
name: sinatra
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.9.4
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.9.4
- !ruby/object:Gem::Dependency
name: rspec
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 2.2.0
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 2.2.0
- !ruby/object:Gem::Dependency
name: launchy
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 2.0.4
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 2.0.4
- !ruby/object:Gem::Dependency
name: yard
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.5.8
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.5.8
- !ruby/object:Gem::Dependency
name: fuubar
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.0.1
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.0.1
- !ruby/object:Gem::Dependency
name: cucumber
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.10.5
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 0.10.5
- !ruby/object:Gem::Dependency
name: rake
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: '0'
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: '0'
- !ruby/object:Gem::Dependency
name: pry
requirement: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: '0'
type: :development
prerelease: false
version_requirements: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: '0'
description: Capybara is an integration testing tool for rack based web applications.
@@ -325,6 +289,8 @@ files:
- lib/capybara/spec/session/find_link_spec.rb
- lib/capybara/spec/session/find_spec.rb
- lib/capybara/spec/session/first_spec.rb
+- lib/capybara/spec/session/go_back_spec.rb
+- lib/capybara/spec/session/go_forward_spec.rb
- lib/capybara/spec/session/has_button_spec.rb
- lib/capybara/spec/session/has_css_spec.rb
- lib/capybara/spec/session/has_field_spec.rb
@@ -391,40 +357,35 @@ files:
- spec/rspec/matchers_spec.rb
- spec/rspec_spec.rb
- spec/selenium_spec.rb
+- spec/selenium_spec_chrome.rb
- spec/server_spec.rb
- spec/spec_helper.rb
- README.md
- History.md
- License.txt
homepage: http://github.com/jnicklas/capybara
-licenses: []
-post_install_message: ! "IMPORTANT! Some of the defaults have changed in Capybara
- 2.1. If you're experiencing failures,\nplease revert to the old behaviour by setting:\n\n
- \ Capybara.configure do |config|\n config.match = :one\n config.exact_options
- = true\n config.ignore_hidden_elements = true\n config.visible_text_only
- = true\n end\n\nIf you're migrating from Capybara 1.x, try:\n\n Capybara.configure
- do |config|\n config.match = :prefer_exact\n config.ignore_hidden_elements
- = false\n end\n\nDetails here: http://www.elabs.se/blog/60-introducing-capybara-2-1\n\n"
+licenses:
+- MIT
+metadata: {}
+post_install_message:
rdoc_options: []
require_paths:
- lib
required_ruby_version: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: 1.9.3
required_rubygems_version: !ruby/object:Gem::Requirement
- none: false
requirements:
- - - ! '>='
+ - - '>='
- !ruby/object:Gem::Version
version: '0'
requirements: []
rubyforge_project: capybara
-rubygems_version: 1.8.25
+rubygems_version: 2.0.6
signing_key:
-specification_version: 3
+specification_version: 4
summary: Capybara aims to simplify the process of integration testing Rack applications,
such as Rails, Sinatra or Merb
test_files: []
diff --git a/spec/capybara_spec.rb b/spec/capybara_spec.rb
index d147c7b..548de2b 100644
--- a/spec/capybara_spec.rb
+++ b/spec/capybara_spec.rb
@@ -31,7 +31,7 @@ describe Capybara do
end
it "should default to a proc that calls run_default_server" do
- mock_app = mock('app')
+ mock_app = double('app')
Capybara.should_receive(:run_default_server).with(mock_app, 8000)
Capybara.server.call(mock_app, 8000)
end
diff --git a/spec/result_spec.rb b/spec/result_spec.rb
index 82de3a6..f0d0cd9 100644
--- a/spec/result_spec.rb
+++ b/spec/result_spec.rb
@@ -28,6 +28,10 @@ describe Capybara::Result do
result.last.text == 'Delta'
end
+ it 'can supports values_at method' do
+ result.values_at(0, 2).map(&:text).should == %w(Alpha Gamma)
+ end
+
it "can return an element by its index" do
result.at(1).text.should == 'Beta'
result[2].text.should == 'Gamma'
@@ -48,4 +52,14 @@ describe Capybara::Result do
memo += element.text[0]
end.should == 'ABGD'
end
+
+ it 'can be sampled' do
+ result.should include(result.sample)
+ end
+
+ it 'can be indexed' do
+ result.index do |el|
+ el.text == 'Gamma'
+ end.should == 2
+ end
end
diff --git a/spec/rspec/features_spec.rb b/spec/rspec/features_spec.rb
index a277795..ee23bff 100644
--- a/spec/rspec/features_spec.rb
+++ b/spec/rspec/features_spec.rb
@@ -34,6 +34,21 @@ feature "Capybara's feature DSL" do
scenario "doesn't pollute the Object namespace" do
Object.new.respond_to?(:feature, true).should be_false
end
+
+ feature 'nested features' do
+ scenario 'work as expected' do
+ visit '/'
+ page.should have_content 'Hello world!'
+ end
+
+ scenario 'are marked in the metadata as capybara_feature' do
+ example.metadata[:capybara_feature].should be_true
+ end
+
+ scenario 'have a type of :feature' do
+ example.metadata[:type].should eq :feature
+ end
+ end
end
feature "given and given! aliases to let and let!" do
diff --git a/spec/rspec/matchers_spec.rb b/spec/rspec/matchers_spec.rb
index cb6a977..2914bc6 100644
--- a/spec/rspec/matchers_spec.rb
+++ b/spec/rspec/matchers_spec.rb
@@ -519,21 +519,44 @@ describe Capybara::RSpecMatchers do
end
describe "have_field matcher" do
- let(:html) { '<p><label>Text field<input type="text"/></label></p>' }
+ let(:html) { '<p><label>Text field<input type="text" value="some value"/></label></p>' }
it "gives proper description" do
have_field('Text field').description.should == "have field \"Text field\""
end
+ it "gives proper description for a given value" do
+ have_field('Text field', with: 'some value').description.should == "have field \"Text field\" with value \"some value\""
+ end
+
it "passes if there is such a field" do
html.should have_field('Text field')
end
+ it "passes if there is such a field with value" do
+ html.should have_field('Text field', with: 'some value')
+ end
+
it "fails if there is no such field" do
expect do
html.should have_field('No such Field')
end.to raise_error(/expected to find field "No such Field"/)
end
+
+ it "fails if there is such field but with false value" do
+ expect do
+ html.should have_field('Text field', with: 'false value')
+ end.to raise_error(/expected to find field "Text field"/)
+ end
+
+ it "treats a given value as a string" do
+ class Foo
+ def to_s
+ "some value"
+ end
+ end
+ html.should have_field('Text field', with: Foo.new)
+ end
end
describe "have_checked_field matcher" do
diff --git a/spec/selenium_spec.rb b/spec/selenium_spec.rb
index 7de2545..6b94d59 100644
--- a/spec/selenium_spec.rb
+++ b/spec/selenium_spec.rb
@@ -1,7 +1,14 @@
require 'spec_helper'
+require "selenium-webdriver"
+
+Capybara.register_driver :selenium_focus do |app|
+ profile = Selenium::WebDriver::Firefox::Profile.new
+ profile["focusmanager.testmode"] = true
+ Capybara::Selenium::Driver.new(app, browser: :firefox, profile: profile)
+end
module TestSessions
- Selenium = Capybara::Session.new(:selenium, TestApp)
+ Selenium = Capybara::Session.new(:selenium_focus, TestApp)
end
Capybara::SpecHelper.run_specs TestSessions::Selenium, "selenium", :skip => [
@@ -24,7 +31,7 @@ describe Capybara::Session do
describe '#mode' do
it "should remember the mode" do
- @session.mode.should == :selenium
+ @session.mode.should == :selenium_focus
end
end
diff --git a/spec/selenium_spec_chrome.rb b/spec/selenium_spec_chrome.rb
new file mode 100644
index 0000000..3729008
--- /dev/null
+++ b/spec/selenium_spec_chrome.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+Capybara.register_driver :selenium_chrome do |app|
+ args = ENV['TRAVIS'] ? ['no-sandbox' ] : []
+ Capybara::Selenium::Driver.new(app, :browser => :chrome, :args => args)
+end
+
+class ChromeTestApp < TestApp
+ # Object.id is different from the TestApp used in firefox session so
+ # a new Capybar::Server instance will get launched for chrome testing
+end
+
+module TestSessions
+ Chrome = Capybara::Session.new(:selenium_chrome, ChromeTestApp)
+end
+
+Capybara::SpecHelper.run_specs TestSessions::Chrome, "selenium_chrome", :skip => [
+ :response_headers,
+ :status_code,
+ :trigger
+]
diff --git a/spec/server_spec.rb b/spec/server_spec.rb
index 13e4124..9012edd 100644
--- a/spec/server_spec.rb
+++ b/spec/server_spec.rb
@@ -18,13 +18,21 @@ describe Capybara::Server do
end
it "should bind to the specified host" do
- Capybara.server_host = '0.0.0.0'
+ begin
+ app = proc { |env| [200, {}, ['Hello Server!']] }
- app = proc { |env| [200, {}, ["Hello Server!"]]}
- server = Capybara::Server.new(app).boot
- server.host.should == '0.0.0.0'
+ Capybara.server_host = '127.0.0.1'
+ server = Capybara::Server.new(app).boot
+ res = Net::HTTP.get(URI("http://127.0.0.1:#{server.port}"))
+ expect(res).to eq('Hello Server!')
- Capybara.server_host = nil
+ Capybara.server_host = '0.0.0.0'
+ server = Capybara::Server.new(app).boot
+ res = Net::HTTP.get(URI("http://127.0.0.1:#{server.port}"))
+ expect(res).to eq('Hello Server!')
+ ensure
+ Capybara.server_host = nil
+ end
end
it "should use specified port" do
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-capybara.git
More information about the Pkg-ruby-extras-commits
mailing list