capybara 2.5.0 → 2.18.0

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 (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