capybara 0.3.9 → 0.4.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. data/History.txt +43 -1
  2. data/README.rdoc +168 -98
  3. data/lib/capybara.rb +77 -15
  4. data/lib/capybara/driver/base.rb +21 -16
  5. data/lib/capybara/driver/celerity_driver.rb +39 -41
  6. data/lib/capybara/driver/culerity_driver.rb +2 -1
  7. data/lib/capybara/driver/node.rb +66 -0
  8. data/lib/capybara/driver/rack_test_driver.rb +66 -67
  9. data/lib/capybara/driver/selenium_driver.rb +43 -47
  10. data/lib/capybara/dsl.rb +44 -6
  11. data/lib/capybara/node.rb +185 -24
  12. data/lib/capybara/node/actions.rb +170 -0
  13. data/lib/capybara/node/finders.rb +150 -0
  14. data/lib/capybara/node/matchers.rb +360 -0
  15. data/lib/capybara/rails.rb +1 -0
  16. data/lib/capybara/selector.rb +52 -0
  17. data/lib/capybara/server.rb +68 -87
  18. data/lib/capybara/session.rb +221 -207
  19. data/lib/capybara/spec/driver.rb +45 -35
  20. data/lib/capybara/spec/public/test.js +1 -1
  21. data/lib/capybara/spec/session.rb +28 -53
  22. data/lib/capybara/spec/session/all_spec.rb +7 -3
  23. data/lib/capybara/spec/session/check_spec.rb +50 -52
  24. data/lib/capybara/spec/session/click_button_spec.rb +9 -0
  25. data/lib/capybara/spec/session/click_link_or_button_spec.rb +37 -0
  26. data/lib/capybara/spec/session/current_url_spec.rb +7 -0
  27. data/lib/capybara/spec/session/find_button_spec.rb +4 -2
  28. data/lib/capybara/spec/session/find_by_id_spec.rb +4 -2
  29. data/lib/capybara/spec/session/find_field_spec.rb +7 -3
  30. data/lib/capybara/spec/session/find_link_spec.rb +5 -3
  31. data/lib/capybara/spec/session/find_spec.rb +71 -6
  32. data/lib/capybara/spec/session/has_field_spec.rb +1 -1
  33. data/lib/capybara/spec/session/has_selector_spec.rb +129 -0
  34. data/lib/capybara/spec/session/has_xpath_spec.rb +4 -4
  35. data/lib/capybara/spec/session/javascript.rb +25 -5
  36. data/lib/capybara/spec/session/select_spec.rb +16 -2
  37. data/lib/capybara/spec/session/unselect_spec.rb +8 -1
  38. data/lib/capybara/spec/session/within_spec.rb +5 -5
  39. data/lib/capybara/spec/views/form.erb +65 -1
  40. data/lib/capybara/spec/views/popup_one.erb +8 -0
  41. data/lib/capybara/spec/views/popup_two.erb +8 -0
  42. data/lib/capybara/spec/views/with_html.erb +5 -0
  43. data/lib/capybara/spec/views/within_popups.erb +25 -0
  44. data/lib/capybara/{save_and_open_page.rb → util/save_and_open_page.rb} +3 -3
  45. data/lib/capybara/util/timeout.rb +27 -0
  46. data/lib/capybara/version.rb +1 -1
  47. data/spec/capybara_spec.rb +18 -8
  48. data/spec/driver/celerity_driver_spec.rb +10 -14
  49. data/spec/driver/culerity_driver_spec.rb +4 -3
  50. data/spec/driver/rack_test_driver_spec.rb +39 -2
  51. data/spec/driver/remote_culerity_driver_spec.rb +5 -7
  52. data/spec/driver/remote_selenium_driver_spec.rb +7 -10
  53. data/spec/driver/selenium_driver_spec.rb +3 -2
  54. data/spec/dsl_spec.rb +5 -14
  55. data/spec/save_and_open_page_spec.rb +19 -19
  56. data/spec/server_spec.rb +22 -10
  57. data/spec/session/celerity_session_spec.rb +17 -21
  58. data/spec/session/culerity_session_spec.rb +3 -3
  59. data/spec/session/rack_test_session_spec.rb +2 -2
  60. data/spec/session/selenium_session_spec.rb +2 -2
  61. data/spec/spec_helper.rb +27 -6
  62. data/spec/{wait_until_spec.rb → timeout_spec.rb} +14 -14
  63. metadata +88 -46
  64. data/lib/capybara/searchable.rb +0 -54
  65. data/lib/capybara/spec/session/click_spec.rb +0 -24
  66. data/lib/capybara/spec/session/locate_spec.rb +0 -65
  67. data/lib/capybara/wait_until.rb +0 -28
  68. data/lib/capybara/xpath.rb +0 -179
  69. data/spec/searchable_spec.rb +0 -66
  70. data/spec/xpath_spec.rb +0 -180
@@ -12,6 +12,13 @@ shared_examples_for "unselect" do
12
12
  extract_results(@session)['underwear'].should_not include('Commando')
13
13
  end
14
14
 
15
+ it "should unselect an option without a select box" do
16
+ @session.unselect('Commando')
17
+ @session.click_button('awesome')
18
+ extract_results(@session)['underwear'].should include('Briefs', 'Boxer Briefs')
19
+ extract_results(@session)['underwear'].should_not include('Commando')
20
+ end
21
+
15
22
  it "should unselect an option from a select box by label" do
16
23
  @session.unselect('Commando', :from => 'Underwear')
17
24
  @session.click_button('awesome')
@@ -47,7 +54,7 @@ shared_examples_for "unselect" do
47
54
 
48
55
  context "with an option that doesn't exist" do
49
56
  it "should raise an error" do
50
- running { @session.unselect('Does not Exist', :from => 'form_underwear') }.should raise_error(Capybara::OptionNotFound)
57
+ running { @session.unselect('Does not Exist', :from => 'form_underwear') }.should raise_error(Capybara::ElementNotFound)
51
58
  end
52
59
  end
53
60
  end
@@ -53,7 +53,7 @@ shared_examples_for "within" do
53
53
  context "with nested scopes" do
54
54
  it "should respect the inner scope" do
55
55
  @session.within("//div[@id='for_bar']") do
56
- @session.within("//li[contains(.,'Bar')]") do
56
+ @session.within(".//li[contains(.,'Bar')]") do
57
57
  @session.click_link('Go')
58
58
  end
59
59
  end
@@ -62,7 +62,7 @@ shared_examples_for "within" do
62
62
 
63
63
  it "should respect the outer scope" do
64
64
  @session.within("//div[@id='another_foo']") do
65
- @session.within("//li[contains(.,'With Simple HTML')]") do
65
+ @session.within(".//li[contains(.,'With Simple HTML')]") do
66
66
  @session.click_link('Go')
67
67
  end
68
68
  end
@@ -82,12 +82,12 @@ shared_examples_for "within" do
82
82
  @session.within("//div[@id='for_bar']") do
83
83
  running {
84
84
  running {
85
- @session.within("//div[@id='doesnotexist']") do
85
+ @session.within(".//div[@id='doesnotexist']") do
86
86
  end
87
87
  }.should raise_error(Capybara::ElementNotFound)
88
- }.should_not change { @session.has_xpath?("//div[@id='another_foo']") }.from(false)
88
+ }.should_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(false)
89
89
  end
90
- }.should_not change { @session.has_xpath?("//div[@id='another_foo']") }.from(true)
90
+ }.should_not change { @session.has_xpath?(".//div[@id='another_foo']") }.from(true)
91
91
  end
92
92
  end
93
93
 
@@ -155,8 +155,27 @@
155
155
  <option selected="selected">Briefs</option>
156
156
  <option selected="selected">Commando</option>
157
157
  <option selected="selected">Frenchman's Pantalons</option>
158
+ <option selected="selected" value="thermal">Long Johns</option>
158
159
  </select>
159
160
  </p>
161
+
162
+ <p>
163
+ <span>First address<span>
164
+ <label for='address1_street'>Street</label>
165
+ <input type="text" name="form[addresses][][street]" value="" id="address1_street">
166
+
167
+ <label for='address1_city'>City</label>
168
+ <input type="text" name="form[addresses][][city]" value="" id="address1_city">
169
+ </p>
170
+
171
+ <p>
172
+ <span>Second address<span>
173
+ <label for='address2_street'>Street</label>
174
+ <input type="text" name="form[addresses][][street]" value="" id="address2_street">
175
+
176
+ <label for='address2_city'>City</label>
177
+ <input type="text" name="form[addresses][][city]" value="" id="address2_city">
178
+ </p>
160
179
 
161
180
  <div style="display:none;">
162
181
  <label for="form_first_name_hidden">
@@ -165,6 +184,50 @@
165
184
  </label>
166
185
  </div>
167
186
 
187
+ <p>
188
+ <label for="form_disabled_text_field">
189
+ Disabled Text Field
190
+ <input type="text" name="form[disabled_text_field]" value="Should not see me" id="form_disabled_text_field" disabled="disabled" />
191
+ </label>
192
+ </p>
193
+
194
+ <p>
195
+ <label for="form_disabled_textarea">
196
+ Disabled Textarea
197
+ <textarea name="form[disabled_textarea]" value="Should not see me" id="form_disabled_textarea" disabled="disabled"></textarea>
198
+ </label>
199
+ </p>
200
+
201
+ <p>
202
+ <label for="form_disabled_checkbox">
203
+ Disabled Checkbox
204
+ <input type="checkbox" name="form[disabled_checkbox]" value="Should not see me" id="form_disabled_checkbox" checked="checked" disabled="disabled" />
205
+ </label>
206
+ </p>
207
+
208
+ <p>
209
+ <label for="form_disabled_radio">
210
+ Disabled Checkbox
211
+ <input type="radio" name="form[disabled_radio]" value="Should not see me" id="form_disabled_radio" checked="checked" disabled="disabled" />
212
+ </label>
213
+ </p>
214
+
215
+ <p>
216
+ <label for="form_disabled_select">
217
+ Disabled Select
218
+ <select name="form[disabled_select]" id="form_disabled_select" disabled="disabled">
219
+ <option value="Should not see me" selected="selected">Should not see me</option>
220
+ </select>
221
+ </label>
222
+ </p>
223
+
224
+ <p>
225
+ <label for="form_disabled_file">
226
+ Disabled File
227
+ <input type="file" name="form[disabled_file]" value="/should/not/see/me" id="form_disabled_file" disabled="disabled" />
228
+ </label>
229
+ </p>
230
+
168
231
  <p>
169
232
  <input type="button" name="form[fresh]" id="fresh_btn" value="i am fresh"/>
170
233
  <input type="submit" name="form[awesome]" id="awe123" value="awesome"/>
@@ -172,10 +235,11 @@
172
235
  <input type="image" name="form[okay]" id="okay556" value="okay" alt="oh hai thar"/>
173
236
  <button type="submit" id="click_me_123" value="click_me">Click me!</button>
174
237
  <button type="submit" name="form[no_value]">No Value!</button>
238
+ <button id="no_type">No Type!</button>
175
239
  </p>
176
240
  </form>
177
241
 
178
- <form action="/form/get?foo=bar" method="get">
242
+ <form id="get-form" action="/form/get?foo=bar" method="get">
179
243
  <p>
180
244
  <label for="form_middle_name">Middle Name</label>
181
245
  <input type="text" name="form[middle_name]" value="Darren" id="form_middle_name"/>
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title>This is the title of the first popup</title>
4
+ </head>
5
+ <body>
6
+ <div id="divInPopupOne">This is the text of divInPopupOne</div>
7
+ </body>
8
+ </html>
@@ -0,0 +1,8 @@
1
+ <html>
2
+ <head>
3
+ <title>This is the title of popup two</title>
4
+ </head>
5
+ <body>
6
+ <div id="divInPopupTwo">This is the text of divInPopupTwo</div>
7
+ </body>
8
+ </html>
@@ -41,3 +41,8 @@
41
41
  <div id="hidden_via_ancestor">Inside element with hidden ancestor</div>
42
42
  <a href="/with_simple_html" title="awesome title" class="simple">hidden link</a>
43
43
  </div>
44
+
45
+ <ul>
46
+ <li id="john_monkey">Monkey John</li>
47
+ <li id="paul_monkey">Monkey Paul</li>
48
+ </ul>
@@ -0,0 +1,25 @@
1
+ <html>
2
+ <head>
3
+ <title>With Popups</title>
4
+ <script language="javascript" type="text/javascript">
5
+ <!--
6
+
7
+ function popItUp(name, url) {
8
+ newwindow=window.open(url,name,'height=200,width=150');
9
+ if (window.focus) { newwindow.focus() }
10
+ return false;
11
+ }
12
+
13
+ function init() {
14
+ popItUp('firstPopup', '/popup_one');
15
+ popItUp('secondPopup', '/popup_two');
16
+ }
17
+ window.onload = init;
18
+
19
+ // -->
20
+ </script>
21
+ </head>
22
+ <body>
23
+ <div id="divInMainWindow">This is the text for divInMainWindow</div>
24
+ </body>
25
+ </html>
@@ -1,7 +1,5 @@
1
1
  module Capybara
2
- module SaveAndOpenPage
3
- extend(self)
4
-
2
+ class << self
5
3
  def save_and_open_page(html)
6
4
  name = File.join(*[Capybara.save_and_open_page_path, "capybara-#{Time.new.strftime("%Y%m%d%H%M%S")}.html"].compact)
7
5
 
@@ -17,6 +15,8 @@ module Capybara
17
15
  open_in_browser(tempfile.path)
18
16
  end
19
17
 
18
+ protected
19
+
20
20
  def open_in_browser(path) # :nodoc
21
21
  require "launchy"
22
22
  Launchy::Browser.run(path)
@@ -0,0 +1,27 @@
1
+ module Capybara
2
+ class << self
3
+
4
+ ##
5
+ # Provides timeout similar to standard library Timeout, but avoids threads
6
+ #
7
+ def timeout(seconds = 1, driver = nil, &block)
8
+ start_time = Time.now
9
+
10
+ result = nil
11
+
12
+ until result
13
+ return result if result = yield
14
+
15
+ delay = seconds - (Time.now - start_time)
16
+ if delay <= 0
17
+ raise TimeoutError
18
+ end
19
+
20
+ driver && driver.wait_until(delay)
21
+
22
+ sleep(0.05)
23
+ end
24
+ end
25
+
26
+ end
27
+ end
@@ -1,3 +1,3 @@
1
1
  module Capybara
2
- VERSION = '0.3.9'
2
+ VERSION = '0.4.0.rc'
3
3
  end
@@ -1,18 +1,28 @@
1
- require File.expand_path('spec_helper', File.dirname(__FILE__))
2
-
3
- require 'capybara'
1
+ require 'spec_helper'
4
2
 
5
3
  describe Capybara do
6
-
4
+
7
5
  describe 'default_wait_time' do
8
6
  after do
9
- Capybara.default_wait_time = 2
7
+ Capybara.default_wait_time = @previous_default_time
10
8
  end
11
-
9
+
12
10
  it "should be changeable" do
11
+ @previous_default_time = Capybara.default_wait_time
13
12
  Capybara.default_wait_time = 5
14
13
  Capybara.default_wait_time.should == 5
15
14
  end
16
15
  end
17
-
18
- end
16
+
17
+ describe '.register_driver' do
18
+ it "should add a new driver" do
19
+ Capybara.register_driver :schmoo do |app|
20
+ Capybara::Driver::RackTest.new(app)
21
+ end
22
+ session = Capybara::Session.new(:schmoo, TestApp)
23
+ session.visit('/')
24
+ session.body.should include("Hello world!")
25
+ end
26
+ end
27
+
28
+ end
@@ -1,17 +1,13 @@
1
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
1
+ require 'spec_helper'
2
2
 
3
- if RUBY_PLATFORM =~ /java/
4
- describe Capybara::Driver::Celerity do
5
- before(:all) do
6
- @driver = Capybara::Driver::Celerity.new(TestApp)
7
- end
8
-
9
- it_should_behave_like "driver"
10
- it_should_behave_like "driver with javascript support"
11
- it_should_behave_like "driver with header support"
12
- it_should_behave_like "driver with status code support"
13
- it_should_behave_like "driver with cookies support"
3
+ describe Capybara::Driver::Celerity, :jruby => :platform do
4
+ before(:all) do
5
+ @driver = TestSessions::Celerity.driver
14
6
  end
15
- else
16
- puts "#{File.basename(__FILE__)} requires JRuby; skipping.."
7
+
8
+ it_should_behave_like "driver"
9
+ it_should_behave_like "driver with javascript support"
10
+ it_should_behave_like "driver with header support"
11
+ it_should_behave_like "driver with status code support"
12
+ it_should_behave_like "driver with cookies support"
17
13
  end
@@ -1,8 +1,9 @@
1
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
1
+ require 'spec_helper'
2
+
3
+ describe Capybara::Driver::Culerity, :jruby => :installed do
2
4
 
3
- describe Capybara::Driver::Culerity do
4
5
  before(:all) do
5
- @driver = Capybara::Driver::Culerity.new(TestApp)
6
+ @driver = TestSessions::Culerity.driver
6
7
  end
7
8
 
8
9
  it_should_behave_like "driver"
@@ -1,8 +1,22 @@
1
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+ require 'stringio'
4
+
5
+ def capture(*streams)
6
+ streams.map! { |stream| stream.to_s }
7
+ begin
8
+ result = StringIO.new
9
+ streams.each { |stream| eval "$#{stream} = result" }
10
+ yield
11
+ ensure
12
+ streams.each { |stream| eval("$#{stream} = #{stream.upcase}") }
13
+ end
14
+ result.string
15
+ end
2
16
 
3
17
  describe Capybara::Driver::RackTest do
4
18
  before do
5
- @driver = Capybara::Driver::RackTest.new(TestApp)
19
+ @driver = TestSessions::RackTest.driver
6
20
  end
7
21
 
8
22
  it "should throw an error when no rack app is given" do
@@ -11,6 +25,29 @@ describe Capybara::Driver::RackTest do
11
25
  end.should raise_error(ArgumentError)
12
26
  end
13
27
 
28
+ if '1.9'.respond_to?(:encode)
29
+ describe "with non-binary parameters" do
30
+
31
+ it "should convert attribute values to binary" do
32
+ output = capture(:stderr) {
33
+ @driver.visit('/mypage', :param => 'µ')
34
+ }.should_not =~ %r{warning: regexp match /.../n against to UTF-8 string}
35
+ end
36
+
37
+ it "should convert attribute with Array to binary" do
38
+ output = capture(:stderr) {
39
+ @driver.visit('/mypage', :param => ['µ'])
40
+ }.should_not =~ %r{warning: regexp match /.../n against to UTF-8 string}
41
+ end
42
+
43
+ it "should convert path to binary" do
44
+ output = capture(:stderr) {
45
+ @driver.visit('/mypage'.encode('utf-8'))
46
+ }.should_not =~ %r{warning: regexp match /.../n against to UTF-8 string}
47
+ end
48
+ end
49
+ end
50
+
14
51
  it_should_behave_like "driver"
15
52
  it_should_behave_like "driver with header support"
16
53
  it_should_behave_like "driver with status code support"
@@ -1,22 +1,20 @@
1
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
1
+ require 'spec_helper'
2
2
 
3
- describe Capybara::Driver::Culerity do
3
+ describe Capybara::Driver::Culerity, :jruby => :installed do
4
4
  before(:all) do
5
5
  Capybara.app_host = "http://capybara-testapp.heroku.com"
6
- Capybara.run_server = false
7
- @driver = Capybara::Driver::Culerity.new(TestApp)
6
+ @driver = TestSessions::Culerity.driver
8
7
  end
9
-
8
+
10
9
  after(:all) do
11
10
  Capybara.app_host = nil
12
- Capybara.run_server = true
13
11
  end
14
12
 
15
13
  it "should navigate to a fully qualified remote page" do
16
14
  @driver.visit('http://capybara-testapp.heroku.com/foo')
17
15
  @driver.body.should include('Another World')
18
16
  end
19
-
17
+
20
18
  it_should_behave_like "driver"
21
19
  it_should_behave_like "driver with javascript support"
22
20
  it_should_behave_like "driver with header support"
@@ -1,19 +1,16 @@
1
- require File.expand_path('../spec_helper', File.dirname(__FILE__))
1
+ require 'spec_helper'
2
2
 
3
3
  describe Capybara::Driver::Selenium do
4
- before(:all) do
5
- Capybara.app_host = "http://capybara-testapp.heroku.com"
6
- end
7
-
8
- after(:all) do
9
- Capybara.app_host = nil
4
+ before do
5
+ #Capybara.app_host = "http://capybara-testapp.heroku.com"
6
+ @driver = TestSessions::Selenium.driver
10
7
  end
11
8
 
12
- before do
13
- @driver = Capybara::Driver::Selenium.new(TestApp)
9
+ after do
10
+ Capybara.app_host = nil
14
11
  end
15
12
 
16
13
  it_should_behave_like "driver"
17
14
  it_should_behave_like "driver with javascript support"
18
15
  it_should_behave_like "driver without status code support"
19
- end
16
+ end