capybara 0.3.8 → 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/History.txt +21 -0
  2. data/README.rdoc +33 -2
  3. data/lib/capybara.rb +5 -4
  4. data/lib/capybara/driver/base.rb +12 -0
  5. data/lib/capybara/driver/celerity_driver.rb +15 -2
  6. data/lib/capybara/driver/rack_test_driver.rb +30 -22
  7. data/lib/capybara/driver/selenium_driver.rb +10 -9
  8. data/lib/capybara/rails.rb +0 -1
  9. data/lib/capybara/save_and_open_page.rb +4 -1
  10. data/lib/capybara/session.rb +16 -2
  11. data/lib/capybara/spec/driver.rb +62 -6
  12. data/lib/capybara/spec/session.rb +46 -0
  13. data/lib/capybara/spec/session/click_button_spec.rb +7 -0
  14. data/lib/capybara/spec/session/fill_in_spec.rb +12 -1
  15. data/lib/capybara/spec/session/javascript.rb +9 -1
  16. data/lib/capybara/spec/session/locate_spec.rb +6 -0
  17. data/lib/capybara/spec/session/response_code.rb +19 -0
  18. data/lib/capybara/spec/session/select_spec.rb +14 -0
  19. data/lib/capybara/spec/test_app.rb +21 -2
  20. data/lib/capybara/spec/views/form.erb +12 -1
  21. data/lib/capybara/spec/views/with_html.erb +1 -0
  22. data/lib/capybara/version.rb +1 -1
  23. data/lib/capybara/xpath.rb +3 -3
  24. data/spec/driver/celerity_driver_spec.rb +2 -1
  25. data/spec/driver/culerity_driver_spec.rb +3 -2
  26. data/spec/driver/rack_test_driver_spec.rb +10 -2
  27. data/spec/driver/remote_culerity_driver_spec.rb +3 -2
  28. data/spec/driver/remote_selenium_driver_spec.rb +1 -0
  29. data/spec/driver/selenium_driver_spec.rb +2 -0
  30. data/spec/save_and_open_page_spec.rb +53 -13
  31. data/spec/session/celerity_session_spec.rb +2 -1
  32. data/spec/session/culerity_session_spec.rb +2 -1
  33. data/spec/session/rack_test_session_spec.rb +1 -0
  34. data/spec/session/selenium_session_spec.rb +1 -0
  35. metadata +44 -6
@@ -1,3 +1,24 @@
1
+ # Version 0.3.9
2
+
3
+ Release data: 2010-07-03
4
+
5
+ ### Added
6
+
7
+ * status_code which returns the HTTP status code of the last response (no Selenium!)
8
+ * Capybara.save_and_open_page to store tempfiles
9
+ * RackTest and Culerity drivers now clean up after themselves properly
10
+
11
+ ### Fixed
12
+
13
+ * When no rack app is set and the app is called, a more descriptive error is raised
14
+ * select now works with optgroups
15
+ * Don't submit image buttons unless they were clicked under rack-test
16
+ * Support custom field types under Selenium
17
+ * Support input fields without a type, treat them as though they were text fields
18
+ * Redirect now throws an error after 5 redirects, as per RFC
19
+ * Selenium now properly raises an error when Node#trigger is called
20
+ * Node#value now returns the correct value for textareas under rack-test
21
+
1
22
  # Version 0.3.8
2
23
 
3
24
  Release date: 2010-05-12
@@ -8,7 +8,8 @@ Capybara aims to simplify the process of integration testing Rack applications,
8
8
  such as Rails, Sinatra or Merb. It is inspired by and aims to replace Webrat as
9
9
  a DSL for interacting with a webapplication. It is agnostic about the driver
10
10
  running your tests and currently comes bundled with rack-test, Culerity,
11
- Celerity and Selenium support built in.
11
+ Celerity and Selenium support built in. env.js support is available as the
12
+ {capybara-envjs gem}[http://github.com/smparkes/capybara-envjs].
12
13
 
13
14
  == Install:
14
15
 
@@ -123,6 +124,16 @@ being.
123
124
  Install celerity as noted above, make sure JRuby is in your path. Note that
124
125
  Culerity doesn't seem to be working under Ruby 1.9 at the moment.
125
126
 
127
+ == env.js
128
+
129
+ The {capybara-envjs driver}[http://github.com/smparkes/capybara-envjs]
130
+ uses the envjs gem ({GitHub}[http://github.com/smparkes/env-js],
131
+ {rubygems.org}[http://rubygems.org/gems/envjs]) to interpret
132
+ JavaScript outside the browser. The driver is installed by installing the capybara-envjs gem:
133
+ gem install capybara-envjs
134
+ More info about the driver and env.js are available through the links above. The envjs gem only supports
135
+ Ruby 1.8.7 at this time.
136
+
126
137
  == The DSL
127
138
 
128
139
  Capybara's DSL is inspired by Webrat. While backwards compatibility is retained
@@ -141,6 +152,10 @@ You can use the <tt>visit</tt> method to navigate to other pages:
141
152
  The visit method only takes a single parameter, the request method is *always*
142
153
  GET.
143
154
 
155
+ You can get the current path of the browsing session for test assertions:
156
+
157
+ current_path.should == post_comments_path(post)
158
+
144
159
  === Clicking links and buttons
145
160
 
146
161
  You can interact with the webapp by following links and buttons. Capybara
@@ -196,6 +211,17 @@ specific table, identified by either id or text of the table's caption tag.
196
211
  fill_in 'Name', :with => 'Jimmy'
197
212
  end
198
213
 
214
+ You can also specify a scope to be used for future searches with the <tt>scope_to</tt>.
215
+ It returns a handle to the session scoped to the provided selector.
216
+
217
+ scope = page.scope_to("//div[@id='foo']")
218
+ scope.has_xpath("//a[@class='bar']")
219
+
220
+ You can also chain scopes by calling <tt>scope_to</tt> on an existing scope.
221
+
222
+ more_scope = scope.scope_to("//p")
223
+ more_scope.has_xpath("//a[@class='baz']")
224
+
199
225
  === Querying
200
226
 
201
227
  Capybara has a rich set of options for querying the page for the existence of
@@ -228,7 +254,12 @@ You can also find specific elements, in order to manipulate them:
228
254
 
229
255
  === Scripting
230
256
 
231
- In drivers which support it, you can easily evaluate JavaScript:
257
+ In drivers which support it, you can easily execute JavaScript:
258
+
259
+ page.execute_script("$('body').empty()")
260
+
261
+ For simple expressions, you can return the result of the script. Note
262
+ that this may break with more complicated expressions:
232
263
 
233
264
  result = page.evaluate_script('4 + 4');
234
265
 
@@ -11,15 +11,16 @@ module Capybara
11
11
  class TimeoutError < CapybaraError; end
12
12
  class LocateHiddenElementError < CapybaraError; end
13
13
  class InfiniteRedirectError < TimeoutError; end
14
-
14
+
15
15
  class << self
16
16
  attr_accessor :debug, :asset_root, :app_host, :run_server, :default_host
17
17
  attr_accessor :default_selector, :default_wait_time, :ignore_hidden_elements
18
+ attr_accessor :save_and_open_page_path
18
19
 
19
20
  def default_selector
20
21
  @default_selector ||= :xpath
21
22
  end
22
-
23
+
23
24
  def default_wait_time
24
25
  @default_wait_time ||= 2
25
26
  end
@@ -29,14 +30,14 @@ module Capybara
29
30
  true
30
31
  end
31
32
  end
32
-
33
+
33
34
  autoload :Server, 'capybara/server'
34
35
  autoload :Session, 'capybara/session'
35
36
  autoload :Node, 'capybara/node'
36
37
  autoload :XPath, 'capybara/xpath'
37
38
  autoload :Searchable, 'capybara/searchable'
38
39
  autoload :VERSION, 'capybara/version'
39
-
40
+
40
41
  module Driver
41
42
  autoload :Base, 'capybara/driver/base'
42
43
  autoload :RackTest, 'capybara/driver/rack_test_driver'
@@ -3,6 +3,10 @@ class Capybara::Driver::Base
3
3
  raise NotImplementedError
4
4
  end
5
5
 
6
+ def current_path
7
+ URI.parse(current_url).path
8
+ end
9
+
6
10
  def visit(path)
7
11
  raise NotImplementedError
8
12
  end
@@ -11,6 +15,10 @@ class Capybara::Driver::Base
11
15
  raise NotImplementedError
12
16
  end
13
17
 
18
+ def execute_script(script)
19
+ raise Capybara::NotSupportedByDriverError
20
+ end
21
+
14
22
  def evaluate_script(script)
15
23
  raise Capybara::NotSupportedByDriverError
16
24
  end
@@ -25,6 +33,10 @@ class Capybara::Driver::Base
25
33
  def response_headers
26
34
  raise Capybara::NotSupportedByDriverError
27
35
  end
36
+
37
+ def status_code
38
+ raise Capybara::NotSupportedByDriverError
39
+ end
28
40
 
29
41
  def body
30
42
  raise NotImplementedError
@@ -72,7 +72,7 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
72
72
  def path
73
73
  node.xpath
74
74
  end
75
-
75
+
76
76
  def trigger(event)
77
77
  node.fire_event(event.to_s)
78
78
  end
@@ -102,7 +102,7 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
102
102
  def current_url
103
103
  browser.url
104
104
  end
105
-
105
+
106
106
  def source
107
107
  browser.html
108
108
  end
@@ -115,12 +115,21 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
115
115
  browser.response_headers
116
116
  end
117
117
 
118
+ def status_code
119
+ browser.status_code
120
+ end
121
+
118
122
  def find(selector)
119
123
  browser.elements_by_xpath(selector).map { |node| Node.new(self, node) }
120
124
  end
121
125
 
122
126
  def wait?; true; end
123
127
 
128
+ def execute_script(script)
129
+ browser.execute_script script
130
+ nil
131
+ end
132
+
124
133
  def evaluate_script(script)
125
134
  browser.execute_script "#{script}"
126
135
  end
@@ -134,6 +143,10 @@ class Capybara::Driver::Celerity < Capybara::Driver::Base
134
143
  @_browser
135
144
  end
136
145
 
146
+ def cleanup!
147
+ browser.clear_cookies
148
+ end
149
+
137
150
  private
138
151
 
139
152
  def url(path)
@@ -26,6 +26,13 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
26
26
  end
27
27
  end
28
28
 
29
+ def value
30
+ if tag_name == 'textarea'
31
+ node.content
32
+ else
33
+ super
34
+ end
35
+ end
29
36
 
30
37
  def set(value)
31
38
  if tag_name == 'input' and type == 'radio'
@@ -112,7 +119,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
112
119
  def params(button)
113
120
  params = {}
114
121
 
115
- node.xpath(".//input[@type!='radio' and @type!='checkbox' and @type!='submit']").map do |input|
122
+ node.xpath(".//input[not(@type) or (@type!='radio' and @type!='checkbox' and @type!='submit' and @type!='image')]").map do |input|
116
123
  merge_param!(params, input['name'].to_s, input['value'].to_s)
117
124
  end
118
125
  node.xpath(".//textarea").map do |textarea|
@@ -183,6 +190,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
183
190
  alias_method :request, :last_request
184
191
 
185
192
  def initialize(app)
193
+ raise ArgumentError, "rack-test requires a rack application, but none was given" unless app
186
194
  @app = app
187
195
  end
188
196
 
@@ -191,7 +199,7 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
191
199
  end
192
200
 
193
201
  def process(method, path, attributes = {})
194
- return if path.gsub(/^#{current_path}/, '') =~ /^#/
202
+ return if path.gsub(/^#{request_path}/, '') =~ /^#/
195
203
  send(method, path, attributes, env)
196
204
  follow_redirects!
197
205
  end
@@ -204,8 +212,12 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
204
212
  response.headers
205
213
  end
206
214
 
215
+ def status_code
216
+ response.status
217
+ end
218
+
207
219
  def submit(method, path, attributes)
208
- path = current_path if not path or path.empty?
220
+ path = request_path if not path or path.empty?
209
221
  send(method, path, attributes, env)
210
222
  follow_redirects!
211
223
  end
@@ -213,21 +225,32 @@ class Capybara::Driver::RackTest < Capybara::Driver::Base
213
225
  def find(selector)
214
226
  html.xpath(selector).map { |node| Node.new(self, node) }
215
227
  end
216
-
228
+
217
229
  def body
218
230
  @body ||= response.body
219
231
  end
220
-
232
+
221
233
  def html
222
234
  @html ||= Nokogiri::HTML(body)
223
235
  end
224
236
  alias_method :source, :body
225
237
 
238
+ def cleanup!
239
+ clear_cookies
240
+ end
241
+
226
242
  def get(*args, &block); reset_cache; super; end
227
243
  def post(*args, &block); reset_cache; super; end
228
244
  def put(*args, &block); reset_cache; super; end
229
245
  def delete(*args, &block); reset_cache; super; end
230
-
246
+
247
+ def follow_redirects!
248
+ 5.times do
249
+ follow_redirect! if response.redirect?
250
+ end
251
+ raise Capybara::InfiniteRedirectError, "redirected more than 5 times, check for infinite redirects." if response.redirect?
252
+ end
253
+
231
254
  private
232
255
 
233
256
  def reset_cache
@@ -239,20 +262,10 @@ private
239
262
  Rack::MockSession.new(app, Capybara.default_host || "www.example.com")
240
263
  end
241
264
 
242
- def current_path
265
+ def request_path
243
266
  request.path rescue ""
244
267
  end
245
268
 
246
- def follow_redirects!
247
- Capybara::WaitUntil.timeout(4) do
248
- redirect = response.redirect?
249
- follow_redirect! if redirect
250
- not redirect
251
- end
252
- rescue Capybara::TimeoutError
253
- raise Capybara::InfiniteRedirectError, "infinite redirect detected!"
254
- end
255
-
256
269
  def env
257
270
  env = {}
258
271
  begin
@@ -263,9 +276,4 @@ private
263
276
  env
264
277
  end
265
278
 
266
- def reset_cache
267
- @body = nil
268
- @html = nil
269
- end
270
-
271
279
  end
@@ -25,18 +25,18 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
25
25
  end
26
26
 
27
27
  def set(value)
28
- if tag_name == 'textarea' or (tag_name == 'input' and %w(text password hidden file).include?(type))
29
- node.clear
30
- node.send_keys(value.to_s)
31
- elsif tag_name == 'input' and type == 'radio'
28
+ if tag_name == 'input' and type == 'radio'
32
29
  node.click
33
30
  elsif tag_name == 'input' and type == 'checkbox'
34
31
  node.click if node.attribute('checked') != value
32
+ elsif tag_name == 'textarea' or tag_name == 'input'
33
+ node.clear
34
+ node.send_keys(value.to_s)
35
35
  end
36
36
  end
37
37
 
38
38
  def select(option)
39
- option_node = node.find_element(:xpath, ".//option[text()=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]")
39
+ option_node = node.find_element(:xpath, ".//option[normalize-space(text())=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]")
40
40
  option_node.select
41
41
  rescue
42
42
  options = node.find_elements(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ')
@@ -49,7 +49,7 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
49
49
  end
50
50
 
51
51
  begin
52
- option_node = node.find_element(:xpath, ".//option[text()=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]")
52
+ option_node = node.find_element(:xpath, ".//option[normalize-space(text())=#{Capybara::XPath.escape(option)}]") || node.find_element(:xpath, ".//option[contains(.,#{Capybara::XPath.escape(option)})]")
53
53
  option_node.clear
54
54
  rescue
55
55
  options = node.find_elements(:xpath, "//option").map { |o| "'#{o.text}'" }.join(', ')
@@ -73,9 +73,6 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
73
73
  node.displayed? and node.displayed? != "false"
74
74
  end
75
75
 
76
- def trigger(event)
77
- end
78
-
79
76
  private
80
77
 
81
78
  def all_unfiltered(locator)
@@ -128,6 +125,10 @@ class Capybara::Driver::Selenium < Capybara::Driver::Base
128
125
 
129
126
  def wait?; true; end
130
127
 
128
+ def execute_script(script)
129
+ browser.execute_script script
130
+ end
131
+
131
132
  def evaluate_script(script)
132
133
  browser.execute_script "return #{script}"
133
134
  end
@@ -4,7 +4,6 @@ require 'capybara/dsl'
4
4
  Capybara.app = Rack::Builder.new do
5
5
  map "/" do
6
6
  if Rails.version.to_f >= 3.0
7
- ActionDispatch::Static
8
7
  run Rails.application
9
8
  else # Rails 2
10
9
  use Rails::Rack::Static
@@ -3,8 +3,11 @@ module Capybara
3
3
  extend(self)
4
4
 
5
5
  def save_and_open_page(html)
6
- name="capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}.html"
6
+ name = File.join(*[Capybara.save_and_open_page_path, "capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}.html"].compact)
7
7
 
8
+ unless Capybara.save_and_open_page_path.nil? || File.directory?(Capybara.save_and_open_page_path )
9
+ FileUtils.mkdir_p(Capybara.save_and_open_page_path)
10
+ end
8
11
  FileUtils.touch(name) unless File.exist?(name)
9
12
 
10
13
  tempfile = File.new(name,'w')
@@ -12,7 +12,7 @@ module Capybara
12
12
  :has_no_content?, :has_no_css?, :has_no_xpath?, :has_xpath?, :locate, :save_and_open_page, :select, :source, :uncheck,
13
13
  :visit, :wait_until, :within, :within_fieldset, :within_table, :within_frame, :has_link?, :has_no_link?, :has_button?,
14
14
  :has_no_button?, :has_field?, :has_no_field?, :has_checked_field?, :has_unchecked_field?, :has_no_table?, :has_table?,
15
- :unselect, :has_select?, :has_no_select?
15
+ :unselect, :has_select?, :has_no_select?, :current_path, :scope_to
16
16
  ]
17
17
 
18
18
  attr_reader :mode, :app
@@ -34,7 +34,9 @@ module Capybara
34
34
 
35
35
  def_delegator :driver, :cleanup!
36
36
  def_delegator :driver, :current_url
37
+ def_delegator :driver, :current_path
37
38
  def_delegator :driver, :response_headers
39
+ def_delegator :driver, :status_code
38
40
  def_delegator :driver, :visit
39
41
  def_delegator :driver, :body
40
42
  def_delegator :driver, :source
@@ -126,6 +128,14 @@ module Capybara
126
128
  end
127
129
  end
128
130
 
131
+ def scope_to(*locator)
132
+ scoped_session = self.clone
133
+ scoped_session.instance_eval do
134
+ @scopes = scopes + locator
135
+ end
136
+ scoped_session
137
+ end
138
+
129
139
  def has_xpath?(path, options={})
130
140
  wait_conditionally_until do
131
141
  results = all(:xpath, path, options)
@@ -227,7 +237,7 @@ module Capybara
227
237
  def locate(kind_or_locator, locator=nil, fail_msg = nil)
228
238
  node = wait_conditionally_until { find(kind_or_locator, locator) }
229
239
  ensure
230
- raise Capybara::ElementNotFound, fail_msg || "Unable to locate '#{kind_or_locator}'" unless node
240
+ raise Capybara::ElementNotFound, fail_msg || "Unable to locate '#{locator || kind_or_locator}'" unless node
231
241
  return node
232
242
  end
233
243
 
@@ -235,6 +245,10 @@ module Capybara
235
245
  WaitUntil.timeout(timeout,driver) { yield }
236
246
  end
237
247
 
248
+ def execute_script(script)
249
+ driver.execute_script(script)
250
+ end
251
+
238
252
  def evaluate_script(script)
239
253
  driver.evaluate_script(script)
240
254
  end
@@ -1,6 +1,6 @@
1
1
  require 'capybara/spec/test_app'
2
2
 
3
- Dir[File.dirname(__FILE__)+'/driver/*'].each { |group|
3
+ Dir[File.dirname(__FILE__)+'/driver/*'].each { |group|
4
4
  require group
5
5
  }
6
6
 
@@ -13,11 +13,16 @@ shared_examples_for 'driver' do
13
13
  @driver.visit('/foo')
14
14
  @driver.body.should include('Another World')
15
15
  end
16
-
16
+
17
17
  it "should show the correct URL" do
18
18
  @driver.visit('/foo')
19
19
  @driver.current_url.should include('/foo')
20
20
  end
21
+
22
+ it 'should show the correct location' do
23
+ @driver.visit('/foo')
24
+ @driver.current_path.should == '/foo'
25
+ end
21
26
  end
22
27
 
23
28
  describe '#body' do
@@ -55,6 +60,10 @@ shared_examples_for 'driver' do
55
60
  @driver.find('//input[@id="checked_field"]')[0][:checked].should be_true
56
61
  end
57
62
 
63
+ it "should allow retrieval of the value" do
64
+ @driver.find('//textarea').first.value.should == 'banana'
65
+ end
66
+
58
67
  it "should allow assignment of field value" do
59
68
  @driver.find('//input').first.value.should == 'monkey'
60
69
  @driver.find('//input').first.set('gorilla')
@@ -66,10 +75,10 @@ shared_examples_for 'driver' do
66
75
  @driver.find('//a')[1].tag_name.should == 'a'
67
76
  @driver.find('//p')[1].tag_name.should == 'p'
68
77
  end
69
-
78
+
70
79
  it "should extract node visibility" do
71
80
  @driver.find('//a')[0].should be_visible
72
-
81
+
73
82
  @driver.find('//div[@id="hidden"]')[0].should_not be_visible
74
83
  @driver.find('//div[@id="hidden_via_ancestor"]')[0].should_not be_visible
75
84
  end
@@ -81,7 +90,7 @@ shared_examples_for 'driver' do
81
90
  @driver.visit('/tables')
82
91
  @node = @driver.find('//body').first
83
92
  end
84
-
93
+
85
94
  it "should be able to navigate/search child node" do
86
95
  @node.all('//table').size.should == 5
87
96
  @node.find('//form').all('.//table').size.should == 1
@@ -95,7 +104,6 @@ shared_examples_for 'driver' do
95
104
  end
96
105
  end
97
106
  end
98
-
99
107
  end
100
108
 
101
109
  shared_examples_for "driver with javascript support" do
@@ -130,6 +138,22 @@ shared_examples_for "driver with header support" do
130
138
  end
131
139
  end
132
140
 
141
+ shared_examples_for "driver with status code support" do
142
+ it "should make the status code available through status_code" do
143
+ @driver.visit('/with_simple_html')
144
+ @driver.status_code.should == 200
145
+ end
146
+ end
147
+
148
+ shared_examples_for "driver without status code support" do
149
+ it "should raise when trying to access the status code available through status_code" do
150
+ @driver.visit('/with_simple_html')
151
+ lambda {
152
+ @driver.status_code
153
+ }.should raise_error(Capybara::NotSupportedByDriverError)
154
+ end
155
+ end
156
+
133
157
  shared_examples_for "driver with frame support" do
134
158
  describe '#within_frame' do
135
159
  before(:each) do
@@ -160,3 +184,35 @@ shared_examples_for "driver with frame support" do
160
184
  end
161
185
  end
162
186
  end
187
+
188
+ shared_examples_for "driver with cookies support" do
189
+ describe "#cleanup" do
190
+ it "should set and clean cookies" do
191
+ @driver.visit('/get_cookie')
192
+ @driver.body.should_not include('test_cookie')
193
+
194
+ @driver.visit('/set_cookie')
195
+ @driver.body.should include('Cookie set to test_cookie')
196
+
197
+ @driver.visit('/get_cookie')
198
+ @driver.body.should include('test_cookie')
199
+
200
+ @driver.cleanup!
201
+ @driver.visit('/get_cookie')
202
+ @driver.body.should_not include('test_cookie')
203
+ end
204
+ end
205
+ end
206
+
207
+ shared_examples_for "driver with infinite redirect detection" do
208
+ it "should follow 5 redirects" do
209
+ @driver.visit('/redirect/5/times')
210
+ @driver.body.should include('redirection complete')
211
+ end
212
+
213
+ it "should not follow more than 5 redirects" do
214
+ running do
215
+ @driver.visit('/redirect/6/times')
216
+ end.should raise_error(Capybara::InfiniteRedirectError)
217
+ end
218
+ end
@@ -39,6 +39,52 @@ shared_examples_for "session" do
39
39
  end
40
40
  end
41
41
 
42
+ describe '#scope_to' do
43
+ let(:scope) { @session.scope_to("//p[@id='first']") }
44
+ let(:more_scope) { scope.scope_to("//a[@id='foo']") }
45
+
46
+ before do
47
+ @session.visit('/with_html')
48
+ end
49
+
50
+ it 'has a simple link' do
51
+ scope.should have_xpath("//a[@class='simple']")
52
+ end
53
+
54
+ it 'does not have a redirect link' do
55
+ scope.should have_no_xpath("//a[@id='red']")
56
+ end
57
+
58
+ it 'does have a redirect link' do
59
+ @session.should have_xpath("//a[@id='red']")
60
+ end
61
+
62
+ it 'does not share scopes' do
63
+ @session.should have_xpath("//a[@id='red']")
64
+ scope.should have_no_xpath("//a[@id='red']")
65
+ @session.should have_xpath("//a[@id='red']")
66
+ end
67
+
68
+ context 'more_scope' do
69
+ it 'has the text for foo' do
70
+ more_scope.should have_content('ullamco')
71
+ end
72
+
73
+ it 'does not have a simple link' do
74
+ more_scope.should have_no_xpath("//a[@class='simple']")
75
+ end
76
+
77
+ it 'has not overridden scope' do
78
+ scope.should have_xpath("//a[@class='simple']")
79
+ end
80
+
81
+ it 'has not overridden session' do
82
+ @session.should have_xpath("//p[@id='second']")
83
+ end
84
+ end
85
+
86
+ end
87
+
42
88
  it_should_behave_like "all"
43
89
  it_should_behave_like "attach_file"
44
90
  it_should_behave_like "check"
@@ -207,6 +207,12 @@ shared_examples_for "click_button" do
207
207
  @results = extract_results(@session)
208
208
  @results['no_value'].should_not be_nil
209
209
  end
210
+
211
+ it "should not send image buttons that were not clicked" do
212
+ @session.click_button('Click me!')
213
+ @results = extract_results(@session)
214
+ @results['okay'].should be_nil
215
+ end
210
216
 
211
217
  it "should serialize and send GET forms" do
212
218
  @session.visit('/form')
@@ -218,6 +224,7 @@ shared_examples_for "click_button" do
218
224
 
219
225
  it "should follow redirects" do
220
226
  @session.click_button('Go FAR')
227
+ @session.current_url.should match(%r{/landed$})
221
228
  @session.body.should include('You landed')
222
229
  end
223
230
 
@@ -22,6 +22,12 @@ shared_examples_for "fill_in" do
22
22
  extract_results(@session)['street'].should == 'Avenue Q'
23
23
  end
24
24
 
25
+ it "should fill in a url field by label without for" do
26
+ @session.fill_in('Html5 Url', :with => 'http://www.avenueq.com')
27
+ @session.click_button('html5_submit')
28
+ extract_results(@session)['html5_url'].should == 'http://www.avenueq.com'
29
+ end
30
+
25
31
  it "should favour exact label matches over partial matches" do
26
32
  @session.fill_in('Name', :with => 'Harry Jones')
27
33
  @session.click_button('awesome')
@@ -53,12 +59,17 @@ shared_examples_for "fill_in" do
53
59
  end
54
60
 
55
61
  it "should fill in a field with a custom type" do
56
- pending "selenium doesn't seem to find custom fields" if @session.mode == :selenium
57
62
  @session.fill_in('Schmooo', :with => 'Schmooo is the game')
58
63
  @session.click_button('awesome')
59
64
  extract_results(@session)['schmooo'].should == 'Schmooo is the game'
60
65
  end
61
66
 
67
+ it "should fill in a field without a type" do
68
+ @session.fill_in('Phone', :with => '+1 555 7022')
69
+ @session.click_button('awesome')
70
+ extract_results(@session)['phone'].should == '+1 555 7022'
71
+ end
72
+
62
73
  it "should fill in a password field by name" do
63
74
  @session.fill_in('form[password]', :with => 'supasikrit')
64
75
  @session.click_button('awesome')
@@ -35,12 +35,20 @@ shared_examples_for "session with javascript support" do
35
35
  end
36
36
 
37
37
  describe "#evaluate_script" do
38
- it "should return the evaluated script" do
38
+ it "should evaluate the given script and return whatever it produces" do
39
39
  @session.visit('/with_js')
40
40
  @session.evaluate_script("1+3").should == 4
41
41
  end
42
42
  end
43
43
 
44
+ describe "#execute_script" do
45
+ it "should execute the given script and return nothing" do
46
+ @session.visit('/with_js')
47
+ @session.execute_script("$('#change').text('Funky Doodle')").should be_nil
48
+ @session.should have_css('#change', :text => 'Funky Doodle')
49
+ end
50
+ end
51
+
44
52
  describe '#locate' do
45
53
  it "should wait for asynchronous load" do
46
54
  @session.visit('/with_js')
@@ -38,6 +38,12 @@ shared_examples_for "locate" do
38
38
  end.should raise_error(Capybara::ElementNotFound, "arghh")
39
39
  end
40
40
 
41
+ it "should raise ElementNotFound with a useful default message if nothing was found" do
42
+ running do
43
+ @session.locate(:xpath, '//div[@id="nosuchthing"]').should be_nil
44
+ end.should raise_error(Capybara::ElementNotFound, "Unable to locate '//div[@id=\"nosuchthing\"]'")
45
+ end
46
+
41
47
  it "should accept an XPath instance and respect the order of paths" do
42
48
  @session.visit('/form')
43
49
  @xpath = Capybara::XPath.text_field('Name')
@@ -0,0 +1,19 @@
1
+ shared_examples_for "session with status code support" do
2
+ describe '#status_code' do
3
+ it "should return response codes" do
4
+ @session.visit('/with_simple_html')
5
+ @session.status_code.should == 200
6
+ end
7
+ end
8
+ end
9
+
10
+ shared_examples_for "session without status code support" do
11
+ describe "#status_code" do
12
+ before{ @session.visit('/with_simple_html') }
13
+ it "should raise an error" do
14
+ running {
15
+ @session.status_code
16
+ }.should raise_error(Capybara::NotSupportedByDriverError)
17
+ end
18
+ end
19
+ end
@@ -37,6 +37,20 @@ shared_examples_for "select" do
37
37
  extract_results(@session)['locale'].should == 'jo'
38
38
  end
39
39
 
40
+ it "should obey from" do
41
+ @session.select("Miss", :from => "Other title")
42
+ @session.click_button('awesome')
43
+ results = extract_results(@session)
44
+ results['other_title'].should == "Miss"
45
+ results['title'].should_not == "Miss"
46
+ end
47
+
48
+ it "show match labels with preceding or trailing whitespace" do
49
+ @session.select("Lojban", :from => 'Locale')
50
+ @session.click_button('awesome')
51
+ extract_results(@session)['locale'].should == 'jbo'
52
+ end
53
+
40
54
  context "with a locator that doesn't exist" do
41
55
  it "should raise an error" do
42
56
  running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
@@ -13,7 +13,7 @@ class TestApp < Sinatra::Base
13
13
  get '/foo' do
14
14
  'Another World'
15
15
  end
16
-
16
+
17
17
  get '/redirect' do
18
18
  redirect '/redirect_again'
19
19
  end
@@ -22,6 +22,15 @@ class TestApp < Sinatra::Base
22
22
  redirect '/landed'
23
23
  end
24
24
 
25
+ get '/redirect/:times/times' do
26
+ times = params[:times].to_i
27
+ if times.zero?
28
+ "redirection complete"
29
+ else
30
+ redirect "/redirect/#{times - 1}/times"
31
+ end
32
+ end
33
+
25
34
  get '/landed' do
26
35
  "You landed"
27
36
  end
@@ -33,7 +42,7 @@ class TestApp < Sinatra::Base
33
42
  get '/form/get' do
34
43
  '<pre id="results">' + params[:form].to_yaml + '</pre>'
35
44
  end
36
-
45
+
37
46
  get '/favicon.ico' do
38
47
  nil
39
48
  end
@@ -50,6 +59,16 @@ class TestApp < Sinatra::Base
50
59
  redirect back
51
60
  end
52
61
 
62
+ get '/set_cookie' do
63
+ cookie_value = 'test_cookie'
64
+ response.set_cookie('capybara', cookie_value)
65
+ "Cookie set to #{cookie_value}"
66
+ end
67
+
68
+ get '/get_cookie' do
69
+ request.cookies['capybara']
70
+ end
71
+
53
72
  get '/:view' do |view|
54
73
  erb view.to_sym
55
74
  end
@@ -11,6 +11,16 @@
11
11
  </select>
12
12
  </p>
13
13
 
14
+
15
+ <p>
16
+ <label for="form_other_title">Other title</label>
17
+ <select name="form[other_title]" id="form_other_title">
18
+ <option>Mrs</option>
19
+ <option>Mr</option>
20
+ <option>Miss</option>
21
+ </select>
22
+ </p>
23
+
14
24
  <p>
15
25
  <label for="form_first_name">
16
26
  First Name
@@ -46,7 +56,7 @@
46
56
 
47
57
  <p>
48
58
  <label for="form_phone">Phone</label>
49
- <input type="text" name="form[phone]" value="+1 555 7021" id="form_phone"/>
59
+ <input name="form[phone]" value="+1 555 7021" id="form_phone"/>
50
60
  </p>
51
61
 
52
62
  <p>
@@ -77,6 +87,7 @@
77
87
  <option value="fi">Finish</option>
78
88
  <option value="no">Norwegian</option>
79
89
  <option value="jo">John's made-up language</option>
90
+ <option value="jbo"> Lojban </option>
80
91
  </select>
81
92
  </p>
82
93
 
@@ -20,6 +20,7 @@
20
20
 
21
21
  <p>
22
22
  <input type="text" id="test_field" value="monkey"/>
23
+ <textarea>banana</textarea>
23
24
  <a href="/redirect_back">BackToMyself</a>
24
25
  <a title="twas a fine link" href="/redirect">A link came first</a>
25
26
  <a title="a fine link" href="/with_simple_html">A link</a>
@@ -1,3 +1,3 @@
1
1
  module Capybara
2
- VERSION = '0.3.8'
2
+ VERSION = '0.3.9'
3
3
  end
@@ -111,7 +111,7 @@ module Capybara
111
111
 
112
112
  def text_field(locator, options={})
113
113
  options = options.merge(:value => options[:with]) if options.has_key?(:with)
114
- add_field(locator, "//input[@type!='radio' and @type!='checkbox' and @type!='hidden']", options)
114
+ add_field(locator, "//input[not(@type) or (@type!='radio' and @type!='checkbox' and @type!='hidden')]", options)
115
115
  end
116
116
 
117
117
  def text_area(locator, options={})
@@ -163,8 +163,8 @@ module Capybara
163
163
  when :text then postfix += "[text()=#{s(value)}]"
164
164
  when :checked then postfix += "[@checked]"
165
165
  when :unchecked then postfix += "[not(@checked)]"
166
- when :options then postfix += value.map { |o| "[./option/text()=#{s(o)}]" }.join
167
- when :selected then postfix += [value].flatten.map { |o| "[./option[@selected]/text()=#{s(o)}]" }.join
166
+ when :options then postfix += value.map { |o| "[.//option/text()=#{s(o)}]" }.join
167
+ when :selected then postfix += [value].flatten.map { |o| "[.//option[@selected]/text()=#{s(o)}]" }.join
168
168
  end
169
169
  postfix
170
170
  end
@@ -9,7 +9,8 @@ if RUBY_PLATFORM =~ /java/
9
9
  it_should_behave_like "driver"
10
10
  it_should_behave_like "driver with javascript support"
11
11
  it_should_behave_like "driver with header support"
12
-
12
+ it_should_behave_like "driver with status code support"
13
+ it_should_behave_like "driver with cookies support"
13
14
  end
14
15
  else
15
16
  puts "#{File.basename(__FILE__)} requires JRuby; skipping.."
@@ -4,9 +4,10 @@ describe Capybara::Driver::Culerity do
4
4
  before(:all) do
5
5
  @driver = Capybara::Driver::Culerity.new(TestApp)
6
6
  end
7
-
7
+
8
8
  it_should_behave_like "driver"
9
9
  it_should_behave_like "driver with javascript support"
10
10
  it_should_behave_like "driver with header support"
11
-
11
+ it_should_behave_like "driver with status code support"
12
+ it_should_behave_like "driver with cookies support"
12
13
  end
@@ -4,8 +4,16 @@ describe Capybara::Driver::RackTest do
4
4
  before do
5
5
  @driver = Capybara::Driver::RackTest.new(TestApp)
6
6
  end
7
-
7
+
8
+ it "should throw an error when no rack app is given" do
9
+ running do
10
+ Capybara::Driver::RackTest.new(nil)
11
+ end.should raise_error(ArgumentError)
12
+ end
13
+
8
14
  it_should_behave_like "driver"
9
15
  it_should_behave_like "driver with header support"
10
-
16
+ it_should_behave_like "driver with status code support"
17
+ it_should_behave_like "driver with cookies support"
18
+ it_should_behave_like "driver with infinite redirect detection"
11
19
  end
@@ -13,11 +13,12 @@ describe Capybara::Driver::Culerity do
13
13
  end
14
14
 
15
15
  it "should navigate to a fully qualified remote page" do
16
- @driver.visit('http://elabs.se/contact')
17
- @driver.body.should include('Edithouse eLabs AB')
16
+ @driver.visit('http://capybara-testapp.heroku.com/foo')
17
+ @driver.body.should include('Another World')
18
18
  end
19
19
 
20
20
  it_should_behave_like "driver"
21
21
  it_should_behave_like "driver with javascript support"
22
22
  it_should_behave_like "driver with header support"
23
+ it_should_behave_like "driver with status code support"
23
24
  end
@@ -15,4 +15,5 @@ describe Capybara::Driver::Selenium do
15
15
 
16
16
  it_should_behave_like "driver"
17
17
  it_should_behave_like "driver with javascript support"
18
+ it_should_behave_like "driver without status code support"
18
19
  end
@@ -8,4 +8,6 @@ describe Capybara::Driver::Selenium do
8
8
  it_should_behave_like "driver"
9
9
  it_should_behave_like "driver with javascript support"
10
10
  it_should_behave_like "driver with frame support"
11
+ it_should_behave_like "driver without status code support"
12
+ it_should_behave_like "driver with cookies support"
11
13
  end
@@ -5,18 +5,12 @@ require 'launchy'
5
5
  describe Capybara::SaveAndOpenPage do
6
6
  describe "#save_save_and_open_page" do
7
7
  before do
8
-
9
8
  @time = Time.new.strftime("%Y%m%d%H%M%S")
10
- @name = "capybara-#{@time}.html"
11
9
 
12
10
  @temp_file = mock("FILE")
13
11
  @temp_file.stub!(:write)
14
12
  @temp_file.stub!(:close)
15
- @temp_file.stub!(:path).and_return(@name)
16
-
17
- File.should_receive(:exist?).and_return true
18
- File.should_receive(:new).and_return @temp_file
19
-
13
+
20
14
  @html = <<-HTML
21
15
  <html>
22
16
  <head>
@@ -30,14 +24,60 @@ describe Capybara::SaveAndOpenPage do
30
24
  Launchy::Browser.stub(:run)
31
25
  end
32
26
 
33
- it "should create a new temporary file" do
34
- @temp_file.should_receive(:write).with @html
35
- Capybara::SaveAndOpenPage.save_and_open_page @html
27
+ describe "defaults" do
28
+ before do
29
+ @name = "capybara-#{@time}.html"
30
+
31
+ @temp_file.stub!(:path).and_return(@name)
32
+
33
+ File.should_receive(:exist?).and_return true
34
+ File.should_receive(:new).and_return @temp_file
35
+ end
36
+
37
+ it "should create a new temporary file" do
38
+ @temp_file.should_receive(:write).with @html
39
+ Capybara::SaveAndOpenPage.save_and_open_page @html
40
+ end
41
+
42
+ it "should open the file in the browser" do
43
+ Capybara::SaveAndOpenPage.should_receive(:open_in_browser).with(@name)
44
+ Capybara::SaveAndOpenPage.save_and_open_page @html
45
+ end
36
46
  end
47
+
48
+ describe "custom output path" do
49
+ before do
50
+ @custom_path = File.join('tmp', 'capybara')
51
+ @custom_name = File.join(@custom_path, "capybara-#{@time}.html")
37
52
 
38
- it "should open the file in the browser" do
39
- Capybara::SaveAndOpenPage.should_receive(:open_in_browser).with(@name)
40
- Capybara::SaveAndOpenPage.save_and_open_page @html
53
+ @temp_file.stub!(:path).and_return(@custom_name)
54
+
55
+ Capybara.should_receive(:save_and_open_page_path).at_least(:once).and_return(@custom_path)
56
+ end
57
+
58
+ it "should create a new temporary file in the custom path" do
59
+ File.should_receive(:directory?).and_return true
60
+ File.should_receive(:exist?).and_return true
61
+ File.should_receive(:new).and_return @temp_file
62
+
63
+ @temp_file.should_receive(:write).with @html
64
+ Capybara::SaveAndOpenPage.save_and_open_page @html
65
+ end
66
+
67
+ it "should open the file - in the custom path - in the browser" do
68
+ Capybara::SaveAndOpenPage.should_receive(:open_in_browser).with(@custom_name)
69
+ Capybara::SaveAndOpenPage.save_and_open_page @html
70
+ end
71
+
72
+ it "should be possible to configure output path" do
73
+ Capybara.should respond_to(:save_and_open_page_path)
74
+ default_setting = Capybara.save_and_open_page_path
75
+ lambda {
76
+ Capybara.save_and_open_page_path = File.join('tmp', 'capybara')
77
+ Capybara.save_and_open_page_path.should == File.join('tmp', 'capybara')
78
+ }.should_not raise_error
79
+ Capybara.save_and_open_page_path = default_setting
80
+ end
41
81
  end
42
82
  end
43
83
  end
@@ -7,7 +7,7 @@ if RUBY_PLATFORM =~ /java/
7
7
  end
8
8
 
9
9
  describe '#driver' do
10
- it "should be a rack test driver" do
10
+ it "should be a celerity driver" do
11
11
  @session.driver.should be_an_instance_of(Capybara::Driver::Celerity)
12
12
  end
13
13
  end
@@ -21,6 +21,7 @@ if RUBY_PLATFORM =~ /java/
21
21
  it_should_behave_like "session"
22
22
  it_should_behave_like "session with javascript support"
23
23
  it_should_behave_like "session with headers support"
24
+ it_should_behave_like "session with status code support"
24
25
  end
25
26
  else
26
27
  puts "#{File.basename(__FILE__)} requires JRuby; skipping.."
@@ -7,7 +7,7 @@ describe Capybara::Session do
7
7
  end
8
8
 
9
9
  describe '#driver' do
10
- it "should be a rack test driver" do
10
+ it "should be a culerity driver" do
11
11
  @session.driver.should be_an_instance_of(Capybara::Driver::Culerity)
12
12
  end
13
13
  end
@@ -21,5 +21,6 @@ describe Capybara::Session do
21
21
  it_should_behave_like "session"
22
22
  it_should_behave_like "session with javascript support"
23
23
  it_should_behave_like "session with headers support"
24
+ it_should_behave_like "session with status code support"
24
25
  end
25
26
  end
@@ -29,5 +29,6 @@ describe Capybara::Session do
29
29
  it_should_behave_like "session"
30
30
  it_should_behave_like "session without javascript support"
31
31
  it_should_behave_like "session with headers support"
32
+ it_should_behave_like "session with status code support"
32
33
  end
33
34
  end
@@ -21,5 +21,6 @@ describe Capybara::Session do
21
21
  it_should_behave_like "session"
22
22
  it_should_behave_like "session with javascript support"
23
23
  it_should_behave_like "session without headers support"
24
+ it_should_behave_like "session without status code support"
24
25
  end
25
26
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: capybara
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 1
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 3
8
- - 8
9
- version: 0.3.8
9
+ - 9
10
+ version: 0.3.9
10
11
  platform: ruby
11
12
  authors:
12
13
  - Jonas Nicklas
@@ -14,16 +15,18 @@ autorequire:
14
15
  bindir: bin
15
16
  cert_chain: []
16
17
 
17
- date: 2010-05-12 00:00:00 +02:00
18
+ date: 2010-07-03 00:00:00 +02:00
18
19
  default_executable:
19
20
  dependencies:
20
21
  - !ruby/object:Gem::Dependency
21
22
  name: nokogiri
22
23
  prerelease: false
23
24
  requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
24
26
  requirements:
25
27
  - - ">="
26
28
  - !ruby/object:Gem::Version
29
+ hash: 29
27
30
  segments:
28
31
  - 1
29
32
  - 3
@@ -35,9 +38,11 @@ dependencies:
35
38
  name: mime-types
36
39
  prerelease: false
37
40
  requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
38
42
  requirements:
39
43
  - - ">="
40
44
  - !ruby/object:Gem::Version
45
+ hash: 47
41
46
  segments:
42
47
  - 1
43
48
  - 16
@@ -48,9 +53,11 @@ dependencies:
48
53
  name: culerity
49
54
  prerelease: false
50
55
  requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
51
57
  requirements:
52
58
  - - ">="
53
59
  - !ruby/object:Gem::Version
60
+ hash: 31
54
61
  segments:
55
62
  - 0
56
63
  - 2
@@ -62,9 +69,11 @@ dependencies:
62
69
  name: selenium-webdriver
63
70
  prerelease: false
64
71
  requirement: &id004 !ruby/object:Gem::Requirement
72
+ none: false
65
73
  requirements:
66
74
  - - ">="
67
75
  - !ruby/object:Gem::Version
76
+ hash: 25
68
77
  segments:
69
78
  - 0
70
79
  - 0
@@ -76,9 +85,11 @@ dependencies:
76
85
  name: rack
77
86
  prerelease: false
78
87
  requirement: &id005 !ruby/object:Gem::Requirement
88
+ none: false
79
89
  requirements:
80
90
  - - ">="
81
91
  - !ruby/object:Gem::Version
92
+ hash: 23
82
93
  segments:
83
94
  - 1
84
95
  - 0
@@ -90,23 +101,27 @@ dependencies:
90
101
  name: rack-test
91
102
  prerelease: false
92
103
  requirement: &id006 !ruby/object:Gem::Requirement
104
+ none: false
93
105
  requirements:
94
106
  - - ">="
95
107
  - !ruby/object:Gem::Version
108
+ hash: 3
96
109
  segments:
97
110
  - 0
98
111
  - 5
99
- - 2
100
- version: 0.5.2
112
+ - 4
113
+ version: 0.5.4
101
114
  type: :runtime
102
115
  version_requirements: *id006
103
116
  - !ruby/object:Gem::Dependency
104
117
  name: sinatra
105
118
  prerelease: false
106
119
  requirement: &id007 !ruby/object:Gem::Requirement
120
+ none: false
107
121
  requirements:
108
122
  - - ">="
109
123
  - !ruby/object:Gem::Version
124
+ hash: 51
110
125
  segments:
111
126
  - 0
112
127
  - 9
@@ -118,9 +133,11 @@ dependencies:
118
133
  name: rspec
119
134
  prerelease: false
120
135
  requirement: &id008 !ruby/object:Gem::Requirement
136
+ none: false
121
137
  requirements:
122
138
  - - ">="
123
139
  - !ruby/object:Gem::Version
140
+ hash: 13
124
141
  segments:
125
142
  - 1
126
143
  - 2
@@ -128,6 +145,22 @@ dependencies:
128
145
  version: 1.2.9
129
146
  type: :development
130
147
  version_requirements: *id008
148
+ - !ruby/object:Gem::Dependency
149
+ name: launchy
150
+ prerelease: false
151
+ requirement: &id009 !ruby/object:Gem::Requirement
152
+ none: false
153
+ requirements:
154
+ - - ">="
155
+ - !ruby/object:Gem::Version
156
+ hash: 25
157
+ segments:
158
+ - 0
159
+ - 3
160
+ - 5
161
+ version: 0.3.5
162
+ type: :development
163
+ version_requirements: *id009
131
164
  description: Capybara is an integration testing tool for rack based web applications. It simulates how a user would interact with a website
132
165
  email:
133
166
  - jonas.nicklas@gmail.com
@@ -182,6 +215,7 @@ files:
182
215
  - lib/capybara/spec/session/headers.rb
183
216
  - lib/capybara/spec/session/javascript.rb
184
217
  - lib/capybara/spec/session/locate_spec.rb
218
+ - lib/capybara/spec/session/response_code.rb
185
219
  - lib/capybara/spec/session/select_spec.rb
186
220
  - lib/capybara/spec/session/uncheck_spec.rb
187
221
  - lib/capybara/spec/session/unselect_spec.rb
@@ -235,23 +269,27 @@ rdoc_options:
235
269
  require_paths:
236
270
  - lib
237
271
  required_ruby_version: !ruby/object:Gem::Requirement
272
+ none: false
238
273
  requirements:
239
274
  - - ">="
240
275
  - !ruby/object:Gem::Version
276
+ hash: 3
241
277
  segments:
242
278
  - 0
243
279
  version: "0"
244
280
  required_rubygems_version: !ruby/object:Gem::Requirement
281
+ none: false
245
282
  requirements:
246
283
  - - ">="
247
284
  - !ruby/object:Gem::Version
285
+ hash: 3
248
286
  segments:
249
287
  - 0
250
288
  version: "0"
251
289
  requirements: []
252
290
 
253
291
  rubyforge_project: capybara
254
- rubygems_version: 1.3.6
292
+ rubygems_version: 1.3.7
255
293
  signing_key:
256
294
  specification_version: 3
257
295
  summary: Capybara aims to simplify the process of integration testing Rack applications, such as Rails, Sinatra or Merb