capybara 2.1.0.beta1 → 2.1.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/History.md +11 -2
- data/README.md +5 -47
- data/lib/capybara.rb +0 -1
- data/lib/capybara/helpers.rb +1 -1
- data/lib/capybara/node/actions.rb +6 -6
- data/lib/capybara/node/element.rb +2 -3
- data/lib/capybara/node/finders.rb +1 -1
- data/lib/capybara/node/matchers.rb +6 -6
- data/lib/capybara/node/simple.rb +2 -2
- data/lib/capybara/query.rb +1 -1
- data/lib/capybara/rack_test/node.rb +5 -5
- data/lib/capybara/rails.rb +1 -1
- data/lib/capybara/selenium/driver.rb +10 -11
- data/lib/capybara/server.rb +1 -1
- data/lib/capybara/session.rb +1 -1
- data/lib/capybara/spec/session/fill_in_spec.rb +12 -0
- data/lib/capybara/spec/session/find_spec.rb +6 -0
- data/lib/capybara/spec/session/node_spec.rb +12 -7
- data/lib/capybara/spec/spec_helper.rb +1 -1
- data/lib/capybara/spec/views/with_html.erb +2 -0
- data/lib/capybara/version.rb +1 -1
- data/spec/server_spec.rb +7 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
data.tar.gz.sig
CHANGED
Binary file
|
data/History.md
CHANGED
@@ -64,12 +64,21 @@ Release date: Unreleased
|
|
64
64
|
|
65
65
|
* Fixed race conditions when synchronizing across multiple nodes [Jonas Nicklas]
|
66
66
|
* Fixed race conditions in deeply nested selectors [Jonas Nicklas]
|
67
|
-
* Use posix character class for whitespace replace, solves various encoding
|
68
|
-
problems on Ruby 2.0.0 and JRuby. [Jonas Nicklas]
|
69
67
|
* Fix issue with `within_frame`, where selecting multiple nested frames didn't
|
70
68
|
work as intended. [Thomas Walpole]
|
71
69
|
* RackTest no longer fills in readonly textareas. [Thomas Walpole]
|
72
70
|
* Don't use autoload to load files, require them directly instead. [Jonas Nicklas]
|
71
|
+
* Rescue weird exceptions when booting server [John Wilger]
|
72
|
+
* Non strings are now properly cast when using the maxlength attribute [Jonas Nicklas]
|
73
|
+
|
74
|
+
# Version 2.0.3
|
75
|
+
|
76
|
+
Release date: 2013-03-26
|
77
|
+
|
78
|
+
* Check against Rails version fixed to work with Rails' master branch now returning
|
79
|
+
a Gem::Version [Jonas Nicklas]
|
80
|
+
* Use posix character class for whitespace replace, solves various encoding
|
81
|
+
problems on Ruby 2.0.0 and JRuby. [Ben Cates]
|
73
82
|
|
74
83
|
# Version 2.0.2
|
75
84
|
|
data/README.md
CHANGED
@@ -23,19 +23,19 @@ GitHub): http://groups.google.com/group/ruby-capybara
|
|
23
23
|
|
24
24
|
## Setup
|
25
25
|
|
26
|
-
To install, type
|
26
|
+
Capybara requires Ruby 1.9.3 or later. To install, type:
|
27
27
|
|
28
28
|
```bash
|
29
29
|
gem install capybara
|
30
30
|
```
|
31
31
|
|
32
|
-
If you are
|
32
|
+
If the application that you are testing is a Rails app, add this line to your test helper file:
|
33
33
|
|
34
34
|
```ruby
|
35
35
|
require 'capybara/rails'
|
36
36
|
```
|
37
37
|
|
38
|
-
If you are not
|
38
|
+
If the application that you are testing is a Rack app, but not Rails, set Capybara.app to your Rack app:
|
39
39
|
|
40
40
|
```ruby
|
41
41
|
Capybara.app = MyRackApp
|
@@ -162,36 +162,14 @@ end
|
|
162
162
|
|
163
163
|
## Using Capybara with Test::Unit
|
164
164
|
|
165
|
-
* If you are using Rails, add
|
166
|
-
|
167
|
-
```ruby
|
168
|
-
group :test do
|
169
|
-
gem 'database_cleaner'
|
170
|
-
end
|
171
|
-
```
|
172
|
-
|
173
|
-
Then add the following code in your `test_helper.rb` file to make
|
174
|
-
Capybara available in all test cases deriving from
|
165
|
+
* If you are using Rails, add the following code in your `test_helper.rb`
|
166
|
+
file to make Capybara available in all test cases deriving from
|
175
167
|
`ActionDispatch::IntegrationTest`:
|
176
168
|
|
177
169
|
```ruby
|
178
|
-
# Transactional fixtures do not work with Selenium tests, because Capybara
|
179
|
-
# uses a separate server thread, which the transactions would be hidden
|
180
|
-
# from. We hence use DatabaseCleaner to truncate our test database.
|
181
|
-
DatabaseCleaner.strategy = :truncation
|
182
|
-
|
183
170
|
class ActionDispatch::IntegrationTest
|
184
171
|
# Make the Capybara DSL available in all integration tests
|
185
172
|
include Capybara::DSL
|
186
|
-
|
187
|
-
# Stop ActiveRecord from wrapping tests in transactions
|
188
|
-
self.use_transactional_fixtures = false
|
189
|
-
|
190
|
-
teardown do
|
191
|
-
DatabaseCleaner.clean # Truncate the database
|
192
|
-
Capybara.reset_sessions! # Forget the (simulated) browser state
|
193
|
-
Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
|
194
|
-
end
|
195
173
|
end
|
196
174
|
```
|
197
175
|
|
@@ -784,25 +762,6 @@ find(:row, 3)
|
|
784
762
|
find(:flash_type, :notice)
|
785
763
|
```
|
786
764
|
|
787
|
-
You can specify an optional match option which will automatically use the
|
788
|
-
selector if it matches the argument:
|
789
|
-
|
790
|
-
```ruby
|
791
|
-
Capybara.add_selector(:id) do
|
792
|
-
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
793
|
-
match { |value| value.is_a?(Symbol) }
|
794
|
-
end
|
795
|
-
```
|
796
|
-
|
797
|
-
Now use it like this:
|
798
|
-
|
799
|
-
```ruby
|
800
|
-
find(:post_123)
|
801
|
-
```
|
802
|
-
|
803
|
-
This :id selector is already built into Capybara by default, so you don't
|
804
|
-
need to add it yourself.
|
805
|
-
|
806
765
|
## Beware the XPath // trap
|
807
766
|
|
808
767
|
In XPath the expression // means something very specific, and it might not be what
|
@@ -887,7 +846,6 @@ additional info about how the underlying driver can be configured.
|
|
887
846
|
To set up a development environment, simply do:
|
888
847
|
|
889
848
|
```bash
|
890
|
-
git submodule update --init
|
891
849
|
bundle install
|
892
850
|
bundle exec rake # run the test suite
|
893
851
|
```
|
data/lib/capybara.rb
CHANGED
@@ -33,7 +33,6 @@ module Capybara
|
|
33
33
|
#
|
34
34
|
# === Configurable options
|
35
35
|
#
|
36
|
-
# [asset_host = String] The hostname for a server from which assets can be loaded, used by save_and_open_page
|
37
36
|
# [app_host = String] The default host to use when giving a relative URL to visit
|
38
37
|
# [always_include_port = Boolean] Whether the Rack server's port should automatically be inserted into every visited URL (Default: false)
|
39
38
|
# [asset_host = String] Where dynamic assets are hosted - will be prepended to relative asset locations if present (Default: nil)
|
data/lib/capybara/helpers.rb
CHANGED
@@ -44,8 +44,8 @@ module Capybara
|
|
44
44
|
#
|
45
45
|
# page.fill_in 'Name', :with => 'Bob'
|
46
46
|
#
|
47
|
-
# @param [String] locator
|
48
|
-
# @param [Hash{:with => String}]
|
47
|
+
# @param [String] locator Which field to fill in
|
48
|
+
# @param [Hash{:with => String}] options The value to fill in
|
49
49
|
#
|
50
50
|
def fill_in(locator, options={})
|
51
51
|
raise "Must pass a hash containing 'with'" if not options.is_a?(Hash) or not options.has_key?(:with)
|
@@ -100,8 +100,8 @@ module Capybara
|
|
100
100
|
#
|
101
101
|
# page.select 'March', :from => 'Month'
|
102
102
|
#
|
103
|
-
# @param [String] value
|
104
|
-
# @param [Hash{:from => String}]
|
103
|
+
# @param [String] value Which option to select
|
104
|
+
# @param [Hash{:from => String}] options The id, name or label of the select box
|
105
105
|
#
|
106
106
|
def select(value, options={})
|
107
107
|
if options.has_key?(:from)
|
@@ -120,8 +120,8 @@ module Capybara
|
|
120
120
|
#
|
121
121
|
# page.unselect 'March', :from => 'Month'
|
122
122
|
#
|
123
|
-
# @param [String] value
|
124
|
-
# @param [Hash{:from => String}]
|
123
|
+
# @param [String] value Which option to unselect
|
124
|
+
# @param [Hash{:from => String}] options The id, name or label of the select box
|
125
125
|
#
|
126
126
|
def unselect(value, options={})
|
127
127
|
if options.has_key?(:from)
|
@@ -49,9 +49,8 @@ module Capybara
|
|
49
49
|
# ignored. This behaviour can be overridden by passing `:all` to this
|
50
50
|
# method.
|
51
51
|
#
|
52
|
-
# @param [:all, :visible]
|
53
|
-
#
|
54
|
-
# @return [String] The text of the element
|
52
|
+
# @param [:all, :visible] type Whether to return only visible or all text
|
53
|
+
# @return [String] The text of the element
|
55
54
|
#
|
56
55
|
def text(type=nil)
|
57
56
|
type ||= :all unless Capybara.ignore_hidden_elements or Capybara.visible_text_only
|
@@ -137,7 +137,7 @@ module Capybara
|
|
137
137
|
# @overload first([kind], locator, options)
|
138
138
|
# @param [:css, :xpath] kind The type of selector
|
139
139
|
# @param [String] locator The selector
|
140
|
-
# @param [Hash] options Additional options; see {all}
|
140
|
+
# @param [Hash] options Additional options; see {#all}
|
141
141
|
# @return [Capybara::Element] The found element or nil
|
142
142
|
#
|
143
143
|
def first(*args)
|
@@ -28,12 +28,12 @@ module Capybara
|
|
28
28
|
# page.has_selector?(:xpath, XPath.descendant(:p))
|
29
29
|
#
|
30
30
|
# @param (see Capybara::Node::Finders#all)
|
31
|
-
# @param
|
32
|
-
# @option
|
33
|
-
# @option
|
34
|
-
# @option
|
35
|
-
# @option
|
36
|
-
# @return [Boolean]
|
31
|
+
# @param args
|
32
|
+
# @option args [Integer] :count (nil) Number of times the text should occur
|
33
|
+
# @option args [Integer] :minimum (nil) Minimum number of times the text should occur
|
34
|
+
# @option args [Integer] :maximum (nil) Maximum number of times the text should occur
|
35
|
+
# @option args [Range] :between (nil) Range of times that should contain number of times text occurs
|
36
|
+
# @return [Boolean] If the expression exists
|
37
37
|
#
|
38
38
|
def has_selector?(*args)
|
39
39
|
assert_selector(*args)
|
data/lib/capybara/node/simple.rb
CHANGED
@@ -36,8 +36,8 @@ module Capybara
|
|
36
36
|
#
|
37
37
|
# element[:title] # => HTML title attribute
|
38
38
|
#
|
39
|
-
# @param [Symbol]
|
40
|
-
# @return [String]
|
39
|
+
# @param [Symbol] name The attribute name to retrieve
|
40
|
+
# @return [String] The value of the attribute
|
41
41
|
#
|
42
42
|
def [](name)
|
43
43
|
attr_name = name.to_s
|
data/lib/capybara/query.rb
CHANGED
@@ -37,7 +37,7 @@ module Capybara
|
|
37
37
|
|
38
38
|
def matches_filters?(node)
|
39
39
|
if options[:text]
|
40
|
-
regexp = options[:text].is_a?(Regexp) ? options[:text] : Regexp.escape(options[:text])
|
40
|
+
regexp = options[:text].is_a?(Regexp) ? options[:text] : Regexp.escape(options[:text].to_s)
|
41
41
|
return false if not node.text(visible).match(regexp)
|
42
42
|
end
|
43
43
|
case visible
|
@@ -79,7 +79,7 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
79
79
|
string_node.disabled?
|
80
80
|
end
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
83
|
def path
|
84
84
|
native.path
|
85
85
|
end
|
@@ -87,11 +87,11 @@ class Capybara::RackTest::Node < Capybara::Driver::Node
|
|
87
87
|
def find_xpath(locator)
|
88
88
|
native.xpath(locator).map { |n| self.class.new(driver, n) }
|
89
89
|
end
|
90
|
-
|
91
|
-
def find_css(locator)
|
90
|
+
|
91
|
+
def find_css(locator)
|
92
92
|
native.css(locator, Capybara::RackTest::CSSHandlers.new).map { |n| self.class.new(driver, n) }
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
def ==(other)
|
96
96
|
native == other.native
|
97
97
|
end
|
@@ -153,7 +153,7 @@ private
|
|
153
153
|
if text_or_password? && attribute_is_not_blank?(:maxlength)
|
154
154
|
# Browser behavior for maxlength="0" is inconsistent, so we stick with
|
155
155
|
# Firefox, allowing no input
|
156
|
-
value = value[0...self[:maxlength].to_i]
|
156
|
+
value = value.to_s[0...self[:maxlength].to_i]
|
157
157
|
end
|
158
158
|
if Array === value #Assert multiple attribute is present
|
159
159
|
value.each do |v|
|
data/lib/capybara/rails.rb
CHANGED
@@ -1,14 +1,3 @@
|
|
1
|
-
begin
|
2
|
-
require 'selenium-webdriver'
|
3
|
-
rescue LoadError => e
|
4
|
-
if e.message =~ /selenium-webdriver/
|
5
|
-
raise LoadError, "Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler."
|
6
|
-
else
|
7
|
-
raise e
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
|
12
1
|
class Capybara::Selenium::Driver < Capybara::Driver::Base
|
13
2
|
DEFAULT_OPTIONS = {
|
14
3
|
:browser => :firefox
|
@@ -33,6 +22,16 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
|
|
33
22
|
end
|
34
23
|
|
35
24
|
def initialize(app, options={})
|
25
|
+
begin
|
26
|
+
require 'selenium-webdriver'
|
27
|
+
rescue LoadError => e
|
28
|
+
if e.message =~ /selenium-webdriver/
|
29
|
+
raise LoadError, "Capybara's selenium driver is unable to load `selenium-webdriver`, please install the gem and add `gem 'selenium-webdriver'` to your Gemfile if you are using bundler."
|
30
|
+
else
|
31
|
+
raise e
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
36
35
|
@app = app
|
37
36
|
@browser = nil
|
38
37
|
@exit_status = nil
|
data/lib/capybara/server.rb
CHANGED
data/lib/capybara/session.rb
CHANGED
@@ -325,7 +325,7 @@ module Capybara
|
|
325
325
|
#
|
326
326
|
# Save a snapshot of the page and open it in a browser for inspection
|
327
327
|
#
|
328
|
-
# @param [String]
|
328
|
+
# @param [String] file_name The path to where it should be saved [optional]
|
329
329
|
#
|
330
330
|
def save_and_open_page(file_name=nil)
|
331
331
|
require "launchy"
|
@@ -51,6 +51,12 @@ Capybara::SpecHelper.spec "#fill_in" do
|
|
51
51
|
extract_results(@session)['password'].should == 'supasikrit'
|
52
52
|
end
|
53
53
|
|
54
|
+
it "should handle HTML in a textarea" do
|
55
|
+
@session.fill_in('form_description', :with => 'is <strong>very</strong> secret!')
|
56
|
+
@session.click_button('awesome')
|
57
|
+
extract_results(@session)['description'].should == 'is <strong>very</strong> secret!'
|
58
|
+
end
|
59
|
+
|
54
60
|
it "should fill in a field with a custom type" do
|
55
61
|
@session.fill_in('Schmooo', :with => 'Schmooo is the game')
|
56
62
|
@session.click_button('awesome')
|
@@ -103,6 +109,12 @@ Capybara::SpecHelper.spec "#fill_in" do
|
|
103
109
|
extract_results(@session)['first_name'].should == 'Harry'
|
104
110
|
end
|
105
111
|
|
112
|
+
it "casts to string if field has maxlength", :focus => true do
|
113
|
+
@session.fill_in(:'form_zipcode', :with => 1234567)
|
114
|
+
@session.click_button('awesome')
|
115
|
+
extract_results(@session)['zipcode'].should == '12345'
|
116
|
+
end
|
117
|
+
|
106
118
|
context 'on a pre-populated textfield with a reformatting onchange', :requires => [:js] do
|
107
119
|
it 'should only trigger onchange once' do
|
108
120
|
@session.visit('/with_js')
|
@@ -27,6 +27,12 @@ Capybara::SpecHelper.spec '#find' do
|
|
27
27
|
@session.find(:css, "a#has-been-clicked").text.should include('Has been clicked')
|
28
28
|
end
|
29
29
|
|
30
|
+
context "with :text option" do
|
31
|
+
it "casts text's argument to string" do
|
32
|
+
@session.find(:css, '.number', text: 42).should have_content("42")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
30
36
|
context "with :wait option", :requires => [:js] do
|
31
37
|
it "should not wait for asynchronous load when `false` given" do
|
32
38
|
@session.visit('/with_js')
|
@@ -57,6 +57,11 @@ Capybara::SpecHelper.spec "node" do
|
|
57
57
|
it "should not swallow extra newlines in textarea" do
|
58
58
|
@session.find('//textarea[@id="additional_newline"]').value.should == "\nbanana"
|
59
59
|
end
|
60
|
+
|
61
|
+
it "return any HTML content in textarea" do
|
62
|
+
@session.find('//textarea[1]').set("some <em>html</em> here")
|
63
|
+
@session.find('//textarea[1]').value.should == "some <em>html</em> here"
|
64
|
+
end
|
60
65
|
end
|
61
66
|
|
62
67
|
describe "#set" do
|
@@ -71,18 +76,18 @@ Capybara::SpecHelper.spec "node" do
|
|
71
76
|
@session.first('//input').set('')
|
72
77
|
@session.first('//input').value.should == ''
|
73
78
|
end
|
74
|
-
|
79
|
+
|
75
80
|
it "should not set if the text field is readonly" do
|
76
81
|
@session.first('//input[@readonly]').value.should == 'should not change'
|
77
82
|
@session.first('//input[@readonly]').set('changed')
|
78
83
|
@session.first('//input[@readonly]').value.should == 'should not change'
|
79
84
|
end
|
80
|
-
|
85
|
+
|
81
86
|
it "should not set if the textarea is readonly" do
|
82
87
|
@session.first('//textarea[@readonly]').value.should == 'textarea should not change'
|
83
88
|
@session.first('//textarea[@readonly]').set('changed')
|
84
89
|
@session.first('//textarea[@readonly]').value.should == 'textarea should not change'
|
85
|
-
end
|
90
|
+
end
|
86
91
|
end
|
87
92
|
|
88
93
|
describe "#tag_name" do
|
@@ -99,13 +104,13 @@ Capybara::SpecHelper.spec "node" do
|
|
99
104
|
@session.find('//input[@id="customer_name"]').should be_disabled
|
100
105
|
@session.find('//input[@id="customer_email"]').should_not be_disabled
|
101
106
|
end
|
102
|
-
|
107
|
+
|
103
108
|
it "should see disabled options as disabled" do
|
104
109
|
@session.visit('/form')
|
105
110
|
@session.find('//select[@id="form_title"]/option[1]').should_not be_disabled
|
106
111
|
@session.find('//select[@id="form_title"]/option[@disabled]').should be_disabled
|
107
112
|
end
|
108
|
-
|
113
|
+
|
109
114
|
it "should see enabled options in disabled select as disabled" do
|
110
115
|
@session.visit('/form')
|
111
116
|
@session.find('//select[@id="form_disabled_select"]/option').should be_disabled
|
@@ -170,8 +175,8 @@ Capybara::SpecHelper.spec "node" do
|
|
170
175
|
@session.find('//div[contains(., "Dropped!")]').should_not be_nil
|
171
176
|
end
|
172
177
|
end
|
173
|
-
|
174
|
-
describe '#hover', :requires => [:hover] do
|
178
|
+
|
179
|
+
describe '#hover', :requires => [:hover] do
|
175
180
|
it "should allow hovering on an element" do
|
176
181
|
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
|
177
182
|
@session.visit('/with_hover')
|
@@ -78,7 +78,7 @@ module Capybara
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def extract_results(session)
|
81
|
-
YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.
|
81
|
+
YAML.load Nokogiri::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
@@ -8,6 +8,8 @@
|
|
8
8
|
<h2 class="head">Header Class Test Four</h2>
|
9
9
|
<h2 class="head">Header Class Test Five</h2>
|
10
10
|
|
11
|
+
<span class="number">42</span>
|
12
|
+
|
11
13
|
<p class="para" id="first">
|
12
14
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
|
13
15
|
tempor incididunt ut <a href="/with_simple_html" title="awesome title" class="simple">labore</a>
|
data/lib/capybara/version.rb
CHANGED
data/spec/server_spec.rb
CHANGED
@@ -98,4 +98,11 @@ describe Capybara::Server do
|
|
98
98
|
Capybara.server {|app, port| Capybara.run_default_server(app, port)}
|
99
99
|
end
|
100
100
|
end
|
101
|
+
|
102
|
+
it "is not #responsive? when Net::HTTP raises a SystemCallError" do
|
103
|
+
app = lambda { [200, {}, ['Hello, world']] }
|
104
|
+
server = Capybara::Server.new(app)
|
105
|
+
Net::HTTP.should_receive(:start).and_raise(SystemCallError.allocate)
|
106
|
+
expect(server.responsive?).to eq false
|
107
|
+
end
|
101
108
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.0.
|
4
|
+
version: 2.1.0.rc1
|
5
5
|
prerelease: 6
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -37,7 +37,7 @@ cert_chain:
|
|
37
37
|
TVNSZXpmMTlaVUZyMENxbEZjcnBCU3lPYWtTdFFMTThMYTNFQW1oT0VVYTJV
|
38
38
|
RTJGSWdxNQpSMVNIMW5pKzNiSDdCNHRBa2JXc2tnPT0KLS0tLS1FTkQgQ0VS
|
39
39
|
VElGSUNBVEUtLS0tLQo=
|
40
|
-
date: 2013-
|
40
|
+
date: 2013-04-02 00:00:00.000000000 Z
|
41
41
|
dependencies:
|
42
42
|
- !ruby/object:Gem::Dependency
|
43
43
|
name: nokogiri
|
metadata.gz.sig
CHANGED
Binary file
|