capybara 1.1.2 → 1.1.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -37,6 +37,14 @@ module Capybara
37
37
  self
38
38
  end
39
39
 
40
+ def without_wait
41
+ orig = @wait_disabled
42
+ @wait_disabled = true
43
+ yield
44
+ ensure
45
+ @wait_disabled = orig
46
+ end
47
+
40
48
  protected
41
49
 
42
50
  def wait_until(seconds=Capybara.default_wait_time)
@@ -45,6 +53,7 @@ module Capybara
45
53
  begin
46
54
  yield
47
55
  rescue => e
56
+ raise e if @wait_disabled
48
57
  raise e unless driver.wait?
49
58
  raise e unless (driver.respond_to?(:invalid_element_errors) and driver.invalid_element_errors.include?(e.class)) or e.is_a?(Capybara::ElementNotFound)
50
59
  raise e if (Time.now - start_time) >= seconds
@@ -28,6 +28,10 @@ module Capybara
28
28
  @selector = selector
29
29
  end
30
30
 
31
+ def allow_reload!
32
+ @allow_reload = true
33
+ end
34
+
31
35
  ##
32
36
  #
33
37
  # @return [Object] The native element from the driver, this allows access to driver specific methods
@@ -186,8 +190,10 @@ module Capybara
186
190
  end
187
191
 
188
192
  def reload
189
- reloaded = parent.reload.first(@selector.name, @selector.locator, @selector.options)
190
- @base = reloaded.base if reloaded
193
+ if @allow_reload
194
+ reloaded = parent.reload.first(@selector.name, @selector.locator, @selector.options)
195
+ @base = reloaded.base if reloaded
196
+ end
191
197
  self
192
198
  end
193
199
 
@@ -24,7 +24,7 @@ module Capybara
24
24
  # @raise [Capybara::ElementNotFound] If the element can't be found before time expires
25
25
  #
26
26
  def find(*args)
27
- wait_until { first(*args) or raise_find_error(*args) }
27
+ wait_until { first(*args) or raise_find_error(*args) }.tap(&:allow_reload!)
28
28
  end
29
29
 
30
30
  ##
@@ -107,9 +107,9 @@ module Capybara
107
107
  # @return [Capybara::Element] The found elements
108
108
  #
109
109
  def all(*args)
110
+ selector = Capybara::Selector.normalize(*args)
110
111
  options = extract_normalized_options(args)
111
112
 
112
- selector = Capybara::Selector.normalize(*args)
113
113
  selector.xpaths.
114
114
  map { |path| find_in_base(selector, path) }.flatten.
115
115
  select { |node| matches_options(node, options) }
@@ -129,10 +129,10 @@ module Capybara
129
129
  # @return Capybara::Element The found element
130
130
  #
131
131
  def first(*args)
132
+ selector = Capybara::Selector.normalize(*args)
132
133
  options = extract_normalized_options(args)
133
134
  found_elements = []
134
135
 
135
- selector = Capybara::Selector.normalize(*args)
136
136
  selector.xpaths.each do |path|
137
137
  find_in_base(selector, path).each do |node|
138
138
  if matches_options(node, options)
@@ -179,13 +179,15 @@ module Capybara
179
179
  end
180
180
 
181
181
  def matches_options(node, options)
182
- return false if options[:text] and not node.text.match(options[:text])
183
- return false if options[:visible] and not node.visible?
184
- return false if options[:with] and not node.value == options[:with]
185
- return false if options[:checked] and not node.checked?
186
- return false if options[:unchecked] and node.checked?
187
- return false if options[:selected] and not has_selected_options?(node, options[:selected])
188
- true
182
+ node.without_wait do
183
+ return false if options[:text] and not node.text.match(options[:text])
184
+ return false if options[:visible] and not node.visible?
185
+ return false if options[:with] and not node.value == options[:with]
186
+ return false if options[:checked] and not node.checked?
187
+ return false if options[:unchecked] and node.checked?
188
+ return false if options[:selected] and not has_selected_options?(node, options[:selected])
189
+ true
190
+ end
189
191
  end
190
192
 
191
193
  def has_selected_options?(node, expected)
@@ -74,7 +74,7 @@ module Capybara
74
74
  #
75
75
  def value
76
76
  if tag_name == 'textarea'
77
- native.content
77
+ native.content.sub(/\A\n/, '')
78
78
  elsif tag_name == 'select'
79
79
  if native['multiple'] == 'multiple'
80
80
  native.xpath(".//option[@selected='selected']").map { |option| option[:value] || option.content }
@@ -118,6 +118,14 @@ module Capybara
118
118
  native[:selected]
119
119
  end
120
120
 
121
+ def allow_reload!
122
+ # no op
123
+ end
124
+
125
+ def without_wait
126
+ yield
127
+ end
128
+
121
129
  protected
122
130
 
123
131
  def find_in_base(selector, xpath)
@@ -122,7 +122,9 @@ class Capybara::Selenium::Driver < Capybara::Driver::Base
122
122
  end
123
123
 
124
124
  def invalid_element_errors
125
- [Selenium::WebDriver::Error::ObsoleteElementError]
125
+ [ Selenium::WebDriver::Error::StaleElementReferenceError,
126
+ Selenium::WebDriver::Error::InvalidSelectorError,
127
+ Selenium::WebDriver::Error::UnknownError ]
126
128
  end
127
129
 
128
130
  private
@@ -64,7 +64,11 @@ shared_examples_for 'driver' do
64
64
  end
65
65
 
66
66
  it "should allow retrieval of the value" do
67
- @driver.find('//textarea').first.value.should == 'banana'
67
+ @driver.find('//textarea[@id="normal"]').first.value.should == 'banana'
68
+ end
69
+
70
+ it "should not swallow extra newlines in textarea" do
71
+ @driver.find('//textarea[@id="additional_newline"]').first.value.should == "\nbanana"
68
72
  end
69
73
 
70
74
  it "should allow assignment of field value" do
@@ -37,7 +37,12 @@ $(function() {
37
37
  });
38
38
  $('#reload-link').click(function() {
39
39
  setTimeout(function() {
40
- $('#reload-me').replaceWith('<div id="reload-me"><em><a>RELOADED</a></em></div>');
40
+ $('#reload-me').replaceWith('<div id="reload-me"><em><a>has been reloaded</a></em></div>');
41
+ }, 250)
42
+ });
43
+ $('#reload-list').click(function() {
44
+ setTimeout(function() {
45
+ $('#the-list').html('<li>Foo</li><li>Bar</li>');
41
46
  }, 250)
42
47
  });
43
48
  });
@@ -26,8 +26,8 @@ shared_examples_for "session with javascript support" do
26
26
  node = @session.find(:css, '#reload-me')
27
27
  @session.click_link('Reload!')
28
28
  sleep(0.3)
29
- node.reload.text.should == 'RELOADED'
30
- node.text.should == 'RELOADED'
29
+ node.reload.text.should == 'has been reloaded'
30
+ node.text.should == 'has been reloaded'
31
31
  end
32
32
 
33
33
  it "should reload a parent node" do
@@ -35,8 +35,8 @@ shared_examples_for "session with javascript support" do
35
35
  node = @session.find(:css, '#reload-me').find(:css, 'em')
36
36
  @session.click_link('Reload!')
37
37
  sleep(0.3)
38
- node.reload.text.should == 'RELOADED'
39
- node.text.should == 'RELOADED'
38
+ node.reload.text.should == 'has been reloaded'
39
+ node.text.should == 'has been reloaded'
40
40
  end
41
41
 
42
42
  it "should not automatically reload" do
@@ -44,7 +44,7 @@ shared_examples_for "session with javascript support" do
44
44
  node = @session.find(:css, '#reload-me')
45
45
  @session.click_link('Reload!')
46
46
  sleep(0.3)
47
- running { node.text.should == 'RELOADED' }.should raise_error
47
+ running { node.text.should == 'has been reloaded' }.should raise_error
48
48
  end
49
49
  after { Capybara.automatic_reload = true }
50
50
  end
@@ -55,7 +55,7 @@ shared_examples_for "session with javascript support" do
55
55
  node = @session.find(:css, '#reload-me')
56
56
  @session.click_link('Reload!')
57
57
  sleep(0.3)
58
- node.text.should == 'RELOADED'
58
+ node.text.should == 'has been reloaded'
59
59
  end
60
60
 
61
61
  it "should reload a parent node automatically" do
@@ -63,7 +63,7 @@ shared_examples_for "session with javascript support" do
63
63
  node = @session.find(:css, '#reload-me').find(:css, 'em')
64
64
  @session.click_link('Reload!')
65
65
  sleep(0.3)
66
- node.text.should == 'RELOADED'
66
+ node.text.should == 'has been reloaded'
67
67
  end
68
68
 
69
69
  it "should reload a node automatically when using find" do
@@ -71,7 +71,24 @@ shared_examples_for "session with javascript support" do
71
71
  node = @session.find(:css, '#reload-me')
72
72
  @session.click_link('Reload!')
73
73
  sleep(0.3)
74
- node.find(:css, 'a').text.should == 'RELOADED'
74
+ node.find(:css, 'a').text.should == 'has been reloaded'
75
+ end
76
+
77
+ it "should not reload nodes which haven't been found" do
78
+ @session.visit('/with_js')
79
+ node = @session.all(:css, '#the-list li')[1]
80
+ @session.click_link('Fetch new list!')
81
+ sleep(0.3)
82
+ running { node.text.should == 'Foo' }.should raise_error
83
+ running { node.text.should == 'Bar' }.should raise_error
84
+ end
85
+
86
+ it "should reload nodes with options" do
87
+ @session.visit('/with_js')
88
+ node = @session.find(:css, 'em', :text => "reloaded")
89
+ @session.click_link('Reload!')
90
+ sleep(1)
91
+ node.text.should == 'has been reloaded'
75
92
  end
76
93
  end
77
94
  end
@@ -107,7 +107,7 @@ class TestApp < Sinatra::Base
107
107
  end
108
108
 
109
109
  post '/upload_empty' do
110
- if params[:form][:file].nil?
110
+ if params[:form].nil? || params[:form][:file].nil?
111
111
  'Successfully ignored empty file field.'
112
112
  else
113
113
  'Something went wrong.'
@@ -28,7 +28,11 @@
28
28
 
29
29
  <p>
30
30
  <input type="text" id="test_field" value="monkey"/>
31
- <textarea>banana</textarea>
31
+ <textarea id="normal">
32
+ banana</textarea>
33
+ <textarea id="additional_newline">
34
+
35
+ banana</textarea>
32
36
  <a href="/redirect_back">BackToMyself</a>
33
37
  <a title="twas a fine link" href="/redirect">A link came first</a>
34
38
  <a title="a fine link" href="/with_simple_html">A link</a>
@@ -41,8 +41,22 @@
41
41
 
42
42
  <p>
43
43
  <a id="reload-link" href="#">Reload!</a>
44
+ <em>this won't change</em>
44
45
  <div id="reload-me"><em>waiting to be reloaded</em></div>
45
46
  </p>
47
+
48
+ <p>
49
+ <a id="reload-list" href="#">Fetch new list!</a>
50
+ <ul id="the-list">
51
+ <li>Item 1</li>
52
+ <li>Item 2</li>
53
+ </ul>
54
+ </p>
55
+
56
+ <script type="text/javascript">
57
+ // a javascript comment
58
+ var aVar = 123;
59
+ </script>
46
60
  </body>
47
61
  </html>
48
62
 
@@ -1,3 +1,3 @@
1
1
  module Capybara
2
- VERSION = '1.1.2'
2
+ VERSION = '1.1.3'
3
3
  end
@@ -14,19 +14,6 @@ describe Capybara::Selenium::Driver do
14
14
  it_should_behave_like "driver without status code support"
15
15
  it_should_behave_like "driver with cookies support"
16
16
 
17
- unless Config::CONFIG['host_os'] =~ /mswin|mingw/
18
- it "should not interfere with forking child processes" do
19
- # Launch a browser, which registers the at_exit hook
20
- browser = Capybara::Selenium::Driver.new(TestApp).browser
21
-
22
- # Fork an unrelated child process. This should not run the code in the at_exit hook.
23
- pid = fork { "child" }
24
- Process.wait2(pid)[1].exitstatus.should == 0
25
-
26
- browser.quit
27
- end
28
- end
29
-
30
17
  describe "exit codes" do
31
18
  before do
32
19
  @current_dir = Dir.getwd
@@ -11,6 +11,7 @@ describe Capybara::DSL do
11
11
  after do
12
12
  Capybara.session_name = nil
13
13
  Capybara.default_driver = nil
14
+ Capybara.javascript_driver = nil
14
15
  Capybara.use_default_driver
15
16
  end
16
17
 
@@ -3,7 +3,7 @@ require 'capybara/rspec'
3
3
 
4
4
  Capybara.app = TestApp
5
5
 
6
- RSpec.configuration.before(:each, :example_group => {:file_path => __FILE__}) do
6
+ RSpec.configuration.before(:each, :example_group => {:file_path => "./spec/rspec/features_spec.rb"}) do
7
7
  @in_filtered_hook = true
8
8
  end
9
9
 
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: 1.1.2
4
+ version: 1.1.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-15 00:00:00.000000000 Z
12
+ date: 2012-10-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
16
- requirement: &2152404620 !ruby/object:Gem::Requirement
16
+ requirement: &2151926160 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 1.3.3
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2152404620
24
+ version_requirements: *2151926160
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mime-types
27
- requirement: &2152399360 !ruby/object:Gem::Requirement
27
+ requirement: &2151922440 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '1.16'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2152399360
35
+ version_requirements: *2151922440
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: selenium-webdriver
38
- requirement: &2152397660 !ruby/object:Gem::Requirement
38
+ requirement: &2151935300 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ~>
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '2.0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2152397660
46
+ version_requirements: *2151935300
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rack
49
- requirement: &2152396320 !ruby/object:Gem::Requirement
49
+ requirement: &2151934440 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *2152396320
57
+ version_requirements: *2151934440
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rack-test
60
- requirement: &2152395280 !ruby/object:Gem::Requirement
60
+ requirement: &2151933220 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 0.5.4
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *2152395280
68
+ version_requirements: *2151933220
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: xpath
71
- requirement: &2152394120 !ruby/object:Gem::Requirement
71
+ requirement: &2151943440 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ~>
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: 0.1.4
77
77
  type: :runtime
78
78
  prerelease: false
79
- version_requirements: *2152394120
79
+ version_requirements: *2151943440
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: sinatra
82
- requirement: &2152392600 !ruby/object:Gem::Requirement
82
+ requirement: &2151942160 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,10 +87,10 @@ dependencies:
87
87
  version: 0.9.4
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *2152392600
90
+ version_requirements: *2151942160
91
91
  - !ruby/object:Gem::Dependency
92
92
  name: rspec
93
- requirement: &2152391040 !ruby/object:Gem::Requirement
93
+ requirement: &2151941460 !ruby/object:Gem::Requirement
94
94
  none: false
95
95
  requirements:
96
96
  - - ! '>='
@@ -98,10 +98,10 @@ dependencies:
98
98
  version: 2.0.0
99
99
  type: :development
100
100
  prerelease: false
101
- version_requirements: *2152391040
101
+ version_requirements: *2151941460
102
102
  - !ruby/object:Gem::Dependency
103
103
  name: launchy
104
- requirement: &2152388240 !ruby/object:Gem::Requirement
104
+ requirement: &2151940240 !ruby/object:Gem::Requirement
105
105
  none: false
106
106
  requirements:
107
107
  - - ~>
@@ -109,10 +109,10 @@ dependencies:
109
109
  version: 2.0.4
110
110
  type: :development
111
111
  prerelease: false
112
- version_requirements: *2152388240
112
+ version_requirements: *2151940240
113
113
  - !ruby/object:Gem::Dependency
114
114
  name: yard
115
- requirement: &2152383200 !ruby/object:Gem::Requirement
115
+ requirement: &2151939320 !ruby/object:Gem::Requirement
116
116
  none: false
117
117
  requirements:
118
118
  - - ! '>='
@@ -120,10 +120,10 @@ dependencies:
120
120
  version: 0.5.8
121
121
  type: :development
122
122
  prerelease: false
123
- version_requirements: *2152383200
123
+ version_requirements: *2151939320
124
124
  - !ruby/object:Gem::Dependency
125
125
  name: fuubar
126
- requirement: &2152381360 !ruby/object:Gem::Requirement
126
+ requirement: &2151938480 !ruby/object:Gem::Requirement
127
127
  none: false
128
128
  requirements:
129
129
  - - ! '>='
@@ -131,10 +131,10 @@ dependencies:
131
131
  version: 0.0.1
132
132
  type: :development
133
133
  prerelease: false
134
- version_requirements: *2152381360
134
+ version_requirements: *2151938480
135
135
  - !ruby/object:Gem::Dependency
136
136
  name: cucumber
137
- requirement: &2152379900 !ruby/object:Gem::Requirement
137
+ requirement: &2151937200 !ruby/object:Gem::Requirement
138
138
  none: false
139
139
  requirements:
140
140
  - - ! '>='
@@ -142,7 +142,18 @@ dependencies:
142
142
  version: '0.10'
143
143
  type: :development
144
144
  prerelease: false
145
- version_requirements: *2152379900
145
+ version_requirements: *2151937200
146
+ - !ruby/object:Gem::Dependency
147
+ name: rake
148
+ requirement: &2151936560 !ruby/object:Gem::Requirement
149
+ none: false
150
+ requirements:
151
+ - - ! '>='
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ type: :development
155
+ prerelease: false
156
+ version_requirements: *2151936560
146
157
  description: Capybara is an integration testing tool for rack based web applications.
147
158
  It simulates how a user would interact with a website
148
159
  email:
@@ -284,3 +295,4 @@ specification_version: 3
284
295
  summary: Capybara aims to simplify the process of integration testing Rack applications,
285
296
  such as Rails, Sinatra or Merb
286
297
  test_files: []
298
+ has_rdoc: