capybara 2.5.0 → 2.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (205) hide show
  1. checksums.yaml +5 -5
  2. data/.yard/templates_custom/default/class/html/selectors.erb +38 -0
  3. data/.yard/templates_custom/default/class/html/setup.rb +17 -0
  4. data/.yard/yard_extensions.rb +78 -0
  5. data/.yardopts +1 -0
  6. data/History.md +413 -10
  7. data/License.txt +1 -1
  8. data/README.md +237 -130
  9. data/lib/capybara/config.rb +132 -0
  10. data/lib/capybara/cucumber.rb +3 -1
  11. data/lib/capybara/driver/base.rb +27 -6
  12. data/lib/capybara/driver/node.rb +14 -5
  13. data/lib/capybara/dsl.rb +2 -3
  14. data/lib/capybara/helpers.rb +13 -65
  15. data/lib/capybara/minitest/spec.rb +177 -0
  16. data/lib/capybara/minitest.rb +278 -0
  17. data/lib/capybara/node/actions.rb +180 -24
  18. data/lib/capybara/node/base.rb +17 -5
  19. data/lib/capybara/node/document.rb +5 -0
  20. data/lib/capybara/node/document_matchers.rb +15 -14
  21. data/lib/capybara/node/element.rb +55 -7
  22. data/lib/capybara/node/finders.rb +179 -67
  23. data/lib/capybara/node/matchers.rb +301 -105
  24. data/lib/capybara/node/simple.rb +15 -4
  25. data/lib/capybara/queries/ancestor_query.rb +25 -0
  26. data/lib/capybara/queries/base_query.rb +69 -3
  27. data/lib/capybara/queries/current_path_query.rb +17 -8
  28. data/lib/capybara/queries/match_query.rb +19 -0
  29. data/lib/capybara/queries/selector_query.rb +251 -0
  30. data/lib/capybara/queries/sibling_query.rb +25 -0
  31. data/lib/capybara/queries/text_query.rb +67 -16
  32. data/lib/capybara/queries/title_query.rb +4 -2
  33. data/lib/capybara/query.rb +3 -131
  34. data/lib/capybara/rack_test/browser.rb +14 -5
  35. data/lib/capybara/rack_test/css_handlers.rb +1 -0
  36. data/lib/capybara/rack_test/driver.rb +15 -8
  37. data/lib/capybara/rack_test/form.rb +34 -12
  38. data/lib/capybara/rack_test/node.rb +29 -12
  39. data/lib/capybara/rails.rb +3 -3
  40. data/lib/capybara/result.rb +104 -9
  41. data/lib/capybara/rspec/compound.rb +95 -0
  42. data/lib/capybara/rspec/features.rb +17 -6
  43. data/lib/capybara/rspec/matcher_proxies.rb +45 -0
  44. data/lib/capybara/rspec/matchers.rb +199 -80
  45. data/lib/capybara/rspec.rb +4 -2
  46. data/lib/capybara/selector/css.rb +30 -0
  47. data/lib/capybara/selector/filter.rb +20 -0
  48. data/lib/capybara/selector/filter_set.rb +74 -0
  49. data/lib/capybara/selector/filters/base.rb +33 -0
  50. data/lib/capybara/selector/filters/expression_filter.rb +40 -0
  51. data/lib/capybara/selector/filters/node_filter.rb +27 -0
  52. data/lib/capybara/selector/selector.rb +276 -0
  53. data/lib/capybara/selector.rb +452 -157
  54. data/lib/capybara/selenium/driver.rb +282 -81
  55. data/lib/capybara/selenium/node.rb +144 -46
  56. data/lib/capybara/server.rb +59 -16
  57. data/lib/capybara/session/config.rb +114 -0
  58. data/lib/capybara/session/matchers.rb +29 -19
  59. data/lib/capybara/session.rb +378 -143
  60. data/lib/capybara/spec/fixtures/no_extension +1 -0
  61. data/lib/capybara/spec/public/jquery-ui.js +13 -791
  62. data/lib/capybara/spec/public/jquery.js +4 -9045
  63. data/lib/capybara/spec/public/test.js +45 -11
  64. data/lib/capybara/spec/session/accept_alert_spec.rb +30 -7
  65. data/lib/capybara/spec/session/accept_confirm_spec.rb +14 -2
  66. data/lib/capybara/spec/session/accept_prompt_spec.rb +35 -6
  67. data/lib/capybara/spec/session/all_spec.rb +45 -32
  68. data/lib/capybara/spec/session/ancestor_spec.rb +85 -0
  69. data/lib/capybara/spec/session/assert_all_of_selectors_spec.rb +110 -0
  70. data/lib/capybara/spec/session/assert_current_path.rb +15 -2
  71. data/lib/capybara/spec/session/assert_selector.rb +29 -28
  72. data/lib/capybara/spec/session/assert_text.rb +59 -20
  73. data/lib/capybara/spec/session/assert_title.rb +25 -11
  74. data/lib/capybara/spec/session/attach_file_spec.rb +42 -4
  75. data/lib/capybara/spec/session/body_spec.rb +1 -0
  76. data/lib/capybara/spec/session/check_spec.rb +90 -14
  77. data/lib/capybara/spec/session/choose_spec.rb +31 -5
  78. data/lib/capybara/spec/session/click_button_spec.rb +20 -9
  79. data/lib/capybara/spec/session/click_link_or_button_spec.rb +15 -9
  80. data/lib/capybara/spec/session/click_link_spec.rb +39 -15
  81. data/lib/capybara/spec/session/current_scope_spec.rb +2 -1
  82. data/lib/capybara/spec/session/current_url_spec.rb +12 -3
  83. data/lib/capybara/spec/session/dismiss_confirm_spec.rb +6 -5
  84. data/lib/capybara/spec/session/dismiss_prompt_spec.rb +4 -3
  85. data/lib/capybara/spec/session/element/assert_match_selector.rb +36 -0
  86. data/lib/capybara/spec/session/element/match_css_spec.rb +23 -0
  87. data/lib/capybara/spec/session/element/match_xpath_spec.rb +23 -0
  88. data/lib/capybara/spec/session/element/matches_selector_spec.rb +106 -0
  89. data/lib/capybara/spec/session/evaluate_async_script_spec.rb +22 -0
  90. data/lib/capybara/spec/session/evaluate_script_spec.rb +23 -1
  91. data/lib/capybara/spec/session/execute_script_spec.rb +22 -3
  92. data/lib/capybara/spec/session/fill_in_spec.rb +50 -32
  93. data/lib/capybara/spec/session/find_button_spec.rb +43 -2
  94. data/lib/capybara/spec/session/find_by_id_spec.rb +3 -2
  95. data/lib/capybara/spec/session/find_field_spec.rb +42 -6
  96. data/lib/capybara/spec/session/find_link_spec.rb +22 -3
  97. data/lib/capybara/spec/session/find_spec.rb +103 -57
  98. data/lib/capybara/spec/session/first_spec.rb +34 -18
  99. data/lib/capybara/spec/session/frame/switch_to_frame_spec.rb +103 -0
  100. data/lib/capybara/spec/session/{within_frame_spec.rb → frame/within_frame_spec.rb} +44 -2
  101. data/lib/capybara/spec/session/go_back_spec.rb +2 -1
  102. data/lib/capybara/spec/session/go_forward_spec.rb +2 -1
  103. data/lib/capybara/spec/session/has_all_selectors_spec.rb +69 -0
  104. data/lib/capybara/spec/session/has_button_spec.rb +17 -8
  105. data/lib/capybara/spec/session/has_css_spec.rb +85 -73
  106. data/lib/capybara/spec/session/has_current_path_spec.rb +91 -7
  107. data/lib/capybara/spec/session/has_field_spec.rb +93 -58
  108. data/lib/capybara/spec/session/has_link_spec.rb +9 -8
  109. data/lib/capybara/spec/session/has_none_selectors_spec.rb +76 -0
  110. data/lib/capybara/spec/session/has_select_spec.rb +159 -59
  111. data/lib/capybara/spec/session/has_selector_spec.rb +64 -28
  112. data/lib/capybara/spec/session/has_table_spec.rb +1 -0
  113. data/lib/capybara/spec/session/has_text_spec.rb +27 -12
  114. data/lib/capybara/spec/session/has_title_spec.rb +22 -4
  115. data/lib/capybara/spec/session/has_xpath_spec.rb +32 -29
  116. data/lib/capybara/spec/session/headers.rb +2 -1
  117. data/lib/capybara/spec/session/html_spec.rb +4 -3
  118. data/lib/capybara/spec/session/node_spec.rb +198 -38
  119. data/lib/capybara/spec/session/refresh_spec.rb +28 -0
  120. data/lib/capybara/spec/session/reset_session_spec.rb +46 -5
  121. data/lib/capybara/spec/session/response_code.rb +2 -1
  122. data/lib/capybara/spec/session/save_and_open_page_spec.rb +1 -0
  123. data/lib/capybara/spec/session/save_and_open_screenshot_spec.rb +6 -5
  124. data/lib/capybara/spec/session/save_page_spec.rb +34 -2
  125. data/lib/capybara/spec/session/save_screenshot_spec.rb +31 -1
  126. data/lib/capybara/spec/session/screenshot_spec.rb +4 -2
  127. data/lib/capybara/spec/session/select_spec.rb +34 -32
  128. data/lib/capybara/spec/session/selectors_spec.rb +65 -0
  129. data/lib/capybara/spec/session/sibling_spec.rb +52 -0
  130. data/lib/capybara/spec/session/text_spec.rb +4 -4
  131. data/lib/capybara/spec/session/title_spec.rb +2 -1
  132. data/lib/capybara/spec/session/uncheck_spec.rb +42 -2
  133. data/lib/capybara/spec/session/unselect_spec.rb +17 -16
  134. data/lib/capybara/spec/session/visit_spec.rb +77 -2
  135. data/lib/capybara/spec/session/window/become_closed_spec.rb +12 -11
  136. data/lib/capybara/spec/session/window/current_window_spec.rb +1 -0
  137. data/lib/capybara/spec/session/window/open_new_window_spec.rb +1 -0
  138. data/lib/capybara/spec/session/window/switch_to_window_spec.rb +16 -11
  139. data/lib/capybara/spec/session/window/window_opened_by_spec.rb +7 -4
  140. data/lib/capybara/spec/session/window/window_spec.rb +36 -29
  141. data/lib/capybara/spec/session/window/windows_spec.rb +1 -0
  142. data/lib/capybara/spec/session/window/within_window_spec.rb +31 -7
  143. data/lib/capybara/spec/session/within_spec.rb +14 -6
  144. data/lib/capybara/spec/spec_helper.rb +37 -4
  145. data/lib/capybara/spec/test_app.rb +15 -3
  146. data/lib/capybara/spec/views/buttons.erb +1 -0
  147. data/lib/capybara/spec/views/fieldsets.erb +2 -1
  148. data/lib/capybara/spec/views/form.erb +169 -9
  149. data/lib/capybara/spec/views/frame_child.erb +10 -2
  150. data/lib/capybara/spec/views/frame_one.erb +2 -1
  151. data/lib/capybara/spec/views/frame_parent.erb +3 -2
  152. data/lib/capybara/spec/views/frame_two.erb +2 -1
  153. data/lib/capybara/spec/views/header_links.erb +1 -0
  154. data/lib/capybara/spec/views/host_links.erb +1 -0
  155. data/lib/capybara/spec/views/initial_alert.erb +10 -0
  156. data/lib/capybara/spec/views/path.erb +1 -0
  157. data/lib/capybara/spec/views/popup_one.erb +1 -0
  158. data/lib/capybara/spec/views/popup_two.erb +1 -0
  159. data/lib/capybara/spec/views/postback.erb +2 -1
  160. data/lib/capybara/spec/views/tables.erb +1 -0
  161. data/lib/capybara/spec/views/with_base_tag.erb +1 -0
  162. data/lib/capybara/spec/views/with_count.erb +2 -1
  163. data/lib/capybara/spec/views/with_fixed_header_footer.erb +17 -0
  164. data/lib/capybara/spec/views/with_hover.erb +7 -1
  165. data/lib/capybara/spec/views/with_html.erb +40 -2
  166. data/lib/capybara/spec/views/with_html_entities.erb +1 -0
  167. data/lib/capybara/spec/views/with_js.erb +32 -1
  168. data/lib/capybara/spec/views/with_scope.erb +1 -0
  169. data/lib/capybara/spec/views/with_simple_html.erb +2 -1
  170. data/lib/capybara/spec/views/with_slow_unload.erb +17 -0
  171. data/lib/capybara/spec/views/with_title.erb +2 -1
  172. data/lib/capybara/spec/views/with_unload_alert.erb +14 -0
  173. data/lib/capybara/spec/views/with_windows.erb +7 -0
  174. data/lib/capybara/spec/views/within_frames.erb +3 -2
  175. data/lib/capybara/version.rb +2 -1
  176. data/lib/capybara/window.rb +20 -3
  177. data/lib/capybara.rb +189 -93
  178. data/spec/basic_node_spec.rb +7 -6
  179. data/spec/capybara_spec.rb +90 -4
  180. data/spec/dsl_spec.rb +3 -1
  181. data/spec/filter_set_spec.rb +28 -0
  182. data/spec/fixtures/capybara.csv +1 -0
  183. data/spec/fixtures/selenium_driver_rspec_failure.rb +5 -1
  184. data/spec/fixtures/selenium_driver_rspec_success.rb +5 -1
  185. data/spec/minitest_spec.rb +130 -0
  186. data/spec/minitest_spec_spec.rb +135 -0
  187. data/spec/per_session_config_spec.rb +67 -0
  188. data/spec/rack_test_spec.rb +50 -7
  189. data/spec/result_spec.rb +76 -0
  190. data/spec/rspec/features_spec.rb +21 -8
  191. data/spec/rspec/scenarios_spec.rb +21 -0
  192. data/spec/rspec/{matchers_spec.rb → shared_spec_matchers.rb} +160 -54
  193. data/spec/rspec/views_spec.rb +5 -0
  194. data/spec/rspec_matchers_spec.rb +46 -0
  195. data/spec/rspec_spec.rb +79 -1
  196. data/spec/selector_spec.rb +199 -0
  197. data/spec/selenium_spec_chrome.rb +54 -9
  198. data/spec/selenium_spec_firefox.rb +68 -0
  199. data/spec/selenium_spec_marionette.rb +127 -0
  200. data/spec/server_spec.rb +102 -14
  201. data/spec/session_spec.rb +54 -0
  202. data/spec/shared_selenium_session.rb +215 -0
  203. data/spec/spec_helper.rb +7 -0
  204. metadata +140 -15
  205. data/spec/selenium_spec.rb +0 -128
data/spec/server_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require 'spec_helper'
2
3
 
3
4
  RSpec.describe Capybara::Server do
@@ -33,7 +34,7 @@ RSpec.describe Capybara::Server do
33
34
  ensure
34
35
  Capybara.server_host = nil
35
36
  end
36
- end
37
+ end unless ENV['TRAVIS'] and (RUBY_ENGINE == 'jruby') #TODO travis with jruby in container mode has an issue with this test
37
38
 
38
39
  it "should use specified port" do
39
40
  Capybara.server_port = 22789
@@ -71,23 +72,102 @@ RSpec.describe Capybara::Server do
71
72
  expect(@res2.body).to include('Hello Second Server')
72
73
  end
73
74
 
74
- it "should use the server if it already running" do
75
- @app1 = proc { |env| [200, {}, ["Hello Server!"]]}
76
- @app2 = proc { |env| [200, {}, ["Hello Second Server!"]]}
75
+ context "When Capybara.reuse_server is true" do
76
+ before do
77
+ @old_reuse_server = Capybara.reuse_server
78
+ Capybara.reuse_server = true
79
+ end
80
+
81
+ after do
82
+ Capybara.reuse_server = @old_reuse_server
83
+ end
77
84
 
78
- @server1a = Capybara::Server.new(@app1).boot
79
- @server1b = Capybara::Server.new(@app1).boot
80
- @server2a = Capybara::Server.new(@app2).boot
81
- @server2b = Capybara::Server.new(@app2).boot
85
+ it "should use the existing server if it already running" do
86
+ @app = proc { |env| [200, {}, ["Hello Server!"]]}
82
87
 
83
- @res1 = Net::HTTP.start(@server1b.host, @server1b.port) { |http| http.get('/') }
84
- expect(@res1.body).to include('Hello Server')
88
+ @server1 = Capybara::Server.new(@app).boot
89
+ @server2 = Capybara::Server.new(@app).boot
85
90
 
86
- @res2 = Net::HTTP.start(@server2b.host, @server2b.port) { |http| http.get('/') }
87
- expect(@res2.body).to include('Hello Second Server')
91
+ res = Net::HTTP.start(@server1.host, @server1.port) { |http| http.get('/') }
92
+ expect(res.body).to include('Hello Server')
93
+
94
+ res = Net::HTTP.start(@server2.host, @server2.port) { |http| http.get('/') }
95
+ expect(res.body).to include('Hello Server')
96
+
97
+ expect(@server1.port).to eq(@server2.port)
98
+ end
99
+
100
+ it "detects and waits for all reused server sessions pending requests" do
101
+ done = false
102
+
103
+ app = proc do |env|
104
+ request = Rack::Request.new(env)
105
+ sleep request.params['wait_time'].to_f
106
+ done = true
107
+ [200, {}, ["Hello Server!"]]
108
+ end
109
+
110
+ server1 = Capybara::Server.new(app).boot
111
+ server2 = Capybara::Server.new(app).boot
112
+
113
+ start_request(server1, 0.5)
114
+ start_request(server2, 1.0)
115
+
116
+ expect {
117
+ server1.wait_for_pending_requests
118
+ }.to change{done}.from(false).to(true)
119
+ expect(server2.send(:pending_requests?)).to eq(false)
120
+ end
121
+
122
+ end
123
+
124
+ context "When Capybara.reuse_server is false" do
125
+ before do
126
+ @old_reuse_server = Capybara.reuse_server
127
+ Capybara.reuse_server = false
128
+ end
129
+
130
+ after do
131
+ Capybara.reuse_server = @old_reuse_server
132
+ end
133
+
134
+ it "should not reuse an already running server" do
135
+ @app = proc { |env| [200, {}, ["Hello Server!"]]}
136
+
137
+ @server1 = Capybara::Server.new(@app).boot
138
+ @server2 = Capybara::Server.new(@app).boot
139
+
140
+ res = Net::HTTP.start(@server1.host, @server1.port) { |http| http.get('/') }
141
+ expect(res.body).to include('Hello Server')
142
+
143
+ res = Net::HTTP.start(@server2.host, @server2.port) { |http| http.get('/') }
144
+ expect(res.body).to include('Hello Server')
145
+
146
+ expect(@server1.port).not_to eq(@server2.port)
147
+ end
148
+
149
+ it "detects and waits for only one sessions pending requests" do
150
+ done = false
151
+
152
+ app = proc do |env|
153
+ request = Rack::Request.new(env)
154
+ sleep request.params['wait_time'].to_f
155
+ done = true
156
+ [200, {}, ["Hello Server!"]]
157
+ end
158
+
159
+ server1 = Capybara::Server.new(app).boot
160
+ server2 = Capybara::Server.new(app).boot
161
+
162
+ start_request(server1, 0.5)
163
+ start_request(server2, 1.0)
164
+
165
+ expect {
166
+ server1.wait_for_pending_requests
167
+ }.to change{done}.from(false).to(true)
168
+ expect(server2.send(:pending_requests?)).to eq(true)
169
+ end
88
170
 
89
- expect(@server1a.port).to eq(@server1b.port)
90
- expect(@server2a.port).to eq(@server2b.port)
91
171
  end
92
172
 
93
173
  it "should raise server errors when the server errors before the timeout" do
@@ -113,4 +193,12 @@ RSpec.describe Capybara::Server do
113
193
  expect(Net::HTTP).to receive(:start).and_raise(SystemCallError.allocate)
114
194
  expect(server.responsive?).to eq false
115
195
  end
196
+
197
+ def start_request(server, wait_time)
198
+ # Start request, but don't wait for it to finish
199
+ socket = TCPSocket.new(server.host, server.port)
200
+ socket.write "GET /?wait_time=#{wait_time.to_s} HTTP/1.0\r\n\r\n"
201
+ socket.close
202
+ sleep 0.1
203
+ end
116
204
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+
4
+ RSpec.describe Capybara::Session do
5
+ it "verifies a passed app is a rack app" do
6
+ expect do
7
+ Capybara::Session.new(:unknown, { random: "hash"})
8
+ end.to raise_error TypeError, "The second parameter to Session::new should be a rack app if passed."
9
+ end
10
+
11
+ context "current_driver" do
12
+ it "is global when threadsafe false" do
13
+ Capybara.threadsafe = false
14
+ Capybara.current_driver = :selenium
15
+ thread = Thread.new do
16
+ Capybara.current_driver = :random
17
+ end
18
+ thread.join
19
+ expect(Capybara.current_driver).to eq :random
20
+ end
21
+
22
+ it "is thread specific threadsafe true" do
23
+ Capybara.threadsafe = true
24
+ Capybara.current_driver = :selenium
25
+ thread = Thread.new do
26
+ Capybara.current_driver = :random
27
+ end
28
+ thread.join
29
+ expect(Capybara.current_driver).to eq :selenium
30
+ end
31
+ end
32
+
33
+ context "session_name" do
34
+ it "is global when threadsafe false" do
35
+ Capybara.threadsafe = false
36
+ Capybara.session_name = "sess1"
37
+ thread = Thread.new do
38
+ Capybara.session_name = "sess2"
39
+ end
40
+ thread.join
41
+ expect(Capybara.session_name).to eq "sess2"
42
+ end
43
+
44
+ it "is thread specific when threadsafe true" do
45
+ Capybara.threadsafe = true
46
+ Capybara.session_name = "sess1"
47
+ thread = Thread.new do
48
+ Capybara.session_name = "sess2"
49
+ end
50
+ thread.join
51
+ expect(Capybara.session_name).to eq "sess1"
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,215 @@
1
+ # frozen_string_literal: true
2
+ require 'spec_helper'
3
+ require "selenium-webdriver"
4
+
5
+ RSpec.shared_examples "Capybara::Session" do |session, mode|
6
+ let(:session) {session}
7
+
8
+ context 'with selenium driver' do
9
+ before do
10
+ @session = session
11
+ end
12
+
13
+ describe '#driver' do
14
+ it "should be a selenium driver" do
15
+ expect(@session.driver).to be_an_instance_of(Capybara::Selenium::Driver)
16
+ end
17
+ end
18
+
19
+ describe '#mode' do
20
+ it "should remember the mode" do
21
+ expect(@session.mode).to eq(mode)
22
+ end
23
+ end
24
+
25
+ describe "#reset!" do
26
+ it "freshly reset session should not be touched" do
27
+ @session.instance_variable_set(:@touched, true)
28
+ @session.reset!
29
+ expect(@session.instance_variable_get(:@touched)).to eq false
30
+ end
31
+ end
32
+
33
+ describe "exit codes" do
34
+ before do
35
+ @current_dir = Dir.getwd
36
+ Dir.chdir(File.join(File.dirname(__FILE__), '..'))
37
+ @env = { 'SELENIUM_BROWSER' => @session.driver.options[:browser].to_s }
38
+ @env['LEGACY_FIREFOX'] = 'TRUE' if mode == :selenium_firefox
39
+ end
40
+
41
+ after do
42
+ Dir.chdir(@current_dir)
43
+ end
44
+
45
+ it "should have return code 1 when running selenium_driver_rspec_failure.rb" do
46
+ skip if ENV['HEADLESS']
47
+ system(@env, 'rspec spec/fixtures/selenium_driver_rspec_failure.rb', out: File::NULL, err: File::NULL)
48
+ expect($?.exitstatus).to eq(1)
49
+ end
50
+
51
+ it "should have return code 0 when running selenium_driver_rspec_success.rb" do
52
+ skip if ENV['HEADLESS']
53
+ system(@env, 'rspec spec/fixtures/selenium_driver_rspec_success.rb', out: File::NULL, err: File::NULL)
54
+ expect($?.exitstatus).to eq(0)
55
+ end
56
+ end
57
+
58
+ describe "#accept_alert" do
59
+ it "supports a blockless mode" do
60
+ @session.visit('/with_js')
61
+ @session.click_link('Open alert')
62
+ @session.accept_alert
63
+ expect{@session.driver.browser.switch_to.alert}.to raise_error(@session.driver.send(:modal_error))
64
+ end
65
+
66
+ it "can be called before visiting" do
67
+ @session.accept_alert "Initial alert" do
68
+ @session.visit('/initial_alert')
69
+ end
70
+ expect(@session).to have_text('Initial alert page')
71
+ end
72
+ end
73
+
74
+ context '#fill_in_with empty string and no options' do
75
+ it 'should trigger change when clearing a field' do
76
+ @session.visit('/with_js')
77
+ @session.fill_in('with_change_event', with: '')
78
+ # click outside the field to trigger the change event
79
+ @session.find(:css, 'body').click
80
+ expect(@session).to have_selector(:css, '.change_event_triggered', match: :one)
81
+ end
82
+ end
83
+
84
+ context "#fill_in with { :clear => :backspace } fill_option", requires: [:js] do
85
+ it 'should fill in a field, replacing an existing value' do
86
+ @session.visit('/form')
87
+ @session.fill_in('form_first_name', with: 'Harry',
88
+ fill_options: { clear: :backspace} )
89
+ expect(@session.find(:fillable_field, 'form_first_name').value).to eq('Harry')
90
+ end
91
+
92
+ it 'should only trigger onchange once' do
93
+ @session.visit('/with_js')
94
+ @session.fill_in('with_change_event', with: 'some value',
95
+ fill_options: { :clear => :backspace })
96
+ # click outside the field to trigger the change event
97
+ @session.find(:css, 'body').click
98
+ expect(@session.find(:css, '.change_event_triggered', match: :one)).to have_text 'some value'
99
+ end
100
+
101
+ it 'should trigger change when clearing field' do
102
+ @session.visit('/with_js')
103
+ @session.fill_in('with_change_event', with: '',
104
+ fill_options: { :clear => :backspace })
105
+ # click outside the field to trigger the change event
106
+ @session.find(:css, 'body').click
107
+ expect(@session).to have_selector(:css, '.change_event_triggered', match: :one)
108
+ end
109
+
110
+ it 'should trigger input event field_value.length times' do
111
+ @session.visit('/with_js')
112
+ @session.fill_in('with_change_event', with: '',
113
+ fill_options: { :clear => :backspace })
114
+ # click outside the field to trigger the change event
115
+ @session.find(:css, 'body').click
116
+ expect(@session).to have_xpath('//p[@class="input_event_triggered"]', count: 13)
117
+ end
118
+ end
119
+
120
+ context "#fill_in with { clear: :none } fill_options" do
121
+ it 'should append to content in a field' do
122
+ @session.visit('/form')
123
+ @session.fill_in('form_first_name', with: 'Harry',
124
+ fill_options: { clear: :none} )
125
+ expect(@session.find(:fillable_field, 'form_first_name').value).to eq('JohnHarry')
126
+ end
127
+ end
128
+
129
+ context "#fill_in with { clear: Array } fill_options" do
130
+ it 'should pass the array through to the element' do
131
+ pending "selenium-webdriver/geckodriver doesn't support complex sets of characters" if marionette?(@session)
132
+ #this is mainly for use with [[:control, 'a'], :backspace] - however since that is platform dependant I'm testing with something less useful
133
+ @session.visit('/form')
134
+ @session.fill_in('form_first_name', with: 'Harry',
135
+ fill_options: { clear: [[:shift, 'abc'], :backspace] } )
136
+ expect(@session.find(:fillable_field, 'form_first_name').value).to eq('JohnABHarry')
137
+ end
138
+ end
139
+
140
+ describe "#path" do
141
+ it "returns xpath" do
142
+ # this is here because it is testing for an XPath that is specific to the algorithm used in the selenium driver
143
+ @session.visit('/path')
144
+ element = @session.find(:link, 'Second Link')
145
+ expect(element.path).to eq('/html/body/div[2]/a[1]')
146
+ end
147
+ end
148
+
149
+ describe "all with disappearing elements" do
150
+ it "ignores stale elements in results" do
151
+ @session.visit('/path')
152
+ elements = @session.all(:link) { |node| raise Selenium::WebDriver::Error::StaleElementReferenceError }
153
+ expect(elements.size).to eq 0
154
+ end
155
+ end
156
+
157
+ describe "#evaluate_script" do
158
+ it "can return an element" do
159
+ @session.visit('/form')
160
+ element = @session.evaluate_script("document.getElementById('form_title')")
161
+ expect(element).to eq @session.find(:id, 'form_title')
162
+ end
163
+
164
+ it "can return arrays of nested elements" do
165
+ @session.visit('/form')
166
+ elements = @session.evaluate_script('document.querySelectorAll("#form_city option")')
167
+ elements.each do |el|
168
+ expect(el).to be_instance_of Capybara::Node::Element
169
+ end
170
+ expect(elements).to eq @session.find(:css, '#form_city').all(:css, 'option').to_a
171
+ end
172
+
173
+ it "can return hashes with elements" do
174
+ @session.visit('/form')
175
+ result = @session.evaluate_script("{ a: document.getElementById('form_title'), b: {c: document.querySelectorAll('#form_city option')}}")
176
+ expect(result).to eq({
177
+ 'a' => @session.find(:id, 'form_title'),
178
+ 'b' => {
179
+ 'c' => @session.find(:css, '#form_city').all(:css, 'option').to_a
180
+ }
181
+ })
182
+ end
183
+
184
+ describe "#evaluate_async_script" do
185
+ it "will timeout if the script takes too long" do
186
+ @session.visit('/with_js')
187
+ expect do
188
+ @session.using_wait_time(1) do
189
+ @session.evaluate_async_script("var cb = arguments[0]; setTimeout(function(){ cb(null) }, 3000)")
190
+ end
191
+ end.to raise_error Selenium::WebDriver::Error::ScriptTimeoutError
192
+ end
193
+ end
194
+ end
195
+
196
+ describe "Element#inspect" do
197
+ it "outputs obsolete elements" do
198
+ @session.visit('/form')
199
+ el = @session.find(:button, 'Click me!').click
200
+ expect(@session).to have_no_button('Click me!')
201
+ expect(el).not_to receive(:synchronize)
202
+ expect(el.inspect).to eq "Obsolete #<Capybara::Node::Element>"
203
+ end
204
+ end
205
+
206
+ describe "Element#click" do
207
+ it "should handle fixed headers/footers" do
208
+ @session.visit('/with_fixed_header_footer')
209
+ # @session.click_link('Go to root')
210
+ @session.find(:link, 'Go to root').click
211
+ expect(@session).to have_current_path('/')
212
+ end
213
+ end
214
+ end
215
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,14 @@
1
+ # frozen_string_literal: true
1
2
  require 'rspec/expectations'
2
3
  require "capybara/spec/spec_helper"
3
4
  require "pry"
4
5
 
5
6
  RSpec.configure do |config|
6
7
  Capybara::SpecHelper.configure(config)
8
+ config.filter_run_including focus_: true unless ENV['TRAVIS']
9
+ config.run_all_when_everything_filtered = true
10
+ end
11
+
12
+ def rspec2?
13
+ !defined?(::RSpec::Expectations::Version) || (Gem::Version.new(RSpec::Expectations::Version::STRING) < Gem::Version.new('3.0'))
7
14
  end