capybara 0.4.0.rc → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +16 -1
- data/README.rdoc +16 -7
- data/lib/capybara.rb +41 -1
- data/lib/capybara/driver/celerity_driver.rb +1 -1
- data/lib/capybara/driver/rack_test_driver.rb +1 -0
- data/lib/capybara/driver/selenium_driver.rb +3 -3
- data/lib/capybara/selector.rb +29 -11
- data/lib/capybara/session.rb +1 -1
- data/lib/capybara/spec/session/click_link_spec.rb +12 -7
- data/lib/capybara/spec/session/find_spec.rb +8 -3
- data/lib/capybara/spec/views/with_html.erb +5 -0
- data/lib/capybara/version.rb +1 -1
- metadata +7 -12
data/History.txt
CHANGED
@@ -1,6 +1,21 @@
|
|
1
|
+
# Version 0.4.0
|
2
|
+
|
3
|
+
Release date: 2010-10-22
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
|
7
|
+
* The Selector API was changed slightly, use Capybara.add_selector, see README
|
8
|
+
|
9
|
+
### Fixed
|
10
|
+
|
11
|
+
* Celerity driver is registered properly
|
12
|
+
* has_selector? and has_no_selector? added to DSL
|
13
|
+
* Multiple selects return correct values under C[cu]lerity
|
14
|
+
* Naked query strings are handled correctly by rack-test
|
15
|
+
|
1
16
|
# Version 0.4.0.rc
|
2
17
|
|
3
|
-
Release date:
|
18
|
+
Release date: 2010-10-12
|
4
19
|
|
5
20
|
### Changed
|
6
21
|
|
data/README.rdoc
CHANGED
@@ -382,19 +382,28 @@ Alternatively you can set the default selector to XPath:
|
|
382
382
|
Capybara allows you to add custom selectors, which can be very useful if you
|
383
383
|
find yourself using the same kinds of selectors very often:
|
384
384
|
|
385
|
-
Capybara
|
386
|
-
|
385
|
+
Capybara.add_selector(:id) do
|
386
|
+
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
387
|
+
end
|
388
|
+
|
389
|
+
Capybara.add_selector(:row) do
|
390
|
+
xpath { |num| ".//tbody/tr[#{num}]" }
|
391
|
+
end
|
387
392
|
|
388
|
-
|
389
|
-
generated through the XPath gem. You can now use these
|
393
|
+
The block given to xpath must always return an XPath expression as a String, or
|
394
|
+
an XPath expression generated through the XPath gem. You can now use these
|
395
|
+
selectors like this:
|
390
396
|
|
391
397
|
find(:id, 'post_123')
|
392
398
|
find(:row, 3)
|
393
399
|
|
394
|
-
You can specify an optional
|
395
|
-
selector if it matches the argument
|
400
|
+
You can specify an optional match option which will automatically use the
|
401
|
+
selector if it matches the argument:
|
396
402
|
|
397
|
-
Capybara
|
403
|
+
Capybara.add_selector(:id) do
|
404
|
+
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
405
|
+
match { |value| value.is_a?(Symbol) }
|
406
|
+
end
|
398
407
|
|
399
408
|
Now use it like this:
|
400
409
|
|
data/lib/capybara.rb
CHANGED
@@ -64,6 +64,46 @@ module Capybara
|
|
64
64
|
drivers[name] = block
|
65
65
|
end
|
66
66
|
|
67
|
+
##
|
68
|
+
#
|
69
|
+
# Add a new selector to Capybara. Selectors can be used by various methods in Capybara
|
70
|
+
# to find certain elements on the page in a more convenient way. For example adding a
|
71
|
+
# selector to find certain table rows might look like this:
|
72
|
+
#
|
73
|
+
# Capybara.add_selector(:row) do
|
74
|
+
# xpath { |num| ".//tbody/tr[#{num}]" }
|
75
|
+
# end
|
76
|
+
#
|
77
|
+
# This makes it possible to use this selector in a cariety of ways:
|
78
|
+
#
|
79
|
+
# find(:row, 3)
|
80
|
+
# page.find('table#myTable').find(:row, 3).text
|
81
|
+
# page.find('table#myTable').has_selector?(:row, 3)
|
82
|
+
# within(:row, 3) { page.should have_content('$100.000') }
|
83
|
+
#
|
84
|
+
# It might be convenient to specify that the selector is automatically chosen for certain
|
85
|
+
# values. This way you don't have to explicitely specify that you are looking for a row, or
|
86
|
+
# an id. Let's say we want Capybara to treat any Symbols sent into methods like find to be
|
87
|
+
# treated as though they were element ids. We could achieve this like so:
|
88
|
+
#
|
89
|
+
# Capybara.add_selector(:id) do
|
90
|
+
# xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
91
|
+
# match { |value| value.is_a?(Symbol) }
|
92
|
+
# end
|
93
|
+
#
|
94
|
+
# Now we can retrieve elements by id like this:
|
95
|
+
#
|
96
|
+
# find(:post_123)
|
97
|
+
#
|
98
|
+
# Note that this particular selector already ships with Capybara.
|
99
|
+
#
|
100
|
+
# @param [Symbol] name The name of the selector to add
|
101
|
+
# @yield A block executed in the context of the new {Capybara::Selector}
|
102
|
+
#
|
103
|
+
def add_selector(name, &block)
|
104
|
+
Capybara::Selector.add(name, &block)
|
105
|
+
end
|
106
|
+
|
67
107
|
def drivers
|
68
108
|
@drivers ||= {}
|
69
109
|
end
|
@@ -103,7 +143,7 @@ Capybara.register_driver :rack_test do |app|
|
|
103
143
|
end
|
104
144
|
|
105
145
|
Capybara.register_driver :celerity do |app|
|
106
|
-
Capybara::Driver::
|
146
|
+
Capybara::Driver::Celerity.new(app)
|
107
147
|
end
|
108
148
|
|
109
149
|
Capybara.register_driver :culerity do |app|
|
@@ -185,6 +185,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
|
|
185
185
|
|
186
186
|
def process(method, path, attributes = {})
|
187
187
|
return if path.gsub(/^#{request_path}/, '') =~ /^#/
|
188
|
+
path = request_path + path if path =~ /^\?/
|
188
189
|
send(method, to_binary(path), to_binary( attributes ), env)
|
189
190
|
follow_redirects!
|
190
191
|
end
|
@@ -8,7 +8,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|
8
8
|
|
9
9
|
def [](name)
|
10
10
|
if name == :value
|
11
|
-
|
11
|
+
value
|
12
12
|
else
|
13
13
|
native.attribute(name.to_s)
|
14
14
|
end
|
@@ -17,10 +17,10 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def value
|
20
|
-
if tag_name == "select" and self[:multiple]
|
20
|
+
if tag_name == "select" and self[:multiple] and not self[:multiple] == "false"
|
21
21
|
native.find_elements(:xpath, ".//option").select { |n| n.selected? }.map { |n| n.value || n.text }
|
22
22
|
else
|
23
|
-
|
23
|
+
native.value
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
data/lib/capybara/selector.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module Capybara
|
2
2
|
class Selector
|
3
|
-
attr_reader :name
|
3
|
+
attr_reader :name
|
4
4
|
|
5
5
|
class << self
|
6
6
|
def all
|
7
7
|
@selectors ||= {}
|
8
8
|
end
|
9
9
|
|
10
|
-
def add(name,
|
11
|
-
all[name.to_sym] = Capybara::Selector.new(name.to_sym,
|
10
|
+
def add(name, &block)
|
11
|
+
all[name.to_sym] = Capybara::Selector.new(name.to_sym, &block)
|
12
12
|
end
|
13
13
|
|
14
14
|
def remove(name)
|
@@ -31,22 +31,40 @@ module Capybara
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
def initialize(name,
|
34
|
+
def initialize(name, &block)
|
35
35
|
@name = name
|
36
|
-
|
37
|
-
|
36
|
+
instance_eval(&block)
|
37
|
+
end
|
38
|
+
|
39
|
+
def xpath(&block)
|
40
|
+
@xpath = block if block
|
41
|
+
@xpath
|
42
|
+
end
|
43
|
+
|
44
|
+
def match(&block)
|
45
|
+
@match = block if block
|
46
|
+
@match
|
38
47
|
end
|
39
48
|
|
40
49
|
def call(locator)
|
41
|
-
@
|
50
|
+
@xpath.call(locator)
|
42
51
|
end
|
43
52
|
|
44
53
|
def match?(locator)
|
45
|
-
@
|
54
|
+
@match and @match.call(locator)
|
46
55
|
end
|
47
56
|
end
|
48
57
|
end
|
49
58
|
|
50
|
-
Capybara
|
51
|
-
|
52
|
-
|
59
|
+
Capybara.add_selector(:xpath) do
|
60
|
+
xpath { |xpath| xpath }
|
61
|
+
end
|
62
|
+
|
63
|
+
Capybara.add_selector(:css) do
|
64
|
+
xpath { |css| XPath.css(css) }
|
65
|
+
end
|
66
|
+
|
67
|
+
Capybara.add_selector(:id) do
|
68
|
+
xpath { |id| XPath.descendant[XPath.attr(:id) == id.to_s] }
|
69
|
+
match { |value| value.is_a?(Symbol) }
|
70
|
+
end
|
data/lib/capybara/session.rb
CHANGED
@@ -32,7 +32,7 @@ module Capybara
|
|
32
32
|
:has_no_content?, :has_no_css?, :has_no_xpath?, :has_xpath?, :locate, :save_and_open_page, :select, :source, :uncheck,
|
33
33
|
:visit, :wait_until, :within, :within_fieldset, :within_table, :within_frame, :within_window, :has_link?, :has_no_link?, :has_button?,
|
34
34
|
:has_no_button?, :has_field?, :has_no_field?, :has_checked_field?, :has_unchecked_field?, :has_no_table?, :has_table?,
|
35
|
-
:unselect, :has_select?, :has_no_select?, :current_path, :
|
35
|
+
:unselect, :has_select?, :has_no_select?, :current_path, :click, :has_selector?, :has_no_selector?
|
36
36
|
]
|
37
37
|
|
38
38
|
attr_reader :mode, :app
|
@@ -16,7 +16,7 @@ shared_examples_for "click_link" do
|
|
16
16
|
@session.click_link('labore')
|
17
17
|
@session.body.should include('Bar')
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
it "should accept partial matches" do
|
21
21
|
@session.click_link('abo')
|
22
22
|
@session.body.should include('Bar')
|
@@ -38,7 +38,7 @@ shared_examples_for "click_link" do
|
|
38
38
|
@session.click_link('some tit')
|
39
39
|
@session.body.should include('Bar')
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
it "should prefer exact matches over partial matches" do
|
43
43
|
@session.click_link('a fine link')
|
44
44
|
@session.body.should include('Bar')
|
@@ -74,12 +74,17 @@ shared_examples_for "click_link" do
|
|
74
74
|
@session.click_link('Redirect')
|
75
75
|
@session.body.should include('You landed')
|
76
76
|
end
|
77
|
-
|
77
|
+
|
78
78
|
it "should follow redirects" do
|
79
79
|
@session.click_link('BackToMyself')
|
80
80
|
@session.body.should include('This is a test')
|
81
81
|
end
|
82
|
-
|
82
|
+
|
83
|
+
it "should add query string to current URL with naked query string" do
|
84
|
+
@session.click_link('Naked Query String')
|
85
|
+
@session.body.should include('Query String sent')
|
86
|
+
end
|
87
|
+
|
83
88
|
it "should do nothing on anchor links" do
|
84
89
|
@session.fill_in("test_field", :with => 'blah')
|
85
90
|
@session.click_link('Anchor')
|
@@ -87,18 +92,18 @@ shared_examples_for "click_link" do
|
|
87
92
|
@session.click_link('Blank Anchor')
|
88
93
|
@session.find_field("test_field").value.should == 'blah'
|
89
94
|
end
|
90
|
-
|
95
|
+
|
91
96
|
it "should do nothing on URL+anchor links for the same page" do
|
92
97
|
@session.fill_in("test_field", :with => 'blah')
|
93
98
|
@session.click_link('Anchor on same page')
|
94
99
|
@session.find_field("test_field").value.should == 'blah'
|
95
100
|
end
|
96
|
-
|
101
|
+
|
97
102
|
it "should follow link on URL+anchor links for a different page" do
|
98
103
|
@session.click_link('Anchor on different page')
|
99
104
|
@session.body.should include('Bar')
|
100
105
|
end
|
101
|
-
|
106
|
+
|
102
107
|
it "raise an error with links with no href" do
|
103
108
|
running do
|
104
109
|
@session.click_link('No Href')
|
@@ -64,7 +64,9 @@ shared_examples_for "find" do
|
|
64
64
|
|
65
65
|
context "with custom selector" do
|
66
66
|
it "should use the custom selector" do
|
67
|
-
Capybara
|
67
|
+
Capybara.add_selector(:monkey) do
|
68
|
+
xpath { |name| ".//*[@id='#{name}_monkey']" }
|
69
|
+
end
|
68
70
|
@session.find(:monkey, 'john').text.should == 'Monkey John'
|
69
71
|
@session.find(:monkey, 'paul').text.should == 'Monkey Paul'
|
70
72
|
end
|
@@ -72,7 +74,10 @@ shared_examples_for "find" do
|
|
72
74
|
|
73
75
|
context "with custom selector with :for option" do
|
74
76
|
it "should use the selector when it matches the :for option" do
|
75
|
-
Capybara
|
77
|
+
Capybara.add_selector(:monkey) do
|
78
|
+
xpath { |num| ".//*[contains(@id, 'monkey')][#{num}]" }
|
79
|
+
match { |value| value.is_a?(Fixnum) }
|
80
|
+
end
|
76
81
|
@session.find(:monkey, '2').text.should == 'Monkey Paul'
|
77
82
|
@session.find(1).text.should == 'Monkey John'
|
78
83
|
@session.find(2).text.should == 'Monkey Paul'
|
@@ -115,7 +120,7 @@ shared_examples_for "find" do
|
|
115
120
|
it "should find the first element using the given locator" do
|
116
121
|
@session.within(:xpath, "//div[@id='for_bar']") do
|
117
122
|
@session.find('.//li').text.should =~ /With Simple HTML/
|
118
|
-
end
|
123
|
+
end
|
119
124
|
end
|
120
125
|
end
|
121
126
|
end
|
@@ -35,6 +35,11 @@
|
|
35
35
|
<input type="text" checked="checked" id="checked_field">
|
36
36
|
<a href="/redirect"><img src="http://www.foobar.sun/dummy_image.jpg" width="20" height="20" alt="very fine image" /></a>
|
37
37
|
<a href="/with_simple_html"><img src="http://www.foobar.sun/dummy_image.jpg" width="20" height="20" alt="fine image" /></a>
|
38
|
+
|
39
|
+
<a href="?query_string=true">Naked Query String</a>
|
40
|
+
<% if params[:query_string] %>
|
41
|
+
<em>Query String sent</em>
|
42
|
+
<% end %>
|
38
43
|
</p>
|
39
44
|
|
40
45
|
<div id="hidden" style="display: none;">
|
data/lib/capybara/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: capybara
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
4
|
+
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 4
|
8
8
|
- 0
|
9
|
-
|
10
|
-
version: 0.4.0.rc
|
9
|
+
version: 0.4.0
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Jonas Nicklas
|
@@ -15,7 +14,7 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date: 2010-10-
|
17
|
+
date: 2010-10-22 00:00:00 +02:00
|
19
18
|
default_executable:
|
20
19
|
dependencies:
|
21
20
|
- !ruby/object:Gem::Dependency
|
@@ -164,9 +163,7 @@ dependencies:
|
|
164
163
|
- 2
|
165
164
|
- 0
|
166
165
|
- 0
|
167
|
-
|
168
|
-
- 22
|
169
|
-
version: 2.0.0.beta.22
|
166
|
+
version: 2.0.0
|
170
167
|
type: :development
|
171
168
|
version_requirements: *id010
|
172
169
|
- !ruby/object:Gem::Dependency
|
@@ -321,13 +318,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
321
318
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
322
319
|
none: false
|
323
320
|
requirements:
|
324
|
-
- - "
|
321
|
+
- - ">="
|
325
322
|
- !ruby/object:Gem::Version
|
326
323
|
segments:
|
327
|
-
-
|
328
|
-
|
329
|
-
- 1
|
330
|
-
version: 1.3.1
|
324
|
+
- 0
|
325
|
+
version: "0"
|
331
326
|
requirements: []
|
332
327
|
|
333
328
|
rubyforge_project: capybara
|