bjeanes-capybara 0.3.1

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 (88) hide show
  1. data/History.txt +4 -0
  2. data/Manifest.txt +87 -0
  3. data/README.rdoc +404 -0
  4. data/Rakefile +29 -0
  5. data/config.ru +6 -0
  6. data/lib/capybara.rb +53 -0
  7. data/lib/capybara/cucumber.rb +32 -0
  8. data/lib/capybara/driver/base.rb +37 -0
  9. data/lib/capybara/driver/celerity_driver.rb +135 -0
  10. data/lib/capybara/driver/culerity_driver.rb +25 -0
  11. data/lib/capybara/driver/rack_test_driver.rb +244 -0
  12. data/lib/capybara/driver/selenium_driver.rb +137 -0
  13. data/lib/capybara/dsl.rb +60 -0
  14. data/lib/capybara/node.rb +69 -0
  15. data/lib/capybara/rails.rb +11 -0
  16. data/lib/capybara/save_and_open_page.rb +33 -0
  17. data/lib/capybara/searchable.rb +53 -0
  18. data/lib/capybara/server.rb +111 -0
  19. data/lib/capybara/session.rb +274 -0
  20. data/lib/capybara/wait_until.rb +23 -0
  21. data/lib/capybara/xpath.rb +176 -0
  22. data/script/console +10 -0
  23. data/script/destroy +14 -0
  24. data/script/generate +14 -0
  25. data/spec/capybara_spec.rb +18 -0
  26. data/spec/driver/celerity_driver_spec.rb +17 -0
  27. data/spec/driver/culerity_driver_spec.rb +13 -0
  28. data/spec/driver/rack_test_driver_spec.rb +12 -0
  29. data/spec/driver/remote_culerity_driver_spec.rb +26 -0
  30. data/spec/driver/remote_selenium_driver_spec.rb +18 -0
  31. data/spec/driver/selenium_driver_spec.rb +12 -0
  32. data/spec/drivers_spec.rb +139 -0
  33. data/spec/dsl/all_spec.rb +69 -0
  34. data/spec/dsl/attach_file_spec.rb +64 -0
  35. data/spec/dsl/check_spec.rb +39 -0
  36. data/spec/dsl/choose_spec.rb +26 -0
  37. data/spec/dsl/click_button_spec.rb +218 -0
  38. data/spec/dsl/click_link_spec.rb +108 -0
  39. data/spec/dsl/click_spec.rb +24 -0
  40. data/spec/dsl/current_url_spec.rb +8 -0
  41. data/spec/dsl/fill_in_spec.rb +91 -0
  42. data/spec/dsl/find_button_spec.rb +16 -0
  43. data/spec/dsl/find_by_id_spec.rb +16 -0
  44. data/spec/dsl/find_field_spec.rb +22 -0
  45. data/spec/dsl/find_link_spec.rb +17 -0
  46. data/spec/dsl/find_spec.rb +57 -0
  47. data/spec/dsl/has_button_spec.rb +32 -0
  48. data/spec/dsl/has_content_spec.rb +101 -0
  49. data/spec/dsl/has_css_spec.rb +107 -0
  50. data/spec/dsl/has_field_spec.rb +96 -0
  51. data/spec/dsl/has_link_spec.rb +33 -0
  52. data/spec/dsl/has_xpath_spec.rb +123 -0
  53. data/spec/dsl/locate_spec.rb +59 -0
  54. data/spec/dsl/select_spec.rb +71 -0
  55. data/spec/dsl/uncheck_spec.rb +21 -0
  56. data/spec/dsl/within_spec.rb +153 -0
  57. data/spec/dsl_spec.rb +140 -0
  58. data/spec/fixtures/capybara.jpg +0 -0
  59. data/spec/fixtures/test_file.txt +1 -0
  60. data/spec/public/jquery-ui.js +35 -0
  61. data/spec/public/jquery.js +19 -0
  62. data/spec/public/test.js +30 -0
  63. data/spec/save_and_open_page_spec.rb +43 -0
  64. data/spec/searchable_spec.rb +61 -0
  65. data/spec/server_spec.rb +47 -0
  66. data/spec/session/celerity_session_spec.rb +27 -0
  67. data/spec/session/culerity_session_spec.rb +25 -0
  68. data/spec/session/rack_test_session_spec.rb +25 -0
  69. data/spec/session/selenium_session_spec.rb +25 -0
  70. data/spec/session_spec.rb +77 -0
  71. data/spec/session_with_headers_support_spec.rb +13 -0
  72. data/spec/session_with_javascript_support_spec.rb +182 -0
  73. data/spec/session_without_headers_support_spec.rb +15 -0
  74. data/spec/session_without_javascript_support_spec.rb +15 -0
  75. data/spec/spec_helper.rb +27 -0
  76. data/spec/test_app.rb +71 -0
  77. data/spec/views/buttons.erb +4 -0
  78. data/spec/views/fieldsets.erb +29 -0
  79. data/spec/views/form.erb +226 -0
  80. data/spec/views/postback.erb +13 -0
  81. data/spec/views/tables.erb +122 -0
  82. data/spec/views/with_html.erb +38 -0
  83. data/spec/views/with_js.erb +34 -0
  84. data/spec/views/with_scope.erb +36 -0
  85. data/spec/views/with_simple_html.erb +1 -0
  86. data/spec/wait_until_spec.rb +28 -0
  87. data/spec/xpath_spec.rb +271 -0
  88. metadata +239 -0
@@ -0,0 +1,33 @@
1
+ shared_examples_for "has_link" do
2
+
3
+ describe '#has_link?' do
4
+ before do
5
+ @session.visit('/with_html')
6
+ end
7
+
8
+ it "should be true if the given link is on the page" do
9
+ @session.should have_link('foo')
10
+ @session.should have_link('awesome title')
11
+ end
12
+
13
+ it "should be false if the given link is not on the page" do
14
+ @session.should_not have_link('monkey')
15
+ end
16
+ end
17
+
18
+ describe '#has_no_link?' do
19
+ before do
20
+ @session.visit('/with_html')
21
+ end
22
+
23
+ it "should be false if the given link is on the page" do
24
+ @session.should_not have_no_link('foo')
25
+ @session.should_not have_no_link('awesome title')
26
+ end
27
+
28
+ it "should be true if the given link is not on the page" do
29
+ @session.should have_no_link('monkey')
30
+ end
31
+ end
32
+ end
33
+
@@ -0,0 +1,123 @@
1
+ shared_examples_for "has_xpath" do
2
+ describe '#has_xpath?' do
3
+ before do
4
+ @session.visit('/with_html')
5
+ end
6
+
7
+ it "should be true if the given selector is on the page" do
8
+ @session.should have_xpath("//p")
9
+ @session.should have_xpath("//p//a[@id='foo']")
10
+ @session.should have_xpath("//p[contains(.,'est')]")
11
+ end
12
+
13
+ it "should be false if the given selector is not on the page" do
14
+ @session.should_not have_xpath("//abbr")
15
+ @session.should_not have_xpath("//p//a[@id='doesnotexist']")
16
+ @session.should_not have_xpath("//p[contains(.,'thisstringisnotonpage')]")
17
+ end
18
+
19
+ it "should use xpath even if default selector is CSS" do
20
+ Capybara.default_selector = :css
21
+ @session.should_not have_xpath("//p//a[@id='doesnotexist']")
22
+ end
23
+
24
+ it "should respect scopes" do
25
+ @session.within "//p[@id='first']" do
26
+ @session.should have_xpath("//a[@id='foo']")
27
+ @session.should_not have_xpath("//a[@id='red']")
28
+ end
29
+ end
30
+
31
+ context "with count" do
32
+ it "should be true if the content is on the page the given number of times" do
33
+ @session.should have_xpath("//p", :count => 3)
34
+ @session.should have_xpath("//p//a[@id='foo']", :count => 1)
35
+ @session.should have_xpath("//p[contains(.,'est')]", :count => 1)
36
+ end
37
+
38
+ it "should be false if the content is on the page the given number of times" do
39
+ @session.should_not have_xpath("//p", :count => 6)
40
+ @session.should_not have_xpath("//p//a[@id='foo']", :count => 2)
41
+ @session.should_not have_xpath("//p[contains(.,'est')]", :count => 5)
42
+ end
43
+
44
+ it "should be false if the content isn't on the page at all" do
45
+ @session.should_not have_xpath("//abbr", :count => 2)
46
+ @session.should_not have_xpath("//p//a[@id='doesnotexist']", :count => 1)
47
+ end
48
+ end
49
+
50
+ context "with text" do
51
+ it "should discard all matches where the given string is not contained" do
52
+ @session.should have_xpath("//p//a", :text => "Redirect", :count => 1)
53
+ @session.should_not have_xpath("//p", :text => "Doesnotexist")
54
+ end
55
+
56
+ it "should discard all matches where the given regexp is not matched" do
57
+ @session.should have_xpath("//p//a", :text => /re[dab]i/i, :count => 1)
58
+ @session.should_not have_xpath("//p//a", :text => /Red$/)
59
+ end
60
+ end
61
+ end
62
+
63
+ describe '#has_no_xpath?' do
64
+ before do
65
+ @session.visit('/with_html')
66
+ end
67
+
68
+ it "should be false if the given selector is on the page" do
69
+ @session.should_not have_no_xpath("//p")
70
+ @session.should_not have_no_xpath("//p//a[@id='foo']")
71
+ @session.should_not have_no_xpath("//p[contains(.,'est')]")
72
+ end
73
+
74
+ it "should be true if the given selector is not on the page" do
75
+ @session.should have_no_xpath("//abbr")
76
+ @session.should have_no_xpath("//p//a[@id='doesnotexist']")
77
+ @session.should have_no_xpath("//p[contains(.,'thisstringisnotonpage')]")
78
+ end
79
+
80
+ it "should use xpath even if default selector is CSS" do
81
+ Capybara.default_selector = :css
82
+ @session.should have_no_xpath("//p//a[@id='doesnotexist']")
83
+ end
84
+
85
+ it "should respect scopes" do
86
+ @session.within "//p[@id='first']" do
87
+ @session.should_not have_no_xpath("//a[@id='foo']")
88
+ @session.should have_no_xpath("//a[@id='red']")
89
+ end
90
+ end
91
+
92
+ context "with count" do
93
+ it "should be false if the content is on the page the given number of times" do
94
+ @session.should_not have_no_xpath("//p", :count => 3)
95
+ @session.should_not have_no_xpath("//p//a[@id='foo']", :count => 1)
96
+ @session.should_not have_no_xpath("//p[contains(.,'est')]", :count => 1)
97
+ end
98
+
99
+ it "should be true if the content is on the page the wrong number of times" do
100
+ @session.should have_no_xpath("//p", :count => 6)
101
+ @session.should have_no_xpath("//p//a[@id='foo']", :count => 2)
102
+ @session.should have_no_xpath("//p[contains(.,'est')]", :count => 5)
103
+ end
104
+
105
+ it "should be true if the content isn't on the page at all" do
106
+ @session.should have_no_xpath("//abbr", :count => 2)
107
+ @session.should have_no_xpath("//p//a[@id='doesnotexist']", :count => 1)
108
+ end
109
+ end
110
+
111
+ context "with text" do
112
+ it "should discard all matches where the given string is contained" do
113
+ @session.should_not have_no_xpath("//p//a", :text => "Redirect", :count => 1)
114
+ @session.should have_no_xpath("//p", :text => "Doesnotexist")
115
+ end
116
+
117
+ it "should discard all matches where the given regexp is matched" do
118
+ @session.should_not have_no_xpath("//p//a", :text => /re[dab]i/i, :count => 1)
119
+ @session.should have_no_xpath("//p//a", :text => /Red$/)
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,59 @@
1
+ shared_examples_for "locate" do
2
+ describe '#locate' do
3
+ before do
4
+ @session.visit('/with_html')
5
+ end
6
+
7
+ it "should find the first element using the given locator" do
8
+ @session.locate('//h1').text.should == 'This is a test'
9
+ @session.locate("//input[@id='test_field']")[:value].should == 'monkey'
10
+ end
11
+
12
+ context "with css selectors" do
13
+ it "should find the first element using the given locator" do
14
+ @session.locate(:css, 'h1').text.should == 'This is a test'
15
+ @session.locate(:css, "input[id='test_field']")[:value].should == 'monkey'
16
+ end
17
+ end
18
+
19
+ context "with xpath selectors" do
20
+ it "should find the first element using the given locator" do
21
+ @session.locate(:xpath, '//h1').text.should == 'This is a test'
22
+ @session.locate(:xpath, "//input[@id='test_field']")[:value].should == 'monkey'
23
+ end
24
+ end
25
+
26
+ context "with css as default selector" do
27
+ before { Capybara.default_selector = :css }
28
+ it "should find the first element using the given locator" do
29
+ @session.locate('h1').text.should == 'This is a test'
30
+ @session.locate("input[id='test_field']")[:value].should == 'monkey'
31
+ end
32
+ after { Capybara.default_selector = :xpath }
33
+ end
34
+
35
+ it "should raise ElementNotFound with specified fail message if nothing was found" do
36
+ running do
37
+ @session.locate(:xpath, '//div[@id="nosuchthing"]', 'arghh').should be_nil
38
+ end.should raise_error(Capybara::ElementNotFound, "arghh")
39
+ end
40
+
41
+ it "should accept an XPath instance and respect the order of paths" do
42
+ @session.visit('/form')
43
+ @xpath = Capybara::XPath.text_field('Name')
44
+ @session.locate(@xpath).value.should == 'John Smith'
45
+ end
46
+
47
+ context "within a scope" do
48
+ before do
49
+ @session.visit('/with_scope')
50
+ end
51
+
52
+ it "should find the first element using the given locator" do
53
+ @session.within(:xpath, "//div[@id='for_bar']") do
54
+ @session.locate('//li').text.should =~ /With Simple HTML/
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,71 @@
1
+ shared_examples_for "select" do
2
+ describe "#select" do
3
+ before do
4
+ @session.visit('/form')
5
+ end
6
+
7
+ it "should return value of the first option" do
8
+ @session.find_field('Title').value.should == 'Mrs'
9
+ end
10
+
11
+ it "should return value of the selected option" do
12
+ @session.select("Miss", :from => 'Title')
13
+ @session.find_field('Title').value.should == 'Miss'
14
+ end
15
+
16
+ it "should select an option from a select box by id" do
17
+ @session.select("Finish", :from => 'form_locale')
18
+ @session.click_button('awesome')
19
+ extract_results(@session)['locale'].should == 'fi'
20
+ end
21
+
22
+ it "should select an option from a select box by label" do
23
+ @session.select("Finish", :from => 'Locale')
24
+ @session.click_button('awesome')
25
+ extract_results(@session)['locale'].should == 'fi'
26
+ end
27
+
28
+ it "should favour exact matches to option labels" do
29
+ @session.select("Mr", :from => 'Title')
30
+ @session.click_button('awesome')
31
+ extract_results(@session)['title'].should == 'Mr'
32
+ end
33
+
34
+ context "with a locator that doesn't exist" do
35
+ it "should raise an error" do
36
+ running { @session.select('foo', :from => 'does not exist') }.should raise_error(Capybara::ElementNotFound)
37
+ end
38
+ end
39
+
40
+ context "with an option that doesn't exist" do
41
+ it "should raise an error" do
42
+ running { @session.select('Does not Exist', :from => 'form_locale') }.should raise_error(Capybara::OptionNotFound)
43
+ end
44
+ end
45
+
46
+ context "with multiple select" do
47
+ it "should return an empty value" do
48
+ @session.find_field('Language').value.should == []
49
+ end
50
+
51
+ it "should return value of the selected options" do
52
+ @session.select("Ruby", :from => 'Language')
53
+ @session.select("Javascript", :from => 'Language')
54
+ @session.find_field('Language').value.should include('Ruby', 'Javascript')
55
+ end
56
+
57
+ it "should select one option" do
58
+ @session.select("Ruby", :from => 'Language')
59
+ @session.click_button('awesome')
60
+ extract_results(@session)['languages'].should == ['Ruby']
61
+ end
62
+
63
+ it "should select multiple options" do
64
+ @session.select("Ruby", :from => 'Language')
65
+ @session.select("Javascript", :from => 'Language')
66
+ @session.click_button('awesome')
67
+ extract_results(@session)['languages'].should include('Ruby', 'Javascript')
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,21 @@
1
+ shared_examples_for "uncheck" do
2
+ describe "#uncheck" do
3
+ before do
4
+ @session.visit('/form')
5
+ end
6
+
7
+ it "should uncheck a checkbox by id" do
8
+ @session.uncheck("form_pets_hamster")
9
+ @session.click_button('awesome')
10
+ extract_results(@session)['pets'].should include('dog')
11
+ extract_results(@session)['pets'].should_not include('hamster')
12
+ end
13
+
14
+ it "should uncheck a checkbox by label" do
15
+ @session.uncheck("Hamster")
16
+ @session.click_button('awesome')
17
+ extract_results(@session)['pets'].should include('dog')
18
+ extract_results(@session)['pets'].should_not include('hamster')
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,153 @@
1
+ shared_examples_for "within" do
2
+ describe '#within' do
3
+ before do
4
+ @session.visit('/with_scope')
5
+ end
6
+
7
+ context "with CSS selector" do
8
+ it "should click links in the given scope" do
9
+ @session.within(:css, "ul li[contains('With Simple HTML')]") do
10
+ @session.click_link('Go')
11
+ end
12
+ @session.body.should include('Bar')
13
+ end
14
+ end
15
+
16
+ context "with XPath selector" do
17
+ it "should click links in the given scope" do
18
+ @session.within(:xpath, "//li[contains(.,'With Simple HTML')]") do
19
+ @session.click_link('Go')
20
+ end
21
+ @session.body.should include('Bar')
22
+ end
23
+ end
24
+
25
+ context "with the default selector" do
26
+ it "should use XPath" do
27
+ @session.within("//li[contains(., 'With Simple HTML')]") do
28
+ @session.click_link('Go')
29
+ end
30
+ @session.body.should include('Bar')
31
+ end
32
+ end
33
+
34
+ context "with the default selector set to CSS" do
35
+ before { Capybara.default_selector = :css }
36
+ it "should use CSS" do
37
+ @session.within("ul li[contains('With Simple HTML')]") do
38
+ @session.click_link('Go')
39
+ end
40
+ @session.body.should include('Bar')
41
+ end
42
+ after { Capybara.default_selector = :xpath }
43
+ end
44
+
45
+ context "with click_link" do
46
+ it "should click links in the given scope" do
47
+ @session.within("//li[contains(.,'With Simple HTML')]") do
48
+ @session.click_link('Go')
49
+ end
50
+ @session.body.should include('Bar')
51
+ end
52
+
53
+ context "with nested scopes" do
54
+ it "should respect the inner scope" do
55
+ @session.within("//div[@id='for_bar']") do
56
+ @session.within("//li[contains(.,'Bar')]") do
57
+ @session.click_link('Go')
58
+ end
59
+ end
60
+ @session.body.should include('Another World')
61
+ end
62
+
63
+ it "should respect the outer scope" do
64
+ @session.within("//div[@id='another_foo']") do
65
+ @session.within("//li[contains(.,'With Simple HTML')]") do
66
+ @session.click_link('Go')
67
+ end
68
+ end
69
+ @session.body.should include('Hello world')
70
+ end
71
+ end
72
+
73
+ it "should raise an error if the scope is not found on the page" do
74
+ running {
75
+ @session.within("//div[@id='doesnotexist']") do
76
+ end
77
+ }.should raise_error(Capybara::ElementNotFound)
78
+ end
79
+
80
+ it "should restore the scope when an error is raised" do
81
+ running {
82
+ @session.within("//div[@id='for_bar']") do
83
+ running {
84
+ running {
85
+ @session.within("//div[@id='doesnotexist']") do
86
+ end
87
+ }.should raise_error(Capybara::ElementNotFound)
88
+ }.should_not change { @session.has_xpath?("//div[@id='another_foo']") }.from(false)
89
+ end
90
+ }.should_not change { @session.has_xpath?("//div[@id='another_foo']") }.from(true)
91
+ end
92
+ end
93
+
94
+ context "with forms" do
95
+ it "should fill in a field and click a button" do
96
+ @session.within("//li[contains(.,'Bar')]") do
97
+ @session.click_button('Go')
98
+ end
99
+ extract_results(@session)['first_name'].should == 'Peter'
100
+ @session.visit('/with_scope')
101
+ @session.within("//li[contains(.,'Bar')]") do
102
+ @session.fill_in('First Name', :with => 'Dagobert')
103
+ @session.click_button('Go')
104
+ end
105
+ extract_results(@session)['first_name'].should == 'Dagobert'
106
+ end
107
+ end
108
+ end
109
+
110
+ describe '#within_fieldset' do
111
+ before do
112
+ @session.visit('/fieldsets')
113
+ end
114
+
115
+ it "should restrict scope to a fieldset given by id" do
116
+ @session.within_fieldset("villain_fieldset") do
117
+ @session.fill_in("Name", :with => 'Goldfinger')
118
+ @session.click_button("Create")
119
+ end
120
+ extract_results(@session)['villain_name'].should == 'Goldfinger'
121
+ end
122
+
123
+ it "should restrict scope to a fieldset given by legend" do
124
+ @session.within_fieldset("Villain") do
125
+ @session.fill_in("Name", :with => 'Goldfinger')
126
+ @session.click_button("Create")
127
+ end
128
+ extract_results(@session)['villain_name'].should == 'Goldfinger'
129
+ end
130
+ end
131
+
132
+ describe '#within_table' do
133
+ before do
134
+ @session.visit('/tables')
135
+ end
136
+
137
+ it "should restrict scope to a fieldset given by id" do
138
+ @session.within_table("girl_table") do
139
+ @session.fill_in("Name", :with => 'Christmas')
140
+ @session.click_button("Create")
141
+ end
142
+ extract_results(@session)['girl_name'].should == 'Christmas'
143
+ end
144
+
145
+ it "should restrict scope to a fieldset given by legend" do
146
+ @session.within_table("Villain") do
147
+ @session.fill_in("Name", :with => 'Quantum')
148
+ @session.click_button("Create")
149
+ end
150
+ extract_results(@session)['villain_name'].should == 'Quantum'
151
+ end
152
+ end
153
+ end