capybara 2.1.0 → 2.2.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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data/History.md +48 -1
  4. data/README.md +22 -18
  5. data/lib/capybara/cucumber.rb +0 -2
  6. data/lib/capybara/driver/base.rb +9 -1
  7. data/lib/capybara/empty.html +4 -0
  8. data/lib/capybara/node/actions.rb +1 -1
  9. data/lib/capybara/node/finders.rb +3 -3
  10. data/lib/capybara/node/matchers.rb +22 -18
  11. data/lib/capybara/node/simple.rb +5 -3
  12. data/lib/capybara/query.rb +1 -0
  13. data/lib/capybara/rack_test/browser.rb +5 -4
  14. data/lib/capybara/rack_test/form.rb +5 -2
  15. data/lib/capybara/rack_test/node.rb +2 -1
  16. data/lib/capybara/result.rb +2 -1
  17. data/lib/capybara/rspec/features.rb +2 -0
  18. data/lib/capybara/rspec/matchers.rb +6 -6
  19. data/lib/capybara/rspec.rb +7 -0
  20. data/lib/capybara/selector.rb +3 -1
  21. data/lib/capybara/selenium/driver.rb +14 -2
  22. data/lib/capybara/selenium/node.rb +18 -5
  23. data/lib/capybara/server.rb +3 -7
  24. data/lib/capybara/session.rb +59 -17
  25. data/lib/capybara/spec/public/test.js +1 -1
  26. data/lib/capybara/spec/session/assert_selector.rb +18 -0
  27. data/lib/capybara/spec/session/attach_file_spec.rb +6 -1
  28. data/lib/capybara/spec/session/check_spec.rb +14 -0
  29. data/lib/capybara/spec/session/choose_spec.rb +14 -0
  30. data/lib/capybara/spec/session/click_button_spec.rb +20 -1
  31. data/lib/capybara/spec/session/fill_in_spec.rb +18 -2
  32. data/lib/capybara/spec/session/go_back_spec.rb +10 -0
  33. data/lib/capybara/spec/session/go_forward_spec.rb +12 -0
  34. data/lib/capybara/spec/session/has_button_spec.rb +24 -0
  35. data/lib/capybara/spec/session/has_field_spec.rb +48 -0
  36. data/lib/capybara/spec/session/has_text_spec.rb +18 -0
  37. data/lib/capybara/spec/session/node_spec.rb +36 -1
  38. data/lib/capybara/spec/session/reset_session_spec.rb +17 -2
  39. data/lib/capybara/spec/session/save_page_spec.rb +10 -4
  40. data/lib/capybara/spec/session/visit_spec.rb +16 -0
  41. data/lib/capybara/spec/session/within_frame_spec.rb +7 -0
  42. data/lib/capybara/spec/session/within_window_spec.rb +7 -0
  43. data/lib/capybara/spec/test_app.rb +1 -0
  44. data/lib/capybara/spec/views/form.erb +40 -0
  45. data/lib/capybara/spec/views/with_html.erb +5 -0
  46. data/lib/capybara/spec/views/with_js.erb +8 -0
  47. data/lib/capybara/version.rb +1 -1
  48. data/lib/capybara.rb +28 -3
  49. data/spec/capybara_spec.rb +1 -1
  50. data/spec/result_spec.rb +14 -0
  51. data/spec/rspec/features_spec.rb +15 -0
  52. data/spec/rspec/matchers_spec.rb +24 -1
  53. data/spec/selenium_spec.rb +9 -2
  54. data/spec/selenium_spec_chrome.rb +21 -0
  55. data/spec/server_spec.rb +13 -5
  56. data.tar.gz.sig +0 -0
  57. metadata +59 -97
  58. metadata.gz.sig +0 -0
@@ -37,8 +37,21 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
37
37
  path_names = value.to_s.empty? ? [] : value
38
38
  native.send_keys(*path_names)
39
39
  elsif tag_name == 'textarea' or tag_name == 'input'
40
- #script can change a readonly element which user input cannot, so dont execute if readonly
41
- driver.browser.execute_script "arguments[0].value = ''", native unless self[:readonly]
40
+ if value.to_s.empty?
41
+ native.clear
42
+ else
43
+ #script can change a readonly element which user input cannot, so dont execute if readonly
44
+ driver.browser.execute_script "arguments[0].value = ''", native unless self[:readonly]
45
+ native.send_keys(value.to_s)
46
+ end
47
+ elsif native.attribute('isContentEditable')
48
+ #ensure we are focused on the element
49
+ script = <<-JS
50
+ var range = document.createRange();
51
+ range.selectNodeContents(arguments[0]);
52
+ window.getSelection().addRange(range);
53
+ JS
54
+ driver.browser.execute_script script, native
42
55
  native.send_keys(value.to_s)
43
56
  end
44
57
  end
@@ -61,7 +74,7 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
61
74
  def hover
62
75
  driver.browser.action.move_to(native).perform
63
76
  end
64
-
77
+
65
78
  def drag_to(element)
66
79
  driver.browser.action.drag_and_drop(native, element.native).perform
67
80
  end
@@ -89,11 +102,11 @@ class Capybara::Selenium::Node < Capybara::Driver::Node
89
102
  def find_xpath(locator)
90
103
  native.find_elements(:xpath, locator).map { |n| self.class.new(driver, n) }
91
104
  end
92
-
105
+
93
106
  def find_css(locator)
94
107
  native.find_elements(:css, locator).map { |n| self.class.new(driver, n) }
95
108
  end
96
-
109
+
97
110
  def ==(other)
98
111
  native == other.native
99
112
  end
@@ -31,13 +31,13 @@ module Capybara
31
31
  end
32
32
  end
33
33
 
34
- attr_reader :app, :port
34
+ attr_reader :app, :port, :host
35
35
 
36
- def initialize(app, port=Capybara.server_port)
36
+ def initialize(app, port=Capybara.server_port, host=Capybara.server_host)
37
37
  @app = app
38
38
  @middleware = Middleware.new(@app)
39
39
  @server_thread = nil # supress warnings
40
- @port = port
40
+ @host, @port = host, port
41
41
  @port ||= Capybara::Server.ports[@app.object_id]
42
42
  @port ||= find_available_port
43
43
  end
@@ -50,10 +50,6 @@ module Capybara
50
50
  @middleware.error
51
51
  end
52
52
 
53
- def host
54
- Capybara.server_host || "127.0.0.1"
55
- end
56
-
57
53
  def responsive?
58
54
  return false if @server_thread && @server_thread.join(0)
59
55
 
@@ -37,10 +37,11 @@ module Capybara
37
37
  :has_no_unchecked_field?, :query, :assert_selector, :assert_no_selector
38
38
  ]
39
39
  SESSION_METHODS = [
40
- :body, :html, :current_url, :current_host, :evaluate_script, :source,
41
- :visit, :within, :within_fieldset, :within_table, :within_frame,
42
- :within_window, :current_path, :save_page, :save_and_open_page,
43
- :save_screenshot, :reset_session!, :response_headers, :status_code,
40
+ :body, :html, :source, :current_url, :current_host, :current_path,
41
+ :execute_script, :evaluate_script, :visit, :go_back, :go_forward,
42
+ :within, :within_fieldset, :within_table, :within_frame, :within_window,
43
+ :save_page, :save_and_open_page, :save_screenshot,
44
+ :reset_session!, :response_headers, :status_code,
44
45
  :title, :has_title?, :has_no_title?, :current_scope
45
46
  ]
46
47
  DSL_METHODS = NODE_METHODS + SESSION_METHODS
@@ -74,8 +75,11 @@ module Capybara
74
75
  # Reset the session, removing all cookies.
75
76
  #
76
77
  def reset!
77
- driver.reset! if @touched
78
- @touched = false
78
+ if @touched
79
+ driver.reset!
80
+ @touched = false
81
+ assert_no_selector :xpath, "/html/body/*"
82
+ end
79
83
  raise @server.error if Capybara.raise_server_errors and @server and @server.error
80
84
  ensure
81
85
  @server.reset_error! if @server
@@ -195,27 +199,54 @@ module Capybara
195
199
 
196
200
  ##
197
201
  #
198
- # Execute the given block for a particular scope on the page. Within will find the first
199
- # element matching the given selector and execute the block scoped to that element:
202
+ # Move back a single entry in the browser's history.
203
+ #
204
+ def go_back
205
+ driver.go_back
206
+ end
207
+
208
+ ##
209
+ #
210
+ # Move forward a single entry in the browser's history.
211
+ #
212
+ def go_forward
213
+ driver.go_forward
214
+ end
215
+
216
+ ##
217
+ #
218
+ # Executes the given block within the context of a node. `within` takes the
219
+ # same options as `find`, as well as a block. For the duration of the
220
+ # block, any command to Capybara will be handled as though it were scoped
221
+ # to the given element.
200
222
  #
201
223
  # within(:xpath, '//div[@id="delivery-address"]') do
202
224
  # fill_in('Street', :with => '12 Main Street')
203
225
  # end
204
226
  #
205
- # It is possible to omit the first parameter, in that case, the selector is assumed to be
206
- # of the type set in Capybara.default_selector.
227
+ # Just as with `find`, if multiple elements match the selector given to
228
+ # `within`, an error will be raised, and just as with `find`, this
229
+ # behaviour can be controlled through the `:match` and `:exact` options.
230
+ #
231
+ # It is possible to omit the first parameter, in that case, the selector is
232
+ # assumed to be of the type set in Capybara.default_selector.
207
233
  #
208
234
  # within('div#delivery-address') do
209
235
  # fill_in('Street', :with => '12 Main Street')
210
236
  # end
211
237
  #
238
+ # Note that a lot of uses of `within` can be replaced more succinctly with
239
+ # chaining:
240
+ #
241
+ # find('div#delivery-address').fill_in('Street', :with => '12 Main Street')
242
+ #
212
243
  # @overload within(*find_args)
213
244
  # @param (see Capybara::Node::Finders#all)
214
245
  #
215
246
  # @overload within(a_node)
216
247
  # @param [Capybara::Node::Base] a_node The node in whose scope the block should be evaluated
217
248
  #
218
- # @raise [Capybara::ElementNotFound] If the scope can't be found before time expires
249
+ # @raise [Capybara::ElementNotFound] If the scope can't be found before time expires
219
250
  #
220
251
  def within(*args)
221
252
  new_scope = if args.first.is_a?(Capybara::Node::Base) then args.first else find(*args) end
@@ -262,9 +293,12 @@ module Capybara
262
293
  # @param [String] name name of a frame
263
294
  #
264
295
  def within_frame(frame_handle)
296
+ scopes.push(nil)
265
297
  driver.within_frame(frame_handle) do
266
298
  yield
267
299
  end
300
+ ensure
301
+ scopes.pop
268
302
  end
269
303
 
270
304
  ##
@@ -275,7 +309,10 @@ module Capybara
275
309
  # @param [String] handle of the window
276
310
  #
277
311
  def within_window(handle, &blk)
312
+ scopes.push(nil)
278
313
  driver.within_window(handle, &blk)
314
+ ensure
315
+ scopes.pop
279
316
  end
280
317
 
281
318
  ##
@@ -313,7 +350,7 @@ module Capybara
313
350
  #
314
351
  def save_page(path=nil)
315
352
  path ||= "capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}#{rand(10**10)}.html"
316
- path = File.expand_path(path, Capybara.save_and_open_page_path) if Capybara.save_and_open_page_path
353
+ path = File.expand_path(path, Capybara.save_and_open_page_path)
317
354
 
318
355
  FileUtils.mkdir_p(File.dirname(path))
319
356
 
@@ -328,10 +365,15 @@ module Capybara
328
365
  # @param [String] file_name The path to where it should be saved [optional]
329
366
  #
330
367
  def save_and_open_page(file_name=nil)
331
- require "launchy"
332
- Launchy.open(save_page(file_name))
333
- rescue LoadError
334
- warn "Please install the launchy gem to open page with save_and_open_page"
368
+ file_name = save_page(file_name)
369
+
370
+ begin
371
+ require "launchy"
372
+ Launchy.open(file_name)
373
+ rescue LoadError
374
+ warn "Page saved to #{file_name} with save_and_open_page."
375
+ warn "Please install the launchy gem to open page automatically."
376
+ end
335
377
  end
336
378
 
337
379
  ##
@@ -382,7 +424,7 @@ module Capybara
382
424
  end
383
425
 
384
426
  def current_scope
385
- scopes.last
427
+ scopes.last || document
386
428
  end
387
429
 
388
430
  private
@@ -35,7 +35,7 @@ $(function() {
35
35
  $('body').append('<p id="focus_event_triggered">Focus Event triggered</p>');
36
36
  });
37
37
  $('#with_change_event').change(function() {
38
- if($(this).val() == '') $(this).val("Can't be empty");
38
+ $('body').append($('<p class="change_event_triggered"></p>').text(this.value));
39
39
  });
40
40
  $('#checkbox_with_event').click(function() {
41
41
  $('body').append('<p id="checkbox_event_triggered">Checkbox event triggered</p>');
@@ -58,6 +58,16 @@ Capybara::SpecHelper.spec '#assert_selector' do
58
58
  expect { @session.assert_selector("//p//a", :text => /Red$/) }.to raise_error(Capybara::ElementNotFound)
59
59
  end
60
60
  end
61
+
62
+ context "with wait", :requires => [:js] do
63
+ it "should find element if it appears before given wait duration" do
64
+ Capybara.using_wait_time(0.1) do
65
+ @session.visit('/with_js')
66
+ @session.click_link('Click me')
67
+ @session.assert_selector(:css, "a#has-been-clicked", :text => "Has been clicked", :wait => 0.9)
68
+ end
69
+ end
70
+ end
61
71
  end
62
72
 
63
73
  Capybara::SpecHelper.spec '#assert_no_selector' do
@@ -120,4 +130,12 @@ Capybara::SpecHelper.spec '#assert_no_selector' do
120
130
  @session.assert_no_selector("//p//a", :text => /Red$/)
121
131
  end
122
132
  end
133
+
134
+ context "with wait", :requires => [:js] do
135
+ it "should not find element if it appears after given wait duration" do
136
+ @session.visit('/with_js')
137
+ @session.click_link('Click me')
138
+ @session.assert_no_selector(:css, "a#has-been-clicked", :text => "Has been clicked", :wait => 0.1)
139
+ end
140
+ end
123
141
  end
@@ -64,13 +64,18 @@ Capybara::SpecHelper.spec "#attach_file" do
64
64
  end
65
65
 
66
66
  it "should not break when using HTML5 multiple file input uploading multiple files" do
67
- 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
67
+ 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/
68
68
  @session.attach_file "Multiple Documents", [@test_file_path, @another_test_file_path]
69
69
  @session.click_button('Upload Multiple')
70
70
  @session.body.should include("2 | ")#number of files
71
71
  @session.body.should include(File.read(@test_file_path))
72
72
  @session.body.should include(File.read(@another_test_file_path))
73
73
  end
74
+
75
+ it "should not send anything when attaching no files to a multiple upload field" do
76
+ @session.click_button('Upload Empty Multiple')
77
+ @session.body.should include("Successfully ignored empty file field")
78
+ end
74
79
  end
75
80
 
76
81
  context "with a locator that doesn't exist" do
@@ -96,4 +96,18 @@ Capybara::SpecHelper.spec "#check" do
96
96
  end.to raise_error(Capybara::ElementNotFound)
97
97
  end
98
98
  end
99
+
100
+ context "with `option` option" do
101
+ it "can check boxes by their value" do
102
+ @session.check('form[pets][]', :option => "cat")
103
+ @session.click_button('awesome')
104
+ extract_results(@session)['pets'].should include('cat')
105
+ end
106
+
107
+ it "should raise an error if option not found" do
108
+ expect do
109
+ @session.check('form[pets][]', :option => "elephant")
110
+ end.to raise_error(Capybara::ElementNotFound)
111
+ end
112
+ end
99
113
  end
@@ -51,4 +51,18 @@ Capybara::SpecHelper.spec "#choose" do
51
51
  end.to raise_error(Capybara::ElementNotFound)
52
52
  end
53
53
  end
54
+
55
+ context "with `option` option" do
56
+ it "can check radio buttons by their value" do
57
+ @session.choose('form[gender]', :option => "male")
58
+ @session.click_button('awesome')
59
+ extract_results(@session)['gender'].should == "male"
60
+ end
61
+
62
+ it "should raise an error if option not found" do
63
+ expect do
64
+ @session.choose('form[gender]', :option => "hermaphrodite")
65
+ end.to raise_error(Capybara::ElementNotFound)
66
+ end
67
+ end
54
68
  end
@@ -102,10 +102,18 @@ Capybara::SpecHelper.spec '#click_button' do
102
102
  @results['gender'].should == 'female'
103
103
  end
104
104
 
105
+ it "should default radio value to 'on' if none specified" do
106
+ @results['valueless_radio'].should == 'on'
107
+ end
108
+
105
109
  it "should serialize check boxes" do
106
110
  @results['pets'].should include('dog', 'hamster')
107
111
  @results['pets'].should_not include('cat')
108
112
  end
113
+
114
+ it "should default checkbox value to 'on' if none specififed" do
115
+ @results['valueless_checkbox'].should == 'on'
116
+ end
109
117
 
110
118
  it "should serialize text areas" do
111
119
  @results['description'].should == 'Descriptive text goes here'
@@ -126,7 +134,11 @@ Capybara::SpecHelper.spec '#click_button' do
126
134
  it "should not serialize a select tag without options" do
127
135
  @results['tendency'].should be_nil
128
136
  end
129
-
137
+
138
+ it "should convert lf to cr/lf in submitted textareas" do
139
+ @results['newline'].should == "\r\nNew line after and before textarea tag\r\n"
140
+ end
141
+
130
142
  it "should not submit disabled fields" do
131
143
  @results['disabled_text_field'].should be_nil
132
144
  @results['disabled_textarea'].should be_nil
@@ -225,6 +237,12 @@ Capybara::SpecHelper.spec '#click_button' do
225
237
  end
226
238
  end
227
239
 
240
+ context "with submit button not associated with any form" do
241
+ it "should not error when clicked" do
242
+ lambda { @session.click_button('no_form_button') }.should_not raise_error
243
+ end
244
+ end
245
+
228
246
  context "with alt given on an image button" do
229
247
  it "should submit the associated form" do
230
248
  @session.click_button('oh hai thar')
@@ -236,6 +254,7 @@ Capybara::SpecHelper.spec '#click_button' do
236
254
  extract_results(@session)['first_name'].should == 'John'
237
255
  end
238
256
  end
257
+
239
258
 
240
259
  context "with value given on an image button" do
241
260
  it "should submit the associated form" do
@@ -57,6 +57,12 @@ Capybara::SpecHelper.spec "#fill_in" do
57
57
  extract_results(@session)['description'].should == 'is <strong>very</strong> secret!'
58
58
  end
59
59
 
60
+ it "should handle newlines in a textarea" do
61
+ @session.fill_in('form_description', :with => "\nSome text\n")
62
+ @session.click_button('awesome')
63
+ extract_results(@session)['description'].should == "\r\nSome text\r\n"
64
+ end
65
+
60
66
  it "should fill in a field with a custom type" do
61
67
  @session.fill_in('Schmooo', :with => 'Schmooo is the game')
62
68
  @session.click_button('awesome')
@@ -109,7 +115,7 @@ Capybara::SpecHelper.spec "#fill_in" do
109
115
  extract_results(@session)['first_name'].should == 'Harry'
110
116
  end
111
117
 
112
- it "casts to string if field has maxlength", :focus => true do
118
+ it "casts to string if field has maxlength" do
113
119
  @session.fill_in(:'form_zipcode', :with => 1234567)
114
120
  @session.click_button('awesome')
115
121
  extract_results(@session)['zipcode'].should == '12345'
@@ -119,7 +125,17 @@ Capybara::SpecHelper.spec "#fill_in" do
119
125
  it 'should only trigger onchange once' do
120
126
  @session.visit('/with_js')
121
127
  @session.fill_in('with_change_event', :with => 'some value')
122
- @session.find(:css, '#with_change_event').value.should == 'some value'
128
+ # click outside the field to trigger the change event
129
+ @session.find(:css, 'body').click
130
+ @session.find(:css, '.change_event_triggered', :match => :one).should have_text 'some value'
131
+ end
132
+
133
+ it 'should trigger change when clearing field' do
134
+ @session.visit('/with_js')
135
+ @session.fill_in('with_change_event', :with => '')
136
+ # click outside the field to trigger the change event
137
+ @session.find(:css, 'body').click
138
+ @session.should have_selector(:css, '.change_event_triggered', :match => :one)
123
139
  end
124
140
  end
125
141
 
@@ -0,0 +1,10 @@
1
+ Capybara::SpecHelper.spec '#go_back', :requires => [:js] do
2
+ it "should fetch a response from the driver from the previous page" do
3
+ @session.visit('/')
4
+ @session.should have_content('Hello world!')
5
+ @session.visit('/foo')
6
+ @session.should have_content('Another World')
7
+ @session.go_back
8
+ @session.should have_content('Hello world!')
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ Capybara::SpecHelper.spec '#go_forward', :requires => [:js] do
2
+ it "should fetch a response from the driver from the previous page" do
3
+ @session.visit('/')
4
+ @session.should have_content('Hello world!')
5
+ @session.visit('/foo')
6
+ @session.should have_content('Another World')
7
+ @session.go_back
8
+ @session.should have_content('Hello world!')
9
+ @session.go_forward
10
+ @session.should have_content('Another World')
11
+ end
12
+ end
@@ -9,9 +9,21 @@ Capybara::SpecHelper.spec '#has_button?' do
9
9
  @session.should have_button(:'crap321')
10
10
  end
11
11
 
12
+ it "should be true for disabled buttons if :disabled => true" do
13
+ @session.should have_button('Disabled button', :disabled => true)
14
+ end
15
+
12
16
  it "should be false if the given button is not on the page" do
13
17
  @session.should_not have_button('monkey')
14
18
  end
19
+
20
+ it "should be false for disabled buttons by default" do
21
+ @session.should_not have_button('Disabled button')
22
+ end
23
+
24
+ it "should be false for disabled buttons if :disabled => false" do
25
+ @session.should_not have_button('Disabled button', :disabled => false)
26
+ end
15
27
  end
16
28
 
17
29
  Capybara::SpecHelper.spec '#has_no_button?' do
@@ -24,7 +36,19 @@ Capybara::SpecHelper.spec '#has_no_button?' do
24
36
  @session.should_not have_no_button('crap321')
25
37
  end
26
38
 
39
+ it "should be true for disabled buttons if :disabled => true" do
40
+ @session.should_not have_no_button('Disabled button', :disabled => true)
41
+ end
42
+
27
43
  it "should be false if the given button is not on the page" do
28
44
  @session.should have_no_button('monkey')
29
45
  end
46
+
47
+ it "should be false for disabled buttons by default" do
48
+ @session.should have_no_button('Disabled button')
49
+ end
50
+
51
+ it "should be false for disabled buttons if :disabled => false" do
52
+ @session.should have_no_button('Disabled button', :disabled => false)
53
+ end
30
54
  end
@@ -121,6 +121,10 @@ Capybara::SpecHelper.spec '#has_checked_field?' do
121
121
  @session.should have_checked_field('Hamster')
122
122
  end
123
123
 
124
+ it "should be true for disabled checkboxes if :disabled => true" do
125
+ @session.should have_checked_field('Disabled Checkbox', :disabled => true)
126
+ end
127
+
124
128
  it "should be false if an unchecked field is on the page" do
125
129
  @session.should_not have_checked_field('form_pets_cat')
126
130
  @session.should_not have_checked_field('Male')
@@ -130,6 +134,14 @@ Capybara::SpecHelper.spec '#has_checked_field?' do
130
134
  @session.should_not have_checked_field('Does Not Exist')
131
135
  end
132
136
 
137
+ it "should be false for disabled checkboxes by default" do
138
+ @session.should_not have_checked_field('Disabled Checkbox')
139
+ end
140
+
141
+ it "should be false for disabled checkboxes if :disabled => false" do
142
+ @session.should_not have_checked_field('Disabled Checkbox', :disabled => false)
143
+ end
144
+
133
145
  it "should be true after an unchecked checkbox is checked" do
134
146
  @session.check('form_pets_cat')
135
147
  @session.should have_checked_field('form_pets_cat')
@@ -159,6 +171,10 @@ Capybara::SpecHelper.spec '#has_no_checked_field?' do
159
171
  @session.should_not have_no_checked_field('Hamster')
160
172
  end
161
173
 
174
+ it "should be false for disabled checkboxes if :disabled => true" do
175
+ @session.should_not have_no_checked_field('Disabled Checkbox', :disabled => true)
176
+ end
177
+
162
178
  it "should be true if an unchecked field is on the page" do
163
179
  @session.should have_no_checked_field('form_pets_cat')
164
180
  @session.should have_no_checked_field('Male')
@@ -167,6 +183,14 @@ Capybara::SpecHelper.spec '#has_no_checked_field?' do
167
183
  it "should be true if no field is on the page" do
168
184
  @session.should have_no_checked_field('Does Not Exist')
169
185
  end
186
+
187
+ it "should be true for disabled checkboxes by default" do
188
+ @session.should have_no_checked_field('Disabled Checkbox')
189
+ end
190
+
191
+ it "should be true for disabled checkboxes if :disabled => false" do
192
+ @session.should have_no_checked_field('Disabled Checkbox', :disabled => false)
193
+ end
170
194
  end
171
195
 
172
196
  Capybara::SpecHelper.spec '#has_unchecked_field?' do
@@ -182,10 +206,22 @@ Capybara::SpecHelper.spec '#has_unchecked_field?' do
182
206
  @session.should have_unchecked_field('Male')
183
207
  end
184
208
 
209
+ it "should be true for disabled unchecked fields if :disabled => true" do
210
+ @session.should have_unchecked_field('Disabled Unchecked Checkbox', :disabled => true)
211
+ end
212
+
185
213
  it "should be false if no field is on the page" do
186
214
  @session.should_not have_unchecked_field('Does Not Exist')
187
215
  end
188
216
 
217
+ it "should be false for disabled unchecked fields by default" do
218
+ @session.should_not have_unchecked_field('Disabled Unchecked Checkbox')
219
+ end
220
+
221
+ it "should be false for disabled unchecked fields if :disabled => false" do
222
+ @session.should_not have_unchecked_field('Disabled Unchecked Checkbox', :disabled => false)
223
+ end
224
+
189
225
  it "should be false after an unchecked checkbox is checked" do
190
226
  @session.check('form_pets_cat')
191
227
  @session.should_not have_unchecked_field('form_pets_cat')
@@ -220,7 +256,19 @@ Capybara::SpecHelper.spec '#has_no_unchecked_field?' do
220
256
  @session.should_not have_no_unchecked_field('Male')
221
257
  end
222
258
 
259
+ it "should be false for disabled unchecked fields if :disabled => true" do
260
+ @session.should_not have_no_unchecked_field('Disabled Unchecked Checkbox', :disabled => true)
261
+ end
262
+
223
263
  it "should be true if no field is on the page" do
224
264
  @session.should have_no_unchecked_field('Does Not Exist')
225
265
  end
266
+
267
+ it "should be true for disabled unchecked fields by default" do
268
+ @session.should have_no_unchecked_field('Disabled Unchecked Checkbox')
269
+ end
270
+
271
+ it "should be true for disabled unchecked fields if :disabled => false" do
272
+ @session.should have_no_unchecked_field('Disabled Unchecked Checkbox', :disabled => false)
273
+ end
226
274
  end
@@ -190,6 +190,16 @@ Capybara::SpecHelper.spec '#has_text?' do
190
190
  @session.should_not have_text('count', minimum: '3')
191
191
  end
192
192
  end
193
+
194
+ context "with wait", :requires => [:js] do
195
+ it "should find element if it appears before given wait duration" do
196
+ Capybara.using_wait_time(0.1) do
197
+ @session.visit('/with_js')
198
+ @session.click_link('Click me')
199
+ @session.should have_text('Has been clicked', :wait => 0.9)
200
+ end
201
+ end
202
+ end
193
203
  end
194
204
 
195
205
  Capybara::SpecHelper.spec '#has_no_text?' do
@@ -288,4 +298,12 @@ Capybara::SpecHelper.spec '#has_no_text?' do
288
298
  @session.click_link('Click me')
289
299
  @session.should have_no_text("I changed it")
290
300
  end
301
+
302
+ context "with wait", :requires => [:js] do
303
+ it "should not find element if it appears after given wait duration" do
304
+ @session.visit('/with_js')
305
+ @session.click_link('Click me')
306
+ @session.should have_no_text('Has been clicked', :wait => 0.1)
307
+ end
308
+ end
291
309
  end